ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell) { #if ENABLE(SIMPLE_HEAP_PROFILING) m_visitedTypeCounts.count(cell); #endif ASSERT(Heap::isMarked(cell)); if (isJSString(cell)) { JSString::visitChildren(const_cast<JSCell*>(cell), visitor); return; } if (isJSFinalObject(cell)) { JSObject::visitChildren(const_cast<JSCell*>(cell), visitor); return; } if (isJSArray(cell)) { JSArray::visitChildren(const_cast<JSCell*>(cell), visitor); return; } cell->methodTable()->visitChildren(const_cast<JSCell*>(cell), visitor); }
EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec) { // 1. If Type(O) is not Object throw a TypeError exception. JSValue obj = exec->argument(0); if (!obj.isObject()) return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isFrozen can only be called on Objects."))); JSObject* object = asObject(obj); if (isJSFinalObject(object)) return JSValue::encode(jsBoolean(object->isFrozen(exec->vm()))); // 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, return false. c. If desc.[[Configurable]] is true, then return false. if ((desc.isDataDescriptor() && desc.writable()) || desc.configurable()) return JSValue::encode(jsBoolean(false)); } // 3. If the [[Extensible]] internal property of O is false, then return true. // 4. Otherwise, return false. return JSValue::encode(jsBoolean(!object->isExtensible())); }
EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec) { // 1. If Type(O) is not Object throw a TypeError exception. JSValue obj = exec->argument(0); if (!obj.isObject()) 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. return JSValue::encode(obj); }
ALWAYS_INLINE static void visitChildren(SlotVisitor& visitor, const JSCell* cell) { StackStats::probe(); ASSERT(Heap::isMarked(cell)); if (isJSString(cell)) { JSString::visitChildren(const_cast<JSCell*>(cell), visitor); return; } if (isJSFinalObject(cell)) { JSFinalObject::visitChildren(const_cast<JSCell*>(cell), visitor); return; } if (isJSArray(cell)) { JSArray::visitChildren(const_cast<JSCell*>(cell), visitor); return; } cell->methodTable()->visitChildren(const_cast<JSCell*>(cell), visitor); }
ALWAYS_INLINE void SlotVisitor::visitChildren(const JSCell* cell) { ASSERT(Heap::isMarked(cell)); m_currentObjectCellStateBeforeVisiting = cell->cellState(); cell->setCellState(CellState::OldBlack); if (isJSString(cell)) { JSString::visitChildren(const_cast<JSCell*>(cell), *this); return; } if (isJSFinalObject(cell)) { JSFinalObject::visitChildren(const_cast<JSCell*>(cell), *this); return; } if (isJSArray(cell)) { JSArray::visitChildren(const_cast<JSCell*>(cell), *this); return; } cell->methodTable()->visitChildren(const_cast<JSCell*>(cell), *this); }