]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/ObjectConstructor.cpp
JavaScriptCore-7600.1.4.17.5.tar.gz
[apple/javascriptcore.git] / runtime / ObjectConstructor.cpp
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 *
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.
9 *
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.
14 *
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
18 *
19 */
20
21#include "config.h"
22#include "ObjectConstructor.h"
23
93a37866
A
24#include "ButterflyInlines.h"
25#include "CopiedSpaceInlines.h"
f9bf01c6 26#include "Error.h"
14957cd0 27#include "ExceptionHelpers.h"
ba379fdc 28#include "JSFunction.h"
f9bf01c6 29#include "JSArray.h"
9dae56ea 30#include "JSGlobalObject.h"
14957cd0 31#include "Lookup.h"
9dae56ea 32#include "ObjectPrototype.h"
81345200 33#include "JSCInlines.h"
f9bf01c6
A
34#include "PropertyDescriptor.h"
35#include "PropertyNameArray.h"
81345200 36#include "StackVisitor.h"
9dae56ea
A
37
38namespace JSC {
39
14957cd0
A
40static EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*);
41static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*);
42static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*);
43static EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState*);
44static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*);
45static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*);
46static EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState*);
47static EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState*);
48static EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState*);
49static EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState*);
50static EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState*);
51static EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState*);
52static EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState*);
f9bf01c6 53
14957cd0
A
54}
55
56#include "ObjectConstructor.lut.h"
57
58namespace JSC {
59
81345200 60STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(ObjectConstructor);
6fe7ccc8
A
61
62const ClassInfo ObjectConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::objectConstructorTable, CREATE_METHOD_TABLE(ObjectConstructor) };
14957cd0
A
63
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
79@end
80*/
81
81345200
A
82ObjectConstructor::ObjectConstructor(VM& vm, Structure* structure)
83 : InternalFunction(vm, structure)
9dae56ea 84{
6fe7ccc8
A
85}
86
81345200 87void ObjectConstructor::finishCreation(VM& vm, ObjectPrototype* objectPrototype)
6fe7ccc8 88{
81345200 89 Base::finishCreation(vm, Identifier(&vm, "Object").string());
9dae56ea 90 // ECMA 15.2.3.1
81345200 91 putDirectWithoutTransition(vm, vm.propertyNames->prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
9dae56ea 92 // no. of arguments for constructor
81345200 93 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
14957cd0
A
94}
95
81345200 96bool ObjectConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
14957cd0 97{
81345200 98 return getStaticFunctionSlot<JSObject>(exec, ExecState::objectConstructorTable(exec->vm()), jsCast<ObjectConstructor*>(object), propertyName, slot);
9dae56ea
A
99}
100
93a37866 101static ALWAYS_INLINE JSObject* constructObject(ExecState* exec)
9dae56ea 102{
93a37866
A
103 JSGlobalObject* globalObject = exec->callee()->globalObject();
104 ArgList args(exec);
ba379fdc 105 JSValue arg = args.at(0);
9dae56ea 106 if (arg.isUndefinedOrNull())
93a37866 107 return constructEmptyObject(exec, globalObject->objectPrototype());
14957cd0 108 return arg.toObject(exec, globalObject);
9dae56ea
A
109}
110
14957cd0 111static EncodedJSValue JSC_HOST_CALL constructWithObjectConstructor(ExecState* exec)
9dae56ea 112{
93a37866 113 return JSValue::encode(constructObject(exec));
9dae56ea
A
114}
115
6fe7ccc8 116ConstructType ObjectConstructor::getConstructData(JSCell*, ConstructData& constructData)
9dae56ea
A
117{
118 constructData.native.function = constructWithObjectConstructor;
119 return ConstructTypeHost;
120}
121
14957cd0 122static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec)
9dae56ea 123{
93a37866 124 return JSValue::encode(constructObject(exec));
9dae56ea
A
125}
126
6fe7ccc8 127CallType ObjectConstructor::getCallData(JSCell*, CallData& callData)
9dae56ea
A
128{
129 callData.native.function = callObjectConstructor;
130 return CallTypeHost;
131}
132
81345200
A
133class ObjectConstructorGetPrototypeOfFunctor {
134public:
135 ObjectConstructorGetPrototypeOfFunctor(JSObject* object)
136 : m_hasSkippedFirstFrame(false)
137 , m_object(object)
138 , m_result(JSValue::encode(jsUndefined()))
139 {
140 }
141
142 EncodedJSValue result() const { return m_result; }
143
144 StackVisitor::Status operator()(StackVisitor& visitor)
145 {
146 if (!m_hasSkippedFirstFrame) {
147 m_hasSkippedFirstFrame = true;
148 return StackVisitor::Continue;
149 }
150
151 if (m_object->allowsAccessFrom(visitor->callFrame()))
152 m_result = JSValue::encode(m_object->prototype());
153 return StackVisitor::Done;
154}
155
156private:
157 bool m_hasSkippedFirstFrame;
158 JSObject* m_object;
159 EncodedJSValue m_result;
160};
161
14957cd0 162EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec)
f9bf01c6 163{
14957cd0 164 if (!exec->argument(0).isObject())
93a37866 165 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested prototype of a value that is not an object.")));
6fe7ccc8 166 JSObject* object = asObject(exec->argument(0));
81345200
A
167 ObjectConstructorGetPrototypeOfFunctor functor(object);
168 exec->iterate(functor);
169 return functor.result();
f9bf01c6
A
170}
171
14957cd0 172EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec)
f9bf01c6 173{
14957cd0 174 if (!exec->argument(0).isObject())
93a37866
A
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);
f9bf01c6 177 if (exec->hadException())
14957cd0
A
178 return JSValue::encode(jsNull());
179 JSObject* object = asObject(exec->argument(0));
f9bf01c6 180 PropertyDescriptor descriptor;
81345200 181 if (!object->getOwnPropertyDescriptor(exec, Identifier(exec, propertyName), descriptor))
14957cd0 182 return JSValue::encode(jsUndefined());
f9bf01c6 183 if (exec->hadException())
14957cd0 184 return JSValue::encode(jsUndefined());
f9bf01c6
A
185
186 JSObject* description = constructEmptyObject(exec);
187 if (!descriptor.isAccessorDescriptor()) {
93a37866
A
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);
f9bf01c6 190 } else {
6fe7ccc8
A
191 ASSERT(descriptor.getter());
192 ASSERT(descriptor.setter());
93a37866
A
193 description->putDirect(exec->vm(), exec->propertyNames().get, descriptor.getter(), 0);
194 description->putDirect(exec->vm(), exec->propertyNames().set, descriptor.setter(), 0);
f9bf01c6
A
195 }
196
93a37866
A
197 description->putDirect(exec->vm(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
198 description->putDirect(exec->vm(), exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);
f9bf01c6 199
14957cd0 200 return JSValue::encode(description);
f9bf01c6
A
201}
202
203// FIXME: Use the enumeration cache.
14957cd0 204EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec)
f9bf01c6 205{
14957cd0 206 if (!exec->argument(0).isObject())
93a37866 207 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property names of a value that is not an object.")));
f9bf01c6 208 PropertyNameArray properties(exec);
81345200 209 asObject(exec->argument(0))->methodTable(exec->vm())->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, IncludeDontEnumProperties);
93a37866 210 JSArray* names = constructEmptyArray(exec, 0);
f9bf01c6
A
211 size_t numProperties = properties.size();
212 for (size_t i = 0; i < numProperties; i++)
93a37866 213 names->push(exec, jsOwnedString(exec, properties[i].string()));
14957cd0 214 return JSValue::encode(names);
f9bf01c6
A
215}
216
217// FIXME: Use the enumeration cache.
14957cd0 218EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec)
f9bf01c6 219{
14957cd0 220 if (!exec->argument(0).isObject())
93a37866 221 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested keys of a value that is not an object.")));
f9bf01c6 222 PropertyNameArray properties(exec);
81345200 223 asObject(exec->argument(0))->methodTable(exec->vm())->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, ExcludeDontEnumProperties);
93a37866 224 JSArray* keys = constructEmptyArray(exec, 0);
f9bf01c6
A
225 size_t numProperties = properties.size();
226 for (size_t i = 0; i < numProperties; i++)
93a37866 227 keys->push(exec, jsOwnedString(exec, properties[i].string()));
14957cd0 228 return JSValue::encode(keys);
f9bf01c6
A
229}
230
231// ES5 8.10.5 ToPropertyDescriptor
232static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
233{
234 if (!in.isObject()) {
81345200 235 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Property description must be an object.")));
f9bf01c6
A
236 return false;
237 }
238 JSObject* description = asObject(in);
239
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())
244 return false;
245 }
246
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())
251 return false;
252 }
253
254 JSValue value;
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())
259 return false;
260 }
261
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())
266 return false;
267 }
268
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())
273 return false;
274 if (!get.isUndefined()) {
275 CallData callData;
14957cd0 276 if (getCallData(get, callData) == CallTypeNone) {
81345200 277 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Getter must be a function.")));
f9bf01c6
A
278 return false;
279 }
6fe7ccc8 280 }
f9bf01c6
A
281 desc.setGetter(get);
282 }
283
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())
288 return false;
289 if (!set.isUndefined()) {
290 CallData callData;
14957cd0 291 if (getCallData(set, callData) == CallTypeNone) {
81345200 292 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Setter must be a function.")));
f9bf01c6
A
293 return false;
294 }
6fe7ccc8 295 }
f9bf01c6
A
296 desc.setSetter(set);
297 }
298
299 if (!desc.isAccessorDescriptor())
300 return true;
301
302 if (desc.value()) {
81345200 303 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'value' present on property with getter or setter.")));
f9bf01c6
A
304 return false;
305 }
306
307 if (desc.writablePresent()) {
81345200 308 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'writable' present on property with getter or setter.")));
f9bf01c6
A
309 return false;
310 }
311 return true;
312}
313
14957cd0 314EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec)
f9bf01c6 315{
14957cd0 316 if (!exec->argument(0).isObject())
93a37866 317 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
14957cd0 318 JSObject* O = asObject(exec->argument(0));
93a37866 319 String propertyName = exec->argument(1).toString(exec)->value(exec);
f9bf01c6 320 if (exec->hadException())
14957cd0 321 return JSValue::encode(jsNull());
f9bf01c6 322 PropertyDescriptor descriptor;
14957cd0
A
323 if (!toPropertyDescriptor(exec, exec->argument(2), descriptor))
324 return JSValue::encode(jsNull());
6fe7ccc8 325 ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
f9bf01c6 326 ASSERT(!exec->hadException());
81345200 327 O->methodTable(exec->vm())->defineOwnProperty(O, exec, Identifier(exec, propertyName), descriptor, true);
14957cd0 328 return JSValue::encode(O);
f9bf01c6
A
329}
330
331static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* properties)
332{
333 PropertyNameArray propertyNames(exec);
81345200 334 asObject(properties)->methodTable(exec->vm())->getOwnPropertyNames(asObject(properties), exec, propertyNames, ExcludeDontEnumProperties);
f9bf01c6
A
335 size_t numProperties = propertyNames.size();
336 Vector<PropertyDescriptor> descriptors;
337 MarkedArgumentBuffer markBuffer;
338 for (size_t i = 0; i < numProperties; i++) {
f9bf01c6
A
339 JSValue prop = properties->get(exec, propertyNames[i]);
340 if (exec->hadException())
341 return jsNull();
342 PropertyDescriptor descriptor;
343 if (!toPropertyDescriptor(exec, prop, descriptor))
344 return jsNull();
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());
354 }
355 }
356 for (size_t i = 0; i < numProperties; i++) {
81345200 357 object->methodTable(exec->vm())->defineOwnProperty(object, exec, propertyNames[i], descriptors[i], true);
f9bf01c6
A
358 if (exec->hadException())
359 return jsNull();
360 }
361 return object;
362}
363
14957cd0
A
364EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec)
365{
366 if (!exec->argument(0).isObject())
93a37866 367 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects.")));
6fe7ccc8 368 return JSValue::encode(defineProperties(exec, asObject(exec->argument(0)), exec->argument(1).toObject(exec)));
14957cd0
A
369}
370
371EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec)
372{
14957cd0 373 JSValue proto = exec->argument(0);
81345200
A
374 if (!proto.isObject() && !proto.isNull())
375 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null.")));
93a37866
A
376 JSObject* newObject = proto.isObject()
377 ? constructEmptyObject(exec, asObject(proto))
378 : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
14957cd0
A
379 if (exec->argument(1).isUndefined())
380 return JSValue::encode(newObject);
381 if (!exec->argument(1).isObject())
93a37866 382 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Property descriptor list must be an Object.")));
14957cd0
A
383 return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1))));
384}
385
386EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
387{
6fe7ccc8 388 // 1. If Type(O) is not Object throw a TypeError exception.
14957cd0
A
389 JSValue obj = exec->argument(0);
390 if (!obj.isObject())
93a37866 391 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.seal can only be called on Objects.")));
6fe7ccc8
A
392 JSObject* object = asObject(obj);
393
394 if (isJSFinalObject(object)) {
93a37866 395 object->seal(exec->vm());
6fe7ccc8
A
396 return JSValue::encode(obj);
397 }
398
399 // 2. For each named own property name P of O,
400 PropertyNameArray properties(exec);
81345200 401 object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
6fe7ccc8
A
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;
81345200 406 if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
6fe7ccc8
A
407 continue;
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.
81345200 411 object->methodTable(exec->vm())->defineOwnProperty(object, exec, *iter, desc, true);
6fe7ccc8
A
412 if (exec->hadException())
413 return JSValue::encode(obj);
414 }
415
416 // 3. Set the [[Extensible]] internal property of O to false.
93a37866 417 object->preventExtensions(exec->vm());
6fe7ccc8
A
418
419 // 4. Return O.
14957cd0
A
420 return JSValue::encode(obj);
421}
422
423EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
424{
6fe7ccc8 425 // 1. If Type(O) is not Object throw a TypeError exception.
14957cd0
A
426 JSValue obj = exec->argument(0);
427 if (!obj.isObject())
93a37866 428 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.freeze can only be called on Objects.")));
6fe7ccc8
A
429 JSObject* object = asObject(obj);
430
81345200 431 if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType())) {
93a37866 432 object->freeze(exec->vm());
6fe7ccc8
A
433 return JSValue::encode(obj);
434 }
435
436 // 2. For each named own property name P of O,
437 PropertyNameArray properties(exec);
81345200 438 object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
6fe7ccc8
A
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;
81345200 443 if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
6fe7ccc8
A
444 continue;
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.
81345200 452 object->methodTable(exec->vm())->defineOwnProperty(object, exec, *iter, desc, true);
6fe7ccc8
A
453 if (exec->hadException())
454 return JSValue::encode(obj);
455 }
456
457 // 3. Set the [[Extensible]] internal property of O to false.
93a37866 458 object->preventExtensions(exec->vm());
6fe7ccc8
A
459
460 // 4. Return O.
14957cd0
A
461 return JSValue::encode(obj);
462}
463
464EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState* exec)
465{
466 JSValue obj = exec->argument(0);
467 if (!obj.isObject())
93a37866
A
468 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.preventExtensions can only be called on Objects.")));
469 asObject(obj)->preventExtensions(exec->vm());
14957cd0
A
470 return JSValue::encode(obj);
471}
472
473EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
474{
6fe7ccc8 475 // 1. If Type(O) is not Object throw a TypeError exception.
14957cd0
A
476 JSValue obj = exec->argument(0);
477 if (!obj.isObject())
93a37866 478 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isSealed can only be called on Objects.")));
6fe7ccc8
A
479 JSObject* object = asObject(obj);
480
481 if (isJSFinalObject(object))
93a37866 482 return JSValue::encode(jsBoolean(object->isSealed(exec->vm())));
6fe7ccc8
A
483
484 // 2. For each named own property name P of O,
485 PropertyNameArray properties(exec);
81345200 486 object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
6fe7ccc8
A
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;
81345200 491 if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
6fe7ccc8
A
492 continue;
493 // b. If desc.[[Configurable]] is true, then return false.
494 if (desc.configurable())
495 return JSValue::encode(jsBoolean(false));
496 }
497
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()));
14957cd0
A
501}
502
503EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
f9bf01c6 504{
6fe7ccc8 505 // 1. If Type(O) is not Object throw a TypeError exception.
14957cd0
A
506 JSValue obj = exec->argument(0);
507 if (!obj.isObject())
93a37866 508 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isFrozen can only be called on Objects.")));
6fe7ccc8
A
509 JSObject* object = asObject(obj);
510
511 if (isJSFinalObject(object))
93a37866 512 return JSValue::encode(jsBoolean(object->isFrozen(exec->vm())));
6fe7ccc8
A
513
514 // 2. For each named own property name P of O,
515 PropertyNameArray properties(exec);
81345200 516 object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
6fe7ccc8
A
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;
81345200 521 if (!object->getOwnPropertyDescriptor(exec, *iter, desc))
6fe7ccc8
A
522 continue;
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));
527 }
528
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()));
f9bf01c6
A
532}
533
14957cd0 534EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState* exec)
f9bf01c6 535{
14957cd0
A
536 JSValue obj = exec->argument(0);
537 if (!obj.isObject())
93a37866 538 return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isExtensible can only be called on Objects.")));
14957cd0 539 return JSValue::encode(jsBoolean(asObject(obj)->isExtensible()));
f9bf01c6
A
540}
541
9dae56ea 542} // namespace JSC