diff options
Diffstat (limited to 'JavaScriptCore/runtime/JSValue.h')
| -rw-r--r-- | JavaScriptCore/runtime/JSValue.h | 282 |
1 files changed, 100 insertions, 182 deletions
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h index 6da921f..cad9662 100644 --- a/JavaScriptCore/runtime/JSValue.h +++ b/JavaScriptCore/runtime/JSValue.h @@ -23,8 +23,6 @@ #ifndef JSValue_h #define JSValue_h -#include "CallData.h" -#include "ConstructData.h" #include <math.h> #include <stddef.h> // for size_t #include <stdint.h> @@ -35,6 +33,7 @@ namespace JSC { + class ExecState; class Identifier; class JSCell; class JSGlobalData; @@ -57,8 +56,17 @@ namespace JSC { #endif double nonInlineNaN(); - int32_t toInt32SlowCase(double, bool& ok); - uint32_t toUInt32SlowCase(double, bool& ok); + + // This implements ToInt32, defined in ECMA-262 9.5. + int32_t toInt32(double); + + // This implements ToUInt32, defined in ECMA-262 9.6. + inline uint32_t toUInt32(double number) + { + // As commented in the spec, the operation of ToInt32 and ToUint32 only differ + // in how the result is interpreted; see NOTEs in sections 9.5 and 9.6. + return toInt32(number); + } class JSValue { friend class JSImmediate; @@ -66,11 +74,13 @@ namespace JSC { friend class JIT; friend class JITStubs; friend class JITStubCall; + friend class JSInterfaceJIT; + friend class SpecializedThunkJIT; public: static EncodedJSValue encode(JSValue value); static JSValue decode(EncodedJSValue ptr); -#if !USE(JSVALUE32_64) +#if USE(JSVALUE64) private: static JSValue makeImmediate(intptr_t value); intptr_t immediateValue(); @@ -91,21 +101,18 @@ namespace JSC { JSValue(const JSCell* ptr); // Numbers - JSValue(EncodeAsDoubleTag, ExecState*, double); - JSValue(ExecState*, double); - JSValue(ExecState*, char); - JSValue(ExecState*, unsigned char); - JSValue(ExecState*, short); - JSValue(ExecState*, unsigned short); - JSValue(ExecState*, int); - JSValue(ExecState*, unsigned); - JSValue(ExecState*, long); - JSValue(ExecState*, unsigned long); - JSValue(ExecState*, long long); - JSValue(ExecState*, unsigned long long); - JSValue(JSGlobalData*, double); - JSValue(JSGlobalData*, int); - JSValue(JSGlobalData*, unsigned); + JSValue(EncodeAsDoubleTag, double); + explicit JSValue(double); + explicit JSValue(char); + explicit JSValue(unsigned char); + explicit JSValue(short); + explicit JSValue(unsigned short); + explicit JSValue(int); + explicit JSValue(unsigned); + explicit JSValue(long); + explicit JSValue(unsigned long); + explicit JSValue(long long); + explicit JSValue(unsigned long long); operator bool() const; bool operator==(const JSValue& other) const; @@ -141,9 +148,6 @@ namespace JSC { UString getString(ExecState* exec) const; // null string if not a string JSObject* getObject() const; // 0 if not an object - CallType getCallData(CallData&); - ConstructType getConstructData(ConstructData&); - // Extracting integer values. bool getUInt32(uint32_t&) const; @@ -165,9 +169,7 @@ namespace JSC { double toInteger(ExecState*) const; double toIntegerPreserveNaN(ExecState*) const; int32_t toInt32(ExecState*) const; - int32_t toInt32(ExecState*, bool& ok) const; uint32_t toUInt32(ExecState*) const; - uint32_t toUInt32(ExecState*, bool& ok) const; #if ENABLE(JSC_ZOMBIES) bool isZombie() const; @@ -183,12 +185,14 @@ namespace JSC { JSValue get(ExecState*, unsigned propertyName) const; JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const; void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); + void putDirect(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); void put(ExecState*, unsigned propertyName, JSValue); bool needsThisConversion() const; JSObject* toThisObject(ExecState*) const; + JSValue toStrictThisObject(ExecState*) const; UString toThisString(ExecState*) const; - JSString* toThisJSString(ExecState*); + JSString* toThisJSString(ExecState*) const; static bool equal(ExecState* exec, JSValue v1, JSValue v2); static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2); @@ -201,6 +205,7 @@ namespace JSC { bool isCell() const; JSCell* asCell() const; + bool isValidCallee(); #ifndef NDEBUG char* description(); @@ -214,24 +219,24 @@ namespace JSC { JSObject* toObjectSlowCase(ExecState*) const; JSObject* toThisObjectSlowCase(ExecState*) const; - enum { Int32Tag = 0xffffffff }; - enum { CellTag = 0xfffffffe }; - enum { TrueTag = 0xfffffffd }; - enum { FalseTag = 0xfffffffc }; - enum { NullTag = 0xfffffffb }; - enum { UndefinedTag = 0xfffffffa }; + JSObject* synthesizePrototype(ExecState*) const; + JSObject* synthesizeObject(ExecState*) const; + +#if USE(JSVALUE32_64) + enum { NullTag = 0xffffffff }; + enum { UndefinedTag = 0xfffffffe }; + enum { Int32Tag = 0xfffffffd }; + enum { CellTag = 0xfffffffc }; + enum { TrueTag = 0xfffffffb }; + enum { FalseTag = 0xfffffffa }; enum { EmptyValueTag = 0xfffffff9 }; enum { DeletedValueTag = 0xfffffff8 }; - + enum { LowestTag = DeletedValueTag }; - + uint32_t tag() const; int32_t payload() const; - JSObject* synthesizePrototype(ExecState*) const; - JSObject* synthesizeObject(ExecState*) const; - -#if USE(JSVALUE32_64) union { EncodedJSValue asEncodedJSValue; double asDouble; @@ -286,79 +291,64 @@ namespace JSC { return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse); } - ALWAYS_INLINE JSValue jsDoubleNumber(ExecState* exec, double d) + ALWAYS_INLINE JSValue jsDoubleNumber(double d) { - return JSValue(JSValue::EncodeAsDouble, exec, d); + return JSValue(JSValue::EncodeAsDouble, d); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d) + ALWAYS_INLINE JSValue jsNumber(double d) { - return JSValue(exec, d); + return JSValue(d); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i) + ALWAYS_INLINE JSValue jsNumber(char i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i) + ALWAYS_INLINE JSValue jsNumber(unsigned char i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i) + ALWAYS_INLINE JSValue jsNumber(short i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i) + ALWAYS_INLINE JSValue jsNumber(unsigned short i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i) + ALWAYS_INLINE JSValue jsNumber(int i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i) + ALWAYS_INLINE JSValue jsNumber(unsigned i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i) + ALWAYS_INLINE JSValue jsNumber(long i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i) + ALWAYS_INLINE JSValue jsNumber(unsigned long i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i) + ALWAYS_INLINE JSValue jsNumber(long long i) { - return JSValue(exec, i); + return JSValue(i); } - ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i) + ALWAYS_INLINE JSValue jsNumber(unsigned long long i) { - return JSValue(exec, i); - } - - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d) - { - return JSValue(globalData, d); - } - - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i) - { - return JSValue(globalData, i); - } - - ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i) - { - return JSValue(globalData, i); + return JSValue(i); } inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); } @@ -367,70 +357,23 @@ namespace JSC { inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); } inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; } - inline int32_t toInt32(double val) - { - if (!(val >= -2147483648.0 && val < 2147483648.0)) { - bool ignored; - return toInt32SlowCase(val, ignored); - } - return static_cast<int32_t>(val); - } - - inline uint32_t toUInt32(double val) - { - if (!(val >= 0.0 && val < 4294967296.0)) { - bool ignored; - return toUInt32SlowCase(val, ignored); - } - return static_cast<uint32_t>(val); - } - - // FIXME: We should deprecate this and just use JSValue::asCell() instead. - JSCell* asCell(JSValue); - - inline JSCell* asCell(JSValue value) - { - return value.asCell(); - } - ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const { if (isInt32()) return asInt32(); - bool ignored; - return toInt32SlowCase(toNumber(exec), ignored); + return JSC::toInt32(toNumber(exec)); } inline uint32_t JSValue::toUInt32(ExecState* exec) const { - if (isUInt32()) - return asInt32(); - bool ignored; - return toUInt32SlowCase(toNumber(exec), ignored); - } - - inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const - { - if (isInt32()) { - ok = true; - return asInt32(); - } - return toInt32SlowCase(toNumber(exec), ok); - } - - inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const - { - if (isUInt32()) { - ok = true; - return asInt32(); - } - return toUInt32SlowCase(toNumber(exec), ok); + // See comment on JSC::toUInt32, above. + return toInt32(exec); } #if USE(JSVALUE32_64) - inline JSValue jsNaN(ExecState* exec) + inline JSValue jsNaN() { - return JSValue(exec, nonInlineNaN()); + return JSValue(nonInlineNaN()); } // JSValue member functions. @@ -604,115 +547,90 @@ namespace JSC { return reinterpret_cast<JSCell*>(u.asBits.payload); } - ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d) + ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d) { u.asDouble = d; } - inline JSValue::JSValue(ExecState* exec, double d) + inline JSValue::JSValue(double d) { const int32_t asInt32 = static_cast<int32_t>(d); if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0 u.asDouble = d; return; } - *this = JSValue(exec, static_cast<int32_t>(d)); + *this = JSValue(static_cast<int32_t>(d)); } - inline JSValue::JSValue(ExecState* exec, char i) + inline JSValue::JSValue(char i) { - *this = JSValue(exec, static_cast<int32_t>(i)); + *this = JSValue(static_cast<int32_t>(i)); } - inline JSValue::JSValue(ExecState* exec, unsigned char i) + inline JSValue::JSValue(unsigned char i) { - *this = JSValue(exec, static_cast<int32_t>(i)); + *this = JSValue(static_cast<int32_t>(i)); } - inline JSValue::JSValue(ExecState* exec, short i) + inline JSValue::JSValue(short i) { - *this = JSValue(exec, static_cast<int32_t>(i)); + *this = JSValue(static_cast<int32_t>(i)); } - inline JSValue::JSValue(ExecState* exec, unsigned short i) + inline JSValue::JSValue(unsigned short i) { - *this = JSValue(exec, static_cast<int32_t>(i)); + *this = JSValue(static_cast<int32_t>(i)); } - inline JSValue::JSValue(ExecState*, int i) + inline JSValue::JSValue(int i) { u.asBits.tag = Int32Tag; u.asBits.payload = i; } - inline JSValue::JSValue(ExecState* exec, unsigned i) + inline JSValue::JSValue(unsigned i) { if (static_cast<int32_t>(i) < 0) { - *this = JSValue(exec, static_cast<double>(i)); + *this = JSValue(static_cast<double>(i)); return; } - *this = JSValue(exec, static_cast<int32_t>(i)); + *this = JSValue(static_cast<int32_t>(i)); } - inline JSValue::JSValue(ExecState* exec, long i) + inline JSValue::JSValue(long i) { if (static_cast<int32_t>(i) != i) { - *this = JSValue(exec, static_cast<double>(i)); + *this = JSValue(static_cast<double>(i)); return; } - *this = JSValue(exec, static_cast<int32_t>(i)); + *this = JSValue(static_cast<int32_t>(i)); } - inline JSValue::JSValue(ExecState* exec, unsigned long i) + inline JSValue::JSValue(unsigned long i) { if (static_cast<uint32_t>(i) != i) { - *this = JSValue(exec, static_cast<double>(i)); + *this = JSValue(static_cast<double>(i)); return; } - *this = JSValue(exec, static_cast<uint32_t>(i)); + *this = JSValue(static_cast<uint32_t>(i)); } - inline JSValue::JSValue(ExecState* exec, long long i) + inline JSValue::JSValue(long long i) { if (static_cast<int32_t>(i) != i) { - *this = JSValue(exec, static_cast<double>(i)); + *this = JSValue(static_cast<double>(i)); return; } - *this = JSValue(exec, static_cast<int32_t>(i)); + *this = JSValue(static_cast<int32_t>(i)); } - inline JSValue::JSValue(ExecState* exec, unsigned long long i) + inline JSValue::JSValue(unsigned long long i) { if (static_cast<uint32_t>(i) != i) { - *this = JSValue(exec, static_cast<double>(i)); - return; - } - *this = JSValue(exec, static_cast<uint32_t>(i)); - } - - inline JSValue::JSValue(JSGlobalData* globalData, double d) - { - const int32_t asInt32 = static_cast<int32_t>(d); - if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0 - u.asDouble = d; - return; - } - *this = JSValue(globalData, static_cast<int32_t>(d)); - } - - inline JSValue::JSValue(JSGlobalData*, int i) - { - u.asBits.tag = Int32Tag; - u.asBits.payload = i; - } - - inline JSValue::JSValue(JSGlobalData* globalData, unsigned i) - { - if (static_cast<int32_t>(i) < 0) { - *this = JSValue(globalData, static_cast<double>(i)); + *this = JSValue(static_cast<double>(i)); return; } - *this = JSValue(globalData, static_cast<int32_t>(i)); + *this = JSValue(static_cast<uint32_t>(i)); } inline bool JSValue::isNumber() const @@ -753,7 +671,7 @@ namespace JSC { ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const { - return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec)); + return isNumber() ? asValue() : jsNumber(this->toNumber(exec)); } inline bool JSValue::getNumber(double& result) const |
