summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime/JSNumberCell.h
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/runtime/JSNumberCell.h')
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.h372
1 files changed, 277 insertions, 95 deletions
diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h
index e2f6990..d2377aa 100644
--- a/JavaScriptCore/runtime/JSNumberCell.h
+++ b/JavaScriptCore/runtime/JSNumberCell.h
@@ -23,15 +23,22 @@
#ifndef JSNumberCell_h
#define JSNumberCell_h
-#include "ExecState.h"
+#include "CallFrame.h"
#include "JSCell.h"
#include "JSImmediate.h"
-#include "collector.h"
-#include "ustring.h"
+#include "Collector.h"
+#include "UString.h"
#include <stddef.h> // for size_t
namespace JSC {
+ extern const double NaN;
+ extern const double Inf;
+
+ JSValuePtr jsNumberCell(ExecState*, double);
+
+#if !USE(ALTERNATE_JSIMMEDIATE)
+
class Identifier;
class JSCell;
class JSObject;
@@ -42,16 +49,14 @@ namespace JSC {
struct Instruction;
class JSNumberCell : public JSCell {
- friend class CTI;
- friend JSValue* jsNumberCell(JSGlobalData*, double);
- friend JSValue* jsNaN(JSGlobalData*);
- friend JSValue* jsNumberCell(ExecState*, double);
- friend JSValue* jsNaN(ExecState*);
+ friend class JIT;
+ friend JSValuePtr jsNumberCell(JSGlobalData*, double);
+ friend JSValuePtr jsNumberCell(ExecState*, double);
public:
double value() const { return m_value; }
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
@@ -59,10 +64,7 @@ namespace JSC {
virtual UString toThisString(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
- virtual JSValue* getJSNumber();
-
- int32_t toInt32() const;
- uint32_t toUInt32() const;
+ virtual JSValuePtr getJSNumber();
void* operator new(size_t size, ExecState* exec)
{
@@ -82,22 +84,17 @@ namespace JSC {
#endif
}
- static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
-
- JSNumberCell(JSGlobalData* globalData)
- : JSCell(globalData->numberStructureID.get())
- {
- }
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
private:
JSNumberCell(JSGlobalData* globalData, double value)
- : JSCell(globalData->numberStructureID.get())
+ : JSCell(globalData->numberStructure.get())
, m_value(value)
{
}
JSNumberCell(ExecState* exec, double value)
- : JSCell(exec->globalData().numberStructureID.get())
+ : JSCell(exec->globalData().numberStructure.get())
, m_value(value)
{
}
@@ -109,157 +106,342 @@ namespace JSC {
double m_value;
};
- extern const double NaN;
- extern const double Inf;
-
- JSNumberCell* asNumberCell(JSValue*);
+ JSValuePtr jsNumberCell(JSGlobalData*, double);
- JSValue* jsNumberCell(JSGlobalData*, double);
- JSValue* jsNaN(JSGlobalData*);
- JSValue* jsNumberCell(ExecState*, double);
- JSValue* jsNaN(ExecState*);
-
- inline JSNumberCell* asNumberCell(JSValue* value)
+ inline bool isNumberCell(JSValuePtr v)
{
- ASSERT(asCell(value)->isNumber());
- return static_cast<JSNumberCell*>(asCell(value));
+ return v.isCell() && v.asCell()->isNumber();
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
+ inline JSNumberCell* asNumberCell(JSValuePtr v)
{
- JSValue* v = JSImmediate::from(d);
- return v ? v : jsNumberCell(exec, d);
+ ASSERT(isNumberCell(v));
+ return static_cast<JSNumberCell*>(v.asCell());
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, short i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, double d)
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
- }
-
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned short i)
- {
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValuePtr v = JSImmediate::from(d);
+ return v ? v : jsNumberCell(exec, d);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, int i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, double d)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, double d)
{
- JSValue* v = JSImmediate::from(d);
+ JSValuePtr v = JSImmediate::from(d);
return v ? v : jsNumberCell(globalData, d);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, short i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned short i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, int i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long long i)
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ JSValuePtr v = JSImmediate::from(i);
+ return v ? v : jsNumberCell(globalData, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i)
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ JSValuePtr v = JSImmediate::from(i);
+ return v ? v : jsNumberCell(globalData, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long long i)
+ inline bool JSValuePtr::isDoubleNumber() const
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ return isNumberCell(asValue());
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long long i)
+ inline double JSValuePtr::getDoubleNumber() const
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ return asNumberCell(asValue())->value();
+ }
+
+ inline bool JSValuePtr::isNumber() const
+ {
+ return JSImmediate::isNumber(asValue()) || isDoubleNumber();
+ }
+
+ inline double JSValuePtr::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
+ }
+
+#else
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, double d)
+ {
+ JSValuePtr v = JSImmediate::from(d);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, int i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, double d)
+ {
+ JSValuePtr v = JSImmediate::from(d);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, int i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ inline bool JSValuePtr::isDoubleNumber() const
+ {
+ return JSImmediate::isDoubleNumber(asValue());
+ }
+
+ inline double JSValuePtr::getDoubleNumber() const
+ {
+ return JSImmediate::doubleValue(asValue());
+ }
+
+ inline bool JSValuePtr::isNumber() const
+ {
+ return JSImmediate::isNumber(asValue());
+ }
+
+ inline double JSValuePtr::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return JSImmediate::toDouble(asValue());
+ }
+
+#endif
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ inline JSValuePtr jsNaN(ExecState* exec)
+ {
+ return jsNumber(exec, NaN);
+ }
+
+ inline JSValuePtr jsNaN(JSGlobalData* globalData)
+ {
+ return jsNumber(globalData, NaN);
}
// --- JSValue inlines ----------------------------
- inline double JSValue::uncheckedGetNumber() const
+ ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const
{
- ASSERT(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
- return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
+ return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
}
- inline int32_t JSNumberCell::toInt32() const
+ inline bool JSValuePtr::getNumber(double &result) const
{
- if (m_value >= -2147483648.0 && m_value < 2147483648.0)
- return static_cast<int32_t>(m_value);
- bool scratch;
- return JSC::toInt32SlowCase(m_value, scratch);
+ if (isInt32Fast())
+ result = getInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ result = getDoubleNumber();
+ else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
}
- inline uint32_t JSNumberCell::toUInt32() const
+ inline bool JSValuePtr::numberToInt32(int32_t& arg)
{
- if (m_value >= 0.0 && m_value < 4294967296.0)
- return static_cast<uint32_t>(m_value);
- bool scratch;
- return JSC::toUInt32SlowCase(m_value, scratch);
+ if (isInt32Fast())
+ arg = getInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ arg = JSC::toInt32(getDoubleNumber());
+ else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
}
- ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
+ inline bool JSValuePtr::numberToUInt32(uint32_t& arg)
{
- return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec));
+ if (isUInt32Fast())
+ arg = getUInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ arg = JSC::toUInt32(getDoubleNumber());
+ else if (isInt32Fast()) {
+ // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
+ // on a negative value is equivalent to simple static_casting.
+ bool ignored;
+ arg = toUInt32SlowCase(getInt32Fast(), ignored);
+ } else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
}
} // namespace JSC