]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSCell.cpp
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / runtime / JSCell.cpp
index 0cc1ab1b7a6e419534e7e52d7b8b483480efd3be..84349fe259fc694a458be2308aec7072d8bd8e74 100644 (file)
 #include "config.h"
 #include "JSCell.h"
 
+#include "ArrayBufferView.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "JSObject.h"
+#include "NumberObject.h"
+#include "JSCInlines.h"
 #include <wtf/MathExtras.h>
 
 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
+COMPILE_ASSERT(sizeof(JSCell) == sizeof(uint64_t), jscell_is_eight_bytes);
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSCell);
+
+void JSCell::destroy(JSCell* cell)
+{
+    cell->JSCell::~JSCell();
+}
+
+void JSCell::dump(PrintStream& out) const
+{
+    methodTable()->dumpToStream(this, out);
+}
+
+void JSCell::dumpToStream(const JSCell* cell, PrintStream& out)
+{
+    out.printf("<%p, %s>", cell, cell->className());
+}
+
+void JSCell::copyBackingStore(JSCell*, CopyVisitor&, CopyToken)
 {
-    return false;
 }
 
-bool JSCell::getString(ExecState* exec, UString&stringValue) const
+bool JSCell::getString(ExecState* exec, String& stringValue) const
 {
     if (!isString())
         return false;
@@ -89,9 +63,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<const JSString*>(this)->value(exec) : UString();
+    return isString() ? static_cast<const JSString*>(this)->value(exec) : String();
 }
 
 JSObject* JSCell::getObject()
@@ -104,113 +78,161 @@ const JSObject* JSCell::getObject() const
     return isObject() ? static_cast<const JSObject*>(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)
+void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& 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);
-    slot.setBase(object);
-    if (!object->getPropertySlot(exec, identifier, slot))
-        slot.setUndefined();
-    return true;
+    if (cell->isString()) {
+        JSValue(cell).putToPrimitive(exec, identifier, value, slot);
+        return;
+    }
+    JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
+    thisObject->methodTable(exec->vm())->put(thisObject, exec, identifier, value, slot);
 }
 
-bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot)
+void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow)
 {
-    // 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);
-    slot.setBase(object);
-    if (!object->getPropertySlot(exec, identifier, slot))
-        slot.setUndefined();
-    return true;
+    if (cell->isString()) {
+        PutPropertySlot slot(cell, shouldThrow);
+        JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot);
+        return;
+    }
+    JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
+    thisObject->methodTable(exec->vm())->putByIndex(thisObject, exec, identifier, value, shouldThrow);
 }
 
-void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot)
+bool JSCell::deleteProperty(JSCell* cell, ExecState* exec, PropertyName identifier)
 {
-    toObject(exec)->put(exec, identifier, value, slot);
+    JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
+    return thisObject->methodTable(exec->vm())->deleteProperty(thisObject, exec, identifier);
 }
 
-void JSCell::put(ExecState* exec, unsigned identifier, JSValue value)
+bool JSCell::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned identifier)
 {
-    toObject(exec)->put(exec, identifier, value);
+    JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
+    return thisObject->methodTable(exec->vm())->deletePropertyByIndex(thisObject, exec, identifier);
 }
 
-bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier)
+JSValue JSCell::toThis(JSCell* cell, ExecState* exec, ECMAMode ecmaMode)
 {
-    return toObject(exec)->deleteProperty(exec, identifier);
+    if (ecmaMode == StrictMode)
+        return cell;
+    return cell->toObject(exec, exec->lexicalGlobalObject());
 }
 
-bool JSCell::deleteProperty(ExecState* exec, unsigned identifier)
+JSValue JSCell::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
 {
-    return toObject(exec)->deleteProperty(exec, identifier);
+    if (isString())
+        return static_cast<const JSString*>(this)->toPrimitive(exec, preferredType);
+    return static_cast<const JSObject*>(this)->toPrimitive(exec, preferredType);
 }
 
-JSObject* JSCell::toThisObject(ExecState* exec) const
+bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) const
 {
-    return toObject(exec);
+    if (isString())
+        return static_cast<const JSString*>(this)->getPrimitiveNumber(exec, number, value);
+    return static_cast<const JSObject*>(this)->getPrimitiveNumber(exec, number, value);
 }
 
-const ClassInfo* JSCell::classInfo() const
+double JSCell::toNumber(ExecState* exec) const
+{ 
+    if (isString())
+        return static_cast<const JSString*>(this)->toNumber(exec);
+    return static_cast<const JSObject*>(this)->toNumber(exec);
+}
+
+JSObject* JSCell::toObject(ExecState* exec, JSGlobalObject* globalObject) const
 {
-    return 0;
+    if (isString())
+        return static_cast<const JSString*>(this)->toObject(exec, globalObject);
+    ASSERT(isObject());
+    return jsCast<JSObject*>(const_cast<JSCell*>(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
+bool JSCell::getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&)
 {
-    ASSERT_NOT_REACHED();
-    return JSValue();
+    RELEASE_ASSERT_NOT_REACHED();
+    return false;
 }
 
-bool JSCell::getPrimitiveNumber(ExecState*, double&, JSValue&)
+bool JSCell::getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned, PropertySlot&)
 {
-    ASSERT_NOT_REACHED();
+    RELEASE_ASSERT_NOT_REACHED();
     return false;
 }
 
-bool JSCell::toBoolean(ExecState*) const
+void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
 {
-    ASSERT_NOT_REACHED();
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
+{
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+String JSCell::className(const JSObject*)
+{
+    RELEASE_ASSERT_NOT_REACHED();
+    return String();
+}
+
+const char* JSCell::className() const
+{
+    return classInfo()->className;
+}
+
+void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
+{
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue)
+{
+    RELEASE_ASSERT_NOT_REACHED();
     return false;
 }
 
-double JSCell::toNumber(ExecState*) const
+bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool)
 {
-    ASSERT_NOT_REACHED();
-    return 0;
+    RELEASE_ASSERT_NOT_REACHED();
+    return false;
 }
 
-UString JSCell::toString(ExecState*) const
+ArrayBuffer* JSCell::slowDownAndWasteMemory(JSArrayBufferView*)
 {
-    ASSERT_NOT_REACHED();
-    return UString();
+    RELEASE_ASSERT_NOT_REACHED();
+    return 0;
 }
 
-JSObject* JSCell::toObject(ExecState*) const
+PassRefPtr<ArrayBufferView> JSCell::getTypedArrayImpl(JSArrayBufferView*)
 {
-    ASSERT_NOT_REACHED();
+    RELEASE_ASSERT_NOT_REACHED();
     return 0;
 }