#include "JSFunction.h"
#include "JSString.h"
#include "JSObject.h"
+#include "NumberObject.h"
+#include "Operations.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 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<const JSString*>(this)->value();
+ stringValue = static_cast<const JSString*>(this)->value(exec);
return true;
}
-UString JSCell::getString() const
+String JSCell::getString(ExecState* exec) const
{
- return isString() ? static_cast<const JSString*>(this)->value() : UString();
+ return isString() ? static_cast<const JSString*>(this)->value(exec) : String();
}
JSObject* JSCell::getObject()
{
- return isObject() ? static_cast<JSObject*>(this) : 0;
+ return isObject() ? asObject(this) : 0;
}
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)
+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<const JSString*>(this)->toPrimitive(exec, preferredType);
+ return static_cast<const JSObject*>(this)->toPrimitive(exec, preferredType);
+}
+
+bool JSCell::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) const
+{
+ if (isString())
+ return static_cast<const JSString*>(this)->getPrimitiveNumber(exec, number, value);
+ return static_cast<const JSObject*>(this)->getPrimitiveNumber(exec, number, value);
+}
+
+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
{
- toObject(exec)->put(exec, identifier, value, slot);
+ if (isString())
+ return static_cast<const JSString*>(this)->toObject(exec, globalObject);
+ ASSERT(isObject());
+ return jsCast<JSObject*>(const_cast<JSCell*>(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;
}