+ return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.freeze can only be called on Objects.")));
+ JSObject* object = asObject(obj);
+
+ if (isJSFinalObject(object) && !hasIndexedProperties(object->structure()->indexingType())) {
+ object->freeze(exec->vm());
+ return JSValue::encode(obj);
+ }
+
+ // 2. For each named own property name P of O,
+ PropertyNameArray properties(exec);
+ object->methodTable()->getOwnPropertyNames(object, exec, properties, IncludeDontEnumProperties);
+ PropertyNameArray::const_iterator end = properties.end();
+ for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
+ PropertyDescriptor desc;
+ if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, *iter, desc))
+ continue;
+ // b. If IsDataDescriptor(desc) is true, then
+ // i. If desc.[[Writable]] is true, set desc.[[Writable]] to false.
+ if (desc.isDataDescriptor())
+ desc.setWritable(false);
+ // c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false.
+ desc.setConfigurable(false);
+ // d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments.
+ object->methodTable()->defineOwnProperty(object, exec, *iter, desc, true);
+ if (exec->hadException())
+ return JSValue::encode(obj);
+ }
+
+ // 3. Set the [[Extensible]] internal property of O to false.
+ object->preventExtensions(exec->vm());
+
+ // 4. Return O.