📄 jsimmediate.h
字号:
{ ASSERT(isImmediate(v)); return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate() : doubleToBoolean(doubleValue(v)) : v == trueImmediate(); }#else ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v) { ASSERT(isImmediate(v)); return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate(); }#endif ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValuePtr v) { // FIXME: should probably be asserting isPositiveIntegerNumber here. ASSERT(isIntegerNumber(v)); return intValue(v); }#if USE(ALTERNATE_JSIMMEDIATE) template<typename T> inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T value) { return makeDouble(static_cast<double>(value)); }#else template<typename T> inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T) { return noValue(); }#endif ALWAYS_INLINE JSValuePtr JSImmediate::from(char i) { return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(signed char i) { return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned char i) { return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(short i) { return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned short i) { return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(int i) {#if !USE(ALTERNATE_JSIMMEDIATE) if ((i < minImmediateInt) | (i > maxImmediateInt)) return fromNumberOutsideIntegerRange(i);#endif return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned i) { if (i > maxImmediateUInt) return fromNumberOutsideIntegerRange(i); return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(long i) { if ((i < minImmediateInt) | (i > maxImmediateInt)) return fromNumberOutsideIntegerRange(i); return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long i) { if (i > maxImmediateUInt) return fromNumberOutsideIntegerRange(i); return makeInt(i); } ALWAYS_INLINE JSValuePtr JSImmediate::from(long long i) { if ((i < minImmediateInt) | (i > maxImmediateInt)) return noValue(); return makeInt(static_cast<intptr_t>(i)); } ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long long i) { if (i > maxImmediateUInt) return fromNumberOutsideIntegerRange(i); return makeInt(static_cast<intptr_t>(i)); } ALWAYS_INLINE JSValuePtr JSImmediate::from(double d) { const int intVal = static_cast<int>(d); // Check for data loss from conversion to int. if (intVal != d || (!intVal && signbit(d))) return fromNumberOutsideIntegerRange(d); return from(intVal); } ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValuePtr v) { ASSERT(isIntegerNumber(v)); return intValue(v); } ALWAYS_INLINE double JSImmediate::toDouble(JSValuePtr v) { ASSERT(isImmediate(v)); if (isIntegerNumber(v)) return intValue(v);#if USE(ALTERNATE_JSIMMEDIATE) if (isNumber(v)) { ASSERT(isDoubleNumber(v)); return doubleValue(v); }#else ASSERT(!isNumber(v));#endif if (rawValue(v) == FullTagTypeUndefined) return nonInlineNaN(); ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate())); return rawValue(v) >> ExtendedPayloadShift; } ALWAYS_INLINE bool JSImmediate::getUInt32(JSValuePtr v, uint32_t& i) { i = uintValue(v); return isPositiveIntegerNumber(v); } ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValuePtr v, int32_t& i) { i = intValue(v); return isIntegerNumber(v); } ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValuePtr v, uint32_t& i) { return getUInt32(v, i); } inline JSValuePtr js0() { return JSImmediate::zeroImmediate(); } inline JSValuePtr jsNull() { return JSImmediate::nullImmediate(); } inline JSValuePtr jsBoolean(bool b) { return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate(); } inline JSValuePtr jsUndefined() { return JSImmediate::undefinedImmediate(); } inline JSValuePtr jsImpossibleValue() { return JSImmediate::impossibleValue(); } // These are identical logic to the JSValue functions above, and faster than jsNumber(number).toInt32(). int32_t toInt32(double); uint32_t toUInt32(double); int32_t toInt32SlowCase(double, bool& ok); uint32_t toUInt32SlowCase(double, bool& ok); inline bool JSValuePtr::isUndefined() const { return asValue() == jsUndefined(); } inline bool JSValuePtr::isNull() const { return asValue() == jsNull(); } inline bool JSValuePtr::isUndefinedOrNull() const { return JSImmediate::isUndefinedOrNull(asValue()); } inline bool JSValuePtr::isBoolean() const { return JSImmediate::isBoolean(asValue()); } inline bool JSValuePtr::getBoolean(bool& v) const { if (JSImmediate::isBoolean(asValue())) { v = JSImmediate::toBoolean(asValue()); return true; } return false; } inline bool JSValuePtr::getBoolean() const { return asValue() == jsBoolean(true); } ALWAYS_INLINE int32_t JSValuePtr::toInt32(ExecState* exec) const { int32_t i; if (getTruncatedInt32(i)) return i; bool ignored; return toInt32SlowCase(toNumber(exec), ignored); } inline uint32_t JSValuePtr::toUInt32(ExecState* exec) const { uint32_t i; if (getTruncatedUInt32(i)) return i; bool ignored; return toUInt32SlowCase(toNumber(exec), ignored); } 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); } inline int32_t JSValuePtr::toInt32(ExecState* exec, bool& ok) const { int32_t i; if (getTruncatedInt32(i)) { ok = true; return i; } return toInt32SlowCase(toNumber(exec), ok); } inline uint32_t JSValuePtr::toUInt32(ExecState* exec, bool& ok) const { uint32_t i; if (getTruncatedUInt32(i)) { ok = true; return i; } return toUInt32SlowCase(toNumber(exec), ok); } inline bool JSValuePtr::isCell() const { return !JSImmediate::isImmediate(asValue()); } inline bool JSValuePtr::isInt32Fast() const { return JSImmediate::isIntegerNumber(asValue()); } inline int32_t JSValuePtr::getInt32Fast() const { ASSERT(isInt32Fast()); return JSImmediate::getTruncatedInt32(asValue()); } inline bool JSValuePtr::isUInt32Fast() const { return JSImmediate::isPositiveIntegerNumber(asValue()); } inline uint32_t JSValuePtr::getUInt32Fast() const { ASSERT(isUInt32Fast()); return JSImmediate::getTruncatedUInt32(asValue()); } inline JSValuePtr JSValuePtr::makeInt32Fast(int32_t i) { return JSImmediate::from(i); } inline bool JSValuePtr::areBothInt32Fast(JSValuePtr v1, JSValuePtr v2) { return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); } class JSFastMath { public: static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValuePtr v1, JSValuePtr v2) { return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); } static ALWAYS_INLINE JSValuePtr equal(JSValuePtr v1, JSValuePtr v2) { ASSERT(canDoFastBitwiseOperations(v1, v2)); return jsBoolean(v1 == v2); } static ALWAYS_INLINE JSValuePtr notEqual(JSValuePtr v1, JSValuePtr v2) { ASSERT(canDoFastBitwiseOperations(v1, v2)); return jsBoolean(v1 != v2); } static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2) { ASSERT(canDoFastBitwiseOperations(v1, v2)); return JSImmediate::makeValue(JSImmediate::rawValue(v1) & JSImmediate::rawValue(v2)); } static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2) { ASSERT(canDoFastBitwiseOperations(v1, v2)); return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeNumber); } static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2) { ASSERT(canDoFastBitwiseOperations(v1, v2)); return JSImmediate::makeValue(JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2)); } static ALWAYS_INLINE bool canDoFastRshift(JSValuePtr v1, JSValuePtr v2) { return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); } static ALWAYS_INLINE bool canDoFastUrshift(JSValuePtr v1, JSValuePtr v2) { return JSImmediate::areBothImmediateIntegerNumbers(v1, v2) && !(JSImmediate::rawValue(v1) & JSImmediate::signBit); } static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift) { ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));#if USE(ALTERNATE_JSIMMEDIATE) return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber);#else return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber);#endif } static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v) { // Number is non-negative and an operation involving two of these can't overflow. // Checking for allowed negative numbers takes more time than it's worth on SunSpider. return (JSImmediate::rawValue(v) & (JSImmediate::TagTypeNumber + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeNumber; } static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v1, JSValuePtr v2) { // Number is non-negative and an operation involving two of these can't overflow. // Checking for allowed negative numbers takes more time than it's worth on SunSpider. return canDoFastAdditiveOperations(v1) && canDoFastAdditiveOperations(v2); } static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2) { ASSERT(canDoFastAdditiveOperations(v1, v2)); return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeNumber); } static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2) { ASSERT(canDoFastAdditiveOperations(v1, v2)); return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeNumber); } static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v) { ASSERT(canDoFastAdditiveOperations(v)); return JSImmediate::makeValue(JSImmediate::rawValue(v) + (1 << JSImmediate::IntegerPayloadShift)); } static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v) { ASSERT(canDoFastAdditiveOperations(v)); return JSImmediate::makeValue(JSImmediate::rawValue(v) - (1 << JSImmediate::IntegerPayloadShift)); } };} // namespace JSC#endif // JSImmediate_h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -