X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..217a6308cd6a1dc049a0bb69263bd4c91f91c4d0:/runtime/JSCell.cpp diff --git a/runtime/JSCell.cpp b/runtime/JSCell.cpp index d449deb..07b3331 100644 --- a/runtime/JSCell.cpp +++ b/runtime/JSCell.cpp @@ -26,96 +26,39 @@ #include "JSFunction.h" #include "JSString.h" #include "JSObject.h" +#include "NumberObject.h" +#include "Operations.h" #include namespace JSC { -#if defined NAN && defined INFINITY - -extern const double NaN = NAN; -extern const double Inf = INFINITY; - -#else // !(defined NAN && defined INFINITY) - -// The trick is to define the NaN and Inf globals with a different type than the declaration. -// This trick works because the mangled name of the globals does not include the type, although -// I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of -// characters don't necessarily need the same alignment doubles do, but for now it seems to work. -// It would be good to figure out a 100% clean way that still avoids code that runs at init time. - -// Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere, -// while NaN_double has to be 4-byte aligned for 32-bits. -// With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading. - -static const union { - struct { - unsigned char NaN_Bytes[8]; - unsigned char Inf_Bytes[8]; - } bytes; - - struct { - double NaN_Double; - double Inf_Double; - } doubles; - -} NaNInf = { { -#if PLATFORM(BIG_ENDIAN) - { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }, - { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } -#elif PLATFORM(MIDDLE_ENDIAN) - { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }, - { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } -#else - { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }, - { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } -#endif -} } ; - -extern const double NaN = NaNInf.doubles.NaN_Double; -extern const double Inf = NaNInf.doubles.Inf_Double; - -#endif // !(defined NAN && defined INFINITY) - -void* JSCell::operator new(size_t size, ExecState* exec) -{ -#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE - return exec->heap()->inlineAllocate(size); -#else - return exec->heap()->allocate(size); -#endif -} - -bool JSCell::getUInt32(uint32_t&) const -{ - return false; -} +ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCell); -bool JSCell::getTruncatedInt32(int32_t&) const +void JSCell::destroy(JSCell* cell) { - return false; + cell->JSCell::~JSCell(); } -bool JSCell::getTruncatedUInt32(uint32_t&) const +void JSCell::copyBackingStore(JSCell*, CopyVisitor&) { - return false; } -bool JSCell::getString(UString&stringValue) const +bool JSCell::getString(ExecState* exec, String& stringValue) const { if (!isString()) return false; - stringValue = static_cast(this)->value(); + stringValue = static_cast(this)->value(exec); return true; } -UString JSCell::getString() const +String JSCell::getString(ExecState* exec) const { - return isString() ? static_cast(this)->value() : UString(); + return isString() ? static_cast(this)->value(exec) : String(); } JSObject* JSCell::getObject() { - return isObject() ? static_cast(this) : 0; + return isObject() ? asObject(this) : 0; } const JSObject* JSCell::getObject() const @@ -123,87 +66,170 @@ const JSObject* JSCell::getObject() const return isObject() ? static_cast(this) : 0; } -CallType JSCell::getCallData(CallData&) +CallType JSCell::getCallData(JSCell*, CallData& callData) { + callData.js.functionExecutable = 0; + callData.js.scope = 0; + callData.native.function = 0; return CallTypeNone; } -ConstructType JSCell::getConstructData(ConstructData&) +ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData) { + constructData.js.functionExecutable = 0; + constructData.js.scope = 0; + constructData.native.function = 0; return ConstructTypeNone; } -bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot) +bool JSCell::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName identifier, PropertySlot& slot) { // This is not a general purpose implementation of getOwnPropertySlot. // It should only be called by JSValue::get. // It calls getPropertySlot, not getOwnPropertySlot. - JSObject* object = toObject(exec); + JSObject* object = cell->toObject(exec, exec->lexicalGlobalObject()); slot.setBase(object); if (!object->getPropertySlot(exec, identifier, slot)) slot.setUndefined(); return true; } -bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot) +bool JSCell::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned identifier, PropertySlot& slot) { // This is not a general purpose implementation of getOwnPropertySlot. // It should only be called by JSValue::get. // It calls getPropertySlot, not getOwnPropertySlot. - JSObject* object = toObject(exec); + JSObject* object = cell->toObject(exec, exec->lexicalGlobalObject()); slot.setBase(object); if (!object->getPropertySlot(exec, identifier, slot)) slot.setUndefined(); return true; } -void JSCell::put(ExecState* exec, const Identifier& identifier, JSValuePtr value, PutPropertySlot& slot) +void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& slot) +{ + if (cell->isString()) { + JSValue(cell).putToPrimitive(exec, identifier, value, slot); + return; + } + JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject()); + thisObject->methodTable()->put(thisObject, exec, identifier, value, slot); +} + +void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow) +{ + if (cell->isString()) { + PutPropertySlot slot(shouldThrow); + JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot); + return; + } + JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject()); + thisObject->methodTable()->putByIndex(thisObject, exec, identifier, value, shouldThrow); +} + +bool JSCell::deleteProperty(JSCell* cell, ExecState* exec, PropertyName identifier) +{ + JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject()); + return thisObject->methodTable()->deleteProperty(thisObject, exec, identifier); +} + +bool JSCell::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned identifier) +{ + JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject()); + return thisObject->methodTable()->deletePropertyByIndex(thisObject, exec, identifier); +} + +JSObject* JSCell::toThisObject(JSCell* cell, ExecState* exec) +{ + return cell->toObject(exec, exec->lexicalGlobalObject()); +} + +JSValue JSCell::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const +{ + if (isString()) + return static_cast(this)->toPrimitive(exec, preferredType); + return static_cast(this)->toPrimitive(exec, preferredType); +} + +bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) const +{ + if (isString()) + return static_cast(this)->getPrimitiveNumber(exec, number, value); + return static_cast(this)->getPrimitiveNumber(exec, number, value); +} + +double JSCell::toNumber(ExecState* exec) const +{ + if (isString()) + return static_cast(this)->toNumber(exec); + return static_cast(this)->toNumber(exec); +} + +JSObject* JSCell::toObject(ExecState* exec, JSGlobalObject* globalObject) const { - toObject(exec)->put(exec, identifier, value, slot); + if (isString()) + return static_cast(this)->toObject(exec, globalObject); + ASSERT(isObject()); + return jsCast(const_cast(this)); } -void JSCell::put(ExecState* exec, unsigned identifier, JSValuePtr value) +void slowValidateCell(JSCell* cell) { - toObject(exec)->put(exec, identifier, value); + ASSERT_GC_OBJECT_LOOKS_VALID(cell); } -bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier) +JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType) { - return toObject(exec)->deleteProperty(exec, identifier); + RELEASE_ASSERT_NOT_REACHED(); + return jsUndefined(); } -bool JSCell::deleteProperty(ExecState* exec, unsigned identifier) +void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) { - return toObject(exec)->deleteProperty(exec, identifier); + RELEASE_ASSERT_NOT_REACHED(); } -JSObject* JSCell::toThisObject(ExecState* exec) const +void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) { - return toObject(exec); + RELEASE_ASSERT_NOT_REACHED(); } -UString JSCell::toThisString(ExecState* exec) const +String JSCell::className(const JSObject*) { - return toThisObject(exec)->toString(exec); + RELEASE_ASSERT_NOT_REACHED(); + return String(); } -JSString* JSCell::toThisJSString(ExecState* exec) +const char* JSCell::className() { - return jsString(exec, toThisString(exec)); + return classInfo()->className; } -const ClassInfo* JSCell::classInfo() const +void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) { - return 0; + RELEASE_ASSERT_NOT_REACHED(); +} + +bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue) +{ + RELEASE_ASSERT_NOT_REACHED(); + return false; } -JSValuePtr JSCell::getJSNumber() +void JSCell::putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned) { - return noValue(); + RELEASE_ASSERT_NOT_REACHED(); +} + +bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool) +{ + RELEASE_ASSERT_NOT_REACHED(); + return false; } -bool JSCell::isGetterSetter() const +bool JSCell::getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&) { + RELEASE_ASSERT_NOT_REACHED(); return false; }