+JSObject* objectConstructorFreeze(ExecState* exec, JSObject* object)
+{
+ if (isJSFinalObject(object) && !hasIndexedProperties(object->indexingType())) {
+ object->freeze(exec->vm());
+ return object;
+ }
+
+ // 2. For each named own property name P of O,
+ PropertyNameArray properties(exec);
+ object->methodTable(exec->vm())->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include, SymbolPropertiesMode::Include));
+ PropertyNameArray::const_iterator end = properties.end();
+ for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) {
+ Identifier propertyName = *iter;
+ if (exec->propertyNames().isPrivateName(propertyName))
+ continue;
+ // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P.
+ PropertyDescriptor desc;
+ if (!object->getOwnPropertyDescriptor(exec, propertyName, 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(exec->vm())->defineOwnProperty(object, exec, propertyName, desc, true);
+ if (exec->hadException())
+ return object;
+ }
+
+ // 3. Set the [[Extensible]] internal property of O to false.
+ object->preventExtensions(exec->vm());
+
+ // 4. Return O.
+ return object;
+}
+