2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include <wtf/Platform.h>
27 #if !USE(JSVALUE32_64)
29 #include <wtf/Assertions.h>
30 #include <wtf/AlwaysInline.h>
31 #include <wtf/MathExtras.h>
32 #include <wtf/StdLibExtras.h>
50 inline intptr_t reinterpretDoubleToIntptr(double value
)
52 return WTF::bitwise_cast
<intptr_t>(value
);
55 inline double reinterpretIntptrToDouble(intptr_t value
)
57 return WTF::bitwise_cast
<double>(value
);
62 * A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged
63 * value masquerading as a pointer). The low two bits in a JSValue* are available for type tagging
64 * because allocator alignment guarantees they will be 00 in cell pointers.
66 * For example, on a 32 bit system:
68 * JSCell*: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 00
69 * [ high 30 bits: pointer address ] [ low 2 bits -- always 0 ]
70 * JSImmediate: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TT
71 * [ high 30 bits: 'payload' ] [ low 2 bits -- tag ]
73 * Where the bottom two bits are non-zero they either indicate that the immediate is a 31 bit signed
74 * integer, or they mark the value as being an immediate of a type other than integer, with a secondary
75 * tag used to indicate the exact type.
77 * Where the lowest bit is set (TT is equal to 01 or 11) the high 31 bits form a 31 bit signed int value.
78 * Where TT is equal to 10 this indicates this is a type of immediate other than an integer, and the next
79 * two bits will form an extended tag.
81 * 31 bit signed int: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X1
82 * [ high 30 bits of the value ] [ high bit part of value ]
83 * Other: YYYYYYYYYYYYYYYYYYYYYYYYYYYY ZZ 10
84 * [ extended 'payload' ] [ extended tag ] [ tag 'other' ]
86 * Where the first bit of the extended tag is set this flags the value as being a boolean, and the following
87 * bit would flag the value as undefined. If neither bits are set, the value is null.
89 * Other: YYYYYYYYYYYYYYYYYYYYYYYYYYYY UB 10
90 * [ extended 'payload' ] [ undefined | bool ] [ tag 'other' ]
92 * For boolean value the lowest bit in the payload holds the value of the bool, all remaining bits are zero.
93 * For undefined or null immediates the payload is zero.
95 * Boolean: 000000000000000000000000000V 01 10
96 * [ boolean value ] [ bool ] [ tag 'other' ]
97 * Undefined: 0000000000000000000000000000 10 10
98 * [ zero ] [ undefined ] [ tag 'other' ]
99 * Null: 0000000000000000000000000000 00 10
100 * [ zero ] [ zero ] [ tag 'other' ]
104 * On 64-bit platforms, we support an alternative encoding form for immediates, if
105 * USE(JSVALUE64) is defined. When this format is used, double precision
106 * floating point values may also be encoded as JSImmediates.
108 * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
109 * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
110 * can encode a 51-bit payload. Hardware produced and C-library payloads typically
111 * have a payload of zero. We assume that non-zero payloads are available to encode
112 * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
113 * all set represents a NaN with a non-zero payload, we can use this space in the NaN
114 * ranges to encode other values (however there are also other ranges of NaN space that
115 * could have been selected). This range of NaN space is represented by 64-bit numbers
116 * begining with the 16-bit hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no
117 * valid double-precision numbers will begin fall in these ranges.
119 * The scheme we have implemented encodes double precision values by adding 2^48 to the
120 * 64-bit integer representation of the number. After this manipulation, no encoded
121 * double-precision value will begin with the pattern 0x0000 or 0xFFFF.
123 * The top 16-bits denote the type of the encoded JSImmediate:
125 * Pointer: 0000:PPPP:PPPP:PPPP
126 * 0001:****:****:****
128 * FFFE:****:****:****
129 * Integer: FFFF:0000:IIII:IIII
131 * 32-bit signed integers are marked with the 16-bit tag 0xFFFF. The tag 0x0000
132 * denotes a pointer, or another form of tagged immediate. Boolean, null and undefined
133 * values are encoded in the same manner as the default format.
139 friend class JSValue
;
140 friend class JSFastMath
;
141 friend JSValue
jsNumber(ExecState
* exec
, double d
);
142 friend JSValue
jsNumber(ExecState
*, char i
);
143 friend JSValue
jsNumber(ExecState
*, unsigned char i
);
144 friend JSValue
jsNumber(ExecState
*, short i
);
145 friend JSValue
jsNumber(ExecState
*, unsigned short i
);
146 friend JSValue
jsNumber(ExecState
* exec
, int i
);
147 friend JSValue
jsNumber(ExecState
* exec
, unsigned i
);
148 friend JSValue
jsNumber(ExecState
* exec
, long i
);
149 friend JSValue
jsNumber(ExecState
* exec
, unsigned long i
);
150 friend JSValue
jsNumber(ExecState
* exec
, long long i
);
151 friend JSValue
jsNumber(ExecState
* exec
, unsigned long long i
);
152 friend JSValue
jsNumber(JSGlobalData
* globalData
, double d
);
153 friend JSValue
jsNumber(JSGlobalData
* globalData
, short i
);
154 friend JSValue
jsNumber(JSGlobalData
* globalData
, unsigned short i
);
155 friend JSValue
jsNumber(JSGlobalData
* globalData
, int i
);
156 friend JSValue
jsNumber(JSGlobalData
* globalData
, unsigned i
);
157 friend JSValue
jsNumber(JSGlobalData
* globalData
, long i
);
158 friend JSValue
jsNumber(JSGlobalData
* globalData
, unsigned long i
);
159 friend JSValue
jsNumber(JSGlobalData
* globalData
, long long i
);
160 friend JSValue
jsNumber(JSGlobalData
* globalData
, unsigned long long i
);
163 // If all bits in the mask are set, this indicates an integer number,
164 // if any but not all are set this value is a double precision number.
165 static const intptr_t TagTypeNumber
= 0xffff000000000000ll
;
166 // This value is 2^48, used to encode doubles such that the encoded value will begin
167 // with a 16-bit pattern within the range 0x0001..0xFFFE.
168 static const intptr_t DoubleEncodeOffset
= 0x1000000000000ll
;
170 static const intptr_t TagTypeNumber
= 0x1; // bottom bit set indicates integer, this dominates the following bit
172 static const intptr_t TagBitTypeOther
= 0x2; // second bit set indicates immediate other than an integer
173 static const intptr_t TagMask
= TagTypeNumber
| TagBitTypeOther
;
175 static const intptr_t ExtendedTagMask
= 0xC; // extended tag holds a further two bits
176 static const intptr_t ExtendedTagBitBool
= 0x4;
177 static const intptr_t ExtendedTagBitUndefined
= 0x8;
179 static const intptr_t FullTagTypeMask
= TagMask
| ExtendedTagMask
;
180 static const intptr_t FullTagTypeBool
= TagBitTypeOther
| ExtendedTagBitBool
;
181 static const intptr_t FullTagTypeUndefined
= TagBitTypeOther
| ExtendedTagBitUndefined
;
182 static const intptr_t FullTagTypeNull
= TagBitTypeOther
;
185 static const int32_t IntegerPayloadShift
= 0;
187 static const int32_t IntegerPayloadShift
= 1;
189 static const int32_t ExtendedPayloadShift
= 4;
191 static const intptr_t ExtendedPayloadBitBoolValue
= 1 << ExtendedPayloadShift
;
193 static const int32_t signBit
= 0x80000000;
195 static ALWAYS_INLINE
bool isImmediate(JSValue v
)
197 return rawValue(v
) & TagMask
;
200 static ALWAYS_INLINE
bool isNumber(JSValue v
)
202 return rawValue(v
) & TagTypeNumber
;
205 static ALWAYS_INLINE
bool isIntegerNumber(JSValue v
)
208 return (rawValue(v
) & TagTypeNumber
) == TagTypeNumber
;
215 static ALWAYS_INLINE
bool isDouble(JSValue v
)
217 return isNumber(v
) && !isIntegerNumber(v
);
221 static ALWAYS_INLINE
bool isPositiveIntegerNumber(JSValue v
)
223 // A single mask to check for the sign bit and the number tag all at once.
224 return (rawValue(v
) & (signBit
| TagTypeNumber
)) == TagTypeNumber
;
227 static ALWAYS_INLINE
bool isBoolean(JSValue v
)
229 return (rawValue(v
) & FullTagTypeMask
) == FullTagTypeBool
;
232 static ALWAYS_INLINE
bool isUndefinedOrNull(JSValue v
)
234 // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
235 return (rawValue(v
) & ~ExtendedTagBitUndefined
) == FullTagTypeNull
;
238 static JSValue
from(char);
239 static JSValue
from(signed char);
240 static JSValue
from(unsigned char);
241 static JSValue
from(short);
242 static JSValue
from(unsigned short);
243 static JSValue
from(int);
244 static JSValue
from(unsigned);
245 static JSValue
from(long);
246 static JSValue
from(unsigned long);
247 static JSValue
from(long long);
248 static JSValue
from(unsigned long long);
249 static JSValue
from(double);
251 static ALWAYS_INLINE
bool isEitherImmediate(JSValue v1
, JSValue v2
)
253 return (rawValue(v1
) | rawValue(v2
)) & TagMask
;
256 static ALWAYS_INLINE
bool areBothImmediate(JSValue v1
, JSValue v2
)
258 return isImmediate(v1
) & isImmediate(v2
);
261 static ALWAYS_INLINE
bool areBothImmediateIntegerNumbers(JSValue v1
, JSValue v2
)
264 return (rawValue(v1
) & rawValue(v2
) & TagTypeNumber
) == TagTypeNumber
;
266 return rawValue(v1
) & rawValue(v2
) & TagTypeNumber
;
270 static double toDouble(JSValue
);
271 static bool toBoolean(JSValue
);
273 static bool getUInt32(JSValue
, uint32_t&);
274 static bool getTruncatedInt32(JSValue
, int32_t&);
275 static bool getTruncatedUInt32(JSValue
, uint32_t&);
277 static int32_t getTruncatedInt32(JSValue
);
278 static uint32_t getTruncatedUInt32(JSValue
);
280 static JSValue
trueImmediate();
281 static JSValue
falseImmediate();
282 static JSValue
undefinedImmediate();
283 static JSValue
nullImmediate();
284 static JSValue
zeroImmediate();
285 static JSValue
oneImmediate();
289 static const int minImmediateInt
= ((-INT_MAX
) - 1);
290 static const int maxImmediateInt
= INT_MAX
;
292 static const int minImmediateInt
= ((-INT_MAX
) - 1) >> IntegerPayloadShift
;
293 static const int maxImmediateInt
= INT_MAX
>> IntegerPayloadShift
;
295 static const unsigned maxImmediateUInt
= maxImmediateInt
;
297 static ALWAYS_INLINE JSValue
makeValue(intptr_t integer
)
299 return JSValue::makeImmediate(integer
);
302 // With USE(JSVALUE64) we want the argument to be zero extended, so the
303 // integer doesn't interfere with the tag bits in the upper word. In the default encoding,
304 // if intptr_t id larger then int32_t we sign extend the value through the upper word.
306 static ALWAYS_INLINE JSValue
makeInt(uint32_t value
)
308 static ALWAYS_INLINE JSValue
makeInt(int32_t value
)
311 return makeValue((static_cast<intptr_t>(value
) << IntegerPayloadShift
) | TagTypeNumber
);
315 static ALWAYS_INLINE JSValue
makeDouble(double value
)
317 return makeValue(reinterpretDoubleToIntptr(value
) + DoubleEncodeOffset
);
321 static ALWAYS_INLINE JSValue
makeBool(bool b
)
323 return makeValue((static_cast<intptr_t>(b
) << ExtendedPayloadShift
) | FullTagTypeBool
);
326 static ALWAYS_INLINE JSValue
makeUndefined()
328 return makeValue(FullTagTypeUndefined
);
331 static ALWAYS_INLINE JSValue
makeNull()
333 return makeValue(FullTagTypeNull
);
337 static JSValue
fromNumberOutsideIntegerRange(T
);
340 static ALWAYS_INLINE
double doubleValue(JSValue v
)
342 return reinterpretIntptrToDouble(rawValue(v
) - DoubleEncodeOffset
);
346 static ALWAYS_INLINE
int32_t intValue(JSValue v
)
348 return static_cast<int32_t>(rawValue(v
) >> IntegerPayloadShift
);
351 static ALWAYS_INLINE
uint32_t uintValue(JSValue v
)
353 return static_cast<uint32_t>(rawValue(v
) >> IntegerPayloadShift
);
356 static ALWAYS_INLINE
bool boolValue(JSValue v
)
358 return rawValue(v
) & ExtendedPayloadBitBoolValue
;
361 static ALWAYS_INLINE
intptr_t rawValue(JSValue v
)
363 return v
.immediateValue();
367 ALWAYS_INLINE JSValue
JSImmediate::trueImmediate() { return makeBool(true); }
368 ALWAYS_INLINE JSValue
JSImmediate::falseImmediate() { return makeBool(false); }
369 ALWAYS_INLINE JSValue
JSImmediate::undefinedImmediate() { return makeUndefined(); }
370 ALWAYS_INLINE JSValue
JSImmediate::nullImmediate() { return makeNull(); }
371 ALWAYS_INLINE JSValue
JSImmediate::zeroImmediate() { return makeInt(0); }
372 ALWAYS_INLINE JSValue
JSImmediate::oneImmediate() { return makeInt(1); }
375 inline bool doubleToBoolean(double value
)
377 return value
< 0.0 || value
> 0.0;
380 ALWAYS_INLINE
bool JSImmediate::toBoolean(JSValue v
)
382 ASSERT(isImmediate(v
));
383 return isNumber(v
) ? isIntegerNumber(v
) ? v
!= zeroImmediate()
384 : doubleToBoolean(doubleValue(v
)) : v
== trueImmediate();
387 ALWAYS_INLINE
bool JSImmediate::toBoolean(JSValue v
)
389 ASSERT(isImmediate(v
));
390 return isIntegerNumber(v
) ? v
!= zeroImmediate() : v
== trueImmediate();
394 ALWAYS_INLINE
uint32_t JSImmediate::getTruncatedUInt32(JSValue v
)
396 // FIXME: should probably be asserting isPositiveIntegerNumber here.
397 ASSERT(isIntegerNumber(v
));
403 inline JSValue
JSImmediate::fromNumberOutsideIntegerRange(T value
)
405 return makeDouble(static_cast<double>(value
));
409 inline JSValue
JSImmediate::fromNumberOutsideIntegerRange(T
)
415 ALWAYS_INLINE JSValue
JSImmediate::from(char i
)
420 ALWAYS_INLINE JSValue
JSImmediate::from(signed char i
)
425 ALWAYS_INLINE JSValue
JSImmediate::from(unsigned char i
)
430 ALWAYS_INLINE JSValue
JSImmediate::from(short i
)
435 ALWAYS_INLINE JSValue
JSImmediate::from(unsigned short i
)
440 ALWAYS_INLINE JSValue
JSImmediate::from(int i
)
443 if ((i
< minImmediateInt
) | (i
> maxImmediateInt
))
444 return fromNumberOutsideIntegerRange(i
);
449 ALWAYS_INLINE JSValue
JSImmediate::from(unsigned i
)
451 if (i
> maxImmediateUInt
)
452 return fromNumberOutsideIntegerRange(i
);
456 ALWAYS_INLINE JSValue
JSImmediate::from(long i
)
458 if ((i
< minImmediateInt
) | (i
> maxImmediateInt
))
459 return fromNumberOutsideIntegerRange(i
);
463 ALWAYS_INLINE JSValue
JSImmediate::from(unsigned long i
)
465 if (i
> maxImmediateUInt
)
466 return fromNumberOutsideIntegerRange(i
);
470 ALWAYS_INLINE JSValue
JSImmediate::from(long long i
)
472 if ((i
< minImmediateInt
) | (i
> maxImmediateInt
))
474 return makeInt(static_cast<intptr_t>(i
));
477 ALWAYS_INLINE JSValue
JSImmediate::from(unsigned long long i
)
479 if (i
> maxImmediateUInt
)
480 return fromNumberOutsideIntegerRange(i
);
481 return makeInt(static_cast<intptr_t>(i
));
484 ALWAYS_INLINE JSValue
JSImmediate::from(double d
)
486 const int intVal
= static_cast<int>(d
);
488 // Check for data loss from conversion to int.
489 if (intVal
!= d
|| (!intVal
&& signbit(d
)))
490 return fromNumberOutsideIntegerRange(d
);
495 ALWAYS_INLINE
int32_t JSImmediate::getTruncatedInt32(JSValue v
)
497 ASSERT(isIntegerNumber(v
));
501 ALWAYS_INLINE
double JSImmediate::toDouble(JSValue v
)
503 ASSERT(isImmediate(v
));
505 if (isIntegerNumber(v
))
511 return doubleValue(v
);
514 ASSERT(!isNumber(v
));
517 if (rawValue(v
) == FullTagTypeUndefined
)
518 return nonInlineNaN();
520 ASSERT(JSImmediate::isBoolean(v
) || (v
== JSImmediate::nullImmediate()));
521 return rawValue(v
) >> ExtendedPayloadShift
;
524 ALWAYS_INLINE
bool JSImmediate::getUInt32(JSValue v
, uint32_t& i
)
527 return isPositiveIntegerNumber(v
);
530 ALWAYS_INLINE
bool JSImmediate::getTruncatedInt32(JSValue v
, int32_t& i
)
533 return isIntegerNumber(v
);
536 ALWAYS_INLINE
bool JSImmediate::getTruncatedUInt32(JSValue v
, uint32_t& i
)
538 return getUInt32(v
, i
);
541 inline JSValue::JSValue(JSNullTag
)
543 *this = JSImmediate::nullImmediate();
546 inline JSValue::JSValue(JSUndefinedTag
)
548 *this = JSImmediate::undefinedImmediate();
551 inline JSValue::JSValue(JSTrueTag
)
553 *this = JSImmediate::trueImmediate();
556 inline JSValue::JSValue(JSFalseTag
)
558 *this = JSImmediate::falseImmediate();
561 inline bool JSValue::isUndefinedOrNull() const
563 return JSImmediate::isUndefinedOrNull(asValue());
566 inline bool JSValue::isBoolean() const
568 return JSImmediate::isBoolean(asValue());
571 inline bool JSValue::isTrue() const
573 return asValue() == JSImmediate::trueImmediate();
576 inline bool JSValue::isFalse() const
578 return asValue() == JSImmediate::falseImmediate();
581 inline bool JSValue::getBoolean(bool& v
) const
583 if (JSImmediate::isBoolean(asValue())) {
584 v
= JSImmediate::toBoolean(asValue());
591 inline bool JSValue::getBoolean() const
593 return asValue() == jsBoolean(true);
596 inline bool JSValue::isCell() const
598 return !JSImmediate::isImmediate(asValue());
601 inline bool JSValue::isInt32() const
603 return JSImmediate::isIntegerNumber(asValue());
606 inline int32_t JSValue::asInt32() const
609 return JSImmediate::getTruncatedInt32(asValue());
612 inline bool JSValue::isUInt32() const
614 return JSImmediate::isPositiveIntegerNumber(asValue());
617 inline uint32_t JSValue::asUInt32() const
620 return JSImmediate::getTruncatedUInt32(asValue());
625 static ALWAYS_INLINE
bool canDoFastBitwiseOperations(JSValue v1
, JSValue v2
)
627 return JSImmediate::areBothImmediateIntegerNumbers(v1
, v2
);
630 static ALWAYS_INLINE JSValue
equal(JSValue v1
, JSValue v2
)
632 ASSERT(canDoFastBitwiseOperations(v1
, v2
));
633 return jsBoolean(v1
== v2
);
636 static ALWAYS_INLINE JSValue
notEqual(JSValue v1
, JSValue v2
)
638 ASSERT(canDoFastBitwiseOperations(v1
, v2
));
639 return jsBoolean(v1
!= v2
);
642 static ALWAYS_INLINE JSValue
andImmediateNumbers(JSValue v1
, JSValue v2
)
644 ASSERT(canDoFastBitwiseOperations(v1
, v2
));
645 return JSImmediate::makeValue(JSImmediate::rawValue(v1
) & JSImmediate::rawValue(v2
));
648 static ALWAYS_INLINE JSValue
xorImmediateNumbers(JSValue v1
, JSValue v2
)
650 ASSERT(canDoFastBitwiseOperations(v1
, v2
));
651 return JSImmediate::makeValue((JSImmediate::rawValue(v1
) ^ JSImmediate::rawValue(v2
)) | JSImmediate::TagTypeNumber
);
654 static ALWAYS_INLINE JSValue
orImmediateNumbers(JSValue v1
, JSValue v2
)
656 ASSERT(canDoFastBitwiseOperations(v1
, v2
));
657 return JSImmediate::makeValue(JSImmediate::rawValue(v1
) | JSImmediate::rawValue(v2
));
660 static ALWAYS_INLINE
bool canDoFastRshift(JSValue v1
, JSValue v2
)
662 return JSImmediate::areBothImmediateIntegerNumbers(v1
, v2
);
665 static ALWAYS_INLINE
bool canDoFastUrshift(JSValue v1
, JSValue v2
)
667 return JSImmediate::areBothImmediateIntegerNumbers(v1
, v2
) && !(JSImmediate::rawValue(v1
) & JSImmediate::signBit
);
670 static ALWAYS_INLINE JSValue
rightShiftImmediateNumbers(JSValue val
, JSValue shift
)
672 ASSERT(canDoFastRshift(val
, shift
) || canDoFastUrshift(val
, shift
));
674 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
);
676 return JSImmediate::makeValue((JSImmediate::rawValue(val
) >> ((JSImmediate::rawValue(shift
) >> JSImmediate::IntegerPayloadShift
) & 0x1f)) | JSImmediate::TagTypeNumber
);
680 static ALWAYS_INLINE
bool canDoFastAdditiveOperations(JSValue v
)
682 // Number is non-negative and an operation involving two of these can't overflow.
683 // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
684 return (JSImmediate::rawValue(v
) & (JSImmediate::TagTypeNumber
+ (JSImmediate::signBit
| (JSImmediate::signBit
>> 1)))) == JSImmediate::TagTypeNumber
;
687 static ALWAYS_INLINE
bool canDoFastAdditiveOperations(JSValue v1
, JSValue v2
)
689 // Number is non-negative and an operation involving two of these can't overflow.
690 // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
691 return canDoFastAdditiveOperations(v1
) && canDoFastAdditiveOperations(v2
);
694 static ALWAYS_INLINE JSValue
addImmediateNumbers(JSValue v1
, JSValue v2
)
696 ASSERT(canDoFastAdditiveOperations(v1
, v2
));
697 return JSImmediate::makeValue(JSImmediate::rawValue(v1
) + JSImmediate::rawValue(v2
) - JSImmediate::TagTypeNumber
);
700 static ALWAYS_INLINE JSValue
subImmediateNumbers(JSValue v1
, JSValue v2
)
702 ASSERT(canDoFastAdditiveOperations(v1
, v2
));
703 return JSImmediate::makeValue(JSImmediate::rawValue(v1
) - JSImmediate::rawValue(v2
) + JSImmediate::TagTypeNumber
);
706 static ALWAYS_INLINE JSValue
incImmediateNumber(JSValue v
)
708 ASSERT(canDoFastAdditiveOperations(v
));
709 return JSImmediate::makeValue(JSImmediate::rawValue(v
) + (1 << JSImmediate::IntegerPayloadShift
));
712 static ALWAYS_INLINE JSValue
decImmediateNumber(JSValue v
)
714 ASSERT(canDoFastAdditiveOperations(v
));
715 return JSImmediate::makeValue(JSImmediate::rawValue(v
) - (1 << JSImmediate::IntegerPayloadShift
));
721 #endif // !USE(JSVALUE32_64)
723 #endif // JSImmediate_h