X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/f9bf01c6616d5ddcf65b13b33cedf9e387ff7a63..217a6308cd6a1dc049a0bb69263bd4c91f91c4d0:/runtime/JSCell.cpp diff --git a/runtime/JSCell.cpp b/runtime/JSCell.cpp index 869fbfc..07b3331 100644 --- a/runtime/JSCell.cpp +++ b/runtime/JSCell.cpp @@ -26,62 +26,24 @@ #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 CPU(BIG_ENDIAN) - { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }, - { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } -#elif CPU(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) - -bool JSCell::getUInt32(uint32_t&) const +ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCell); + +void JSCell::destroy(JSCell* cell) +{ + cell->JSCell::~JSCell(); +} + +void JSCell::copyBackingStore(JSCell*, CopyVisitor&) { - return false; } -bool JSCell::getString(ExecState* exec, UString&stringValue) const +bool JSCell::getString(ExecState* exec, String& stringValue) const { if (!isString()) return false; @@ -89,9 +51,9 @@ bool JSCell::getString(ExecState* exec, UString&stringValue) const return true; } -UString JSCell::getString(ExecState* exec) const +String JSCell::getString(ExecState* exec) const { - return isString() ? static_cast(this)->value(exec) : UString(); + return isString() ? static_cast(this)->value(exec) : String(); } JSObject* JSCell::getObject() @@ -104,124 +66,171 @@ 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, JSValue value, PutPropertySlot& slot) +void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& slot) { - toObject(exec)->put(exec, identifier, value, 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::put(ExecState* exec, unsigned identifier, JSValue value) +void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow) { - toObject(exec)->put(exec, identifier, value); + 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(ExecState* exec, const Identifier& identifier) +bool JSCell::deleteProperty(JSCell* cell, ExecState* exec, PropertyName identifier) { - return toObject(exec)->deleteProperty(exec, identifier); + JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject()); + return thisObject->methodTable()->deleteProperty(thisObject, exec, identifier); } -bool JSCell::deleteProperty(ExecState* exec, unsigned identifier) +bool JSCell::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned identifier) { - return toObject(exec)->deleteProperty(exec, identifier); + JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject()); + return thisObject->methodTable()->deletePropertyByIndex(thisObject, exec, identifier); } -JSObject* JSCell::toThisObject(ExecState* exec) const +JSObject* JSCell::toThisObject(JSCell* cell, ExecState* exec) { - return toObject(exec); + return cell->toObject(exec, exec->lexicalGlobalObject()); } -UString JSCell::toThisString(ExecState* exec) const +JSValue JSCell::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const { - return toThisObject(exec)->toString(exec); + if (isString()) + return static_cast(this)->toPrimitive(exec, preferredType); + return static_cast(this)->toPrimitive(exec, preferredType); } -JSString* JSCell::toThisJSString(ExecState* exec) +bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) const { - return jsString(exec, toThisString(exec)); + if (isString()) + return static_cast(this)->getPrimitiveNumber(exec, number, value); + return static_cast(this)->getPrimitiveNumber(exec, number, value); } -const ClassInfo* JSCell::classInfo() const +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 { - return 0; + if (isString()) + return static_cast(this)->toObject(exec, globalObject); + ASSERT(isObject()); + return jsCast(const_cast(this)); } -JSValue JSCell::getJSNumber() +void slowValidateCell(JSCell* cell) { - return JSValue(); + ASSERT_GC_OBJECT_LOOKS_VALID(cell); } -bool JSCell::isGetterSetter() const +JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType) { - return false; + RELEASE_ASSERT_NOT_REACHED(); + return jsUndefined(); } -JSValue JSCell::toPrimitive(ExecState*, PreferredPrimitiveType) const +void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) { - ASSERT_NOT_REACHED(); - return JSValue(); + RELEASE_ASSERT_NOT_REACHED(); } -bool JSCell::getPrimitiveNumber(ExecState*, double&, JSValue&) +void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) { - ASSERT_NOT_REACHED(); - return false; + RELEASE_ASSERT_NOT_REACHED(); +} + +String JSCell::className(const JSObject*) +{ + RELEASE_ASSERT_NOT_REACHED(); + return String(); +} + +const char* JSCell::className() +{ + return classInfo()->className; } -bool JSCell::toBoolean(ExecState*) const +void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) { - ASSERT_NOT_REACHED(); + RELEASE_ASSERT_NOT_REACHED(); +} + +bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue) +{ + RELEASE_ASSERT_NOT_REACHED(); return false; } -double JSCell::toNumber(ExecState*) const +void JSCell::putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned) { - ASSERT_NOT_REACHED(); - return 0; + RELEASE_ASSERT_NOT_REACHED(); } -UString JSCell::toString(ExecState*) const +bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool) { - ASSERT_NOT_REACHED(); - return UString(); + RELEASE_ASSERT_NOT_REACHED(); + return false; } -JSObject* JSCell::toObject(ExecState*) const +bool JSCell::getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&) { - ASSERT_NOT_REACHED(); - return 0; + RELEASE_ASSERT_NOT_REACHED(); + return false; } } // namespace JSC