Changeset 39958 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- Jan 15, 2009, 7:20:35 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/runtime
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSCell.h
r39851 r39958 130 130 } 131 131 132 inline bool JSValuePtr::isNumberCell() const133 {134 return isCell() && asCell()->isNumber();135 }136 137 132 inline bool JSCell::isObject() const 138 133 { … … 176 171 177 172 // --- JSValue inlines ---------------------------- 178 179 inline bool JSValuePtr::isNumber() const180 {181 return JSImmediate::isNumber(asValue()) || (isCell() && asCell()->isNumber());182 }183 173 184 174 inline bool JSValuePtr::isString() const -
trunk/JavaScriptCore/runtime/JSGlobalData.cpp
r39951 r39958 80 80 , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull())) 81 81 , notAnObjectStructure(JSNotAnObject::createStructure(jsNull())) 82 #if !USE(ALTERNATE_JSIMMEDIATE) 82 83 , numberStructure(JSNumberCell::createStructure(jsNull())) 84 #endif 83 85 , identifierTable(createIdentifierTable()) 84 86 , propertyNames(new CommonIdentifiers(this)) -
trunk/JavaScriptCore/runtime/JSGlobalData.h
r39951 r39958 93 93 RefPtr<Structure> notAnObjectErrorStubStructure; 94 94 RefPtr<Structure> notAnObjectStructure; 95 #if !USE(ALTERNATE_JSIMMEDIATE) 95 96 RefPtr<Structure> numberStructure; 97 #endif 96 98 97 99 IdentifierTable* identifierTable; -
trunk/JavaScriptCore/runtime/JSImmediate.cpp
r39670 r39958 37 37 ASSERT(isImmediate(v)); 38 38 if (isNumber(v)) 39 return constructNumber FromImmediateNumber(exec, v);39 return constructNumber(exec, v); 40 40 if (isBoolean(v)) 41 41 return constructBooleanFromImmediateBoolean(exec, v); … … 52 52 ASSERT(isImmediate(v)); 53 53 if (isNumber(v)) 54 return constructNumber FromImmediateNumber(exec, v);54 return constructNumber(exec, v); 55 55 if (isBoolean(v)) 56 56 return constructBooleanFromImmediateBoolean(exec, v); … … 77 77 { 78 78 ASSERT(isImmediate(v)); 79 if (is Number(v))79 if (isIntegerNumber(v)) 80 80 return UString::from(getTruncatedInt32(v)); 81 #if USE(ALTERNATE_JSIMMEDIATE) 82 if (isNumber(v)) { 83 ASSERT(isDoubleNumber(v)); 84 double value = doubleValue(v); 85 if (value == 0.0) // +0.0 or -0.0 86 return "0"; 87 return UString::from(value); 88 } 89 #else 90 ASSERT(!isNumber(v)); 91 #endif 81 92 if (jsBoolean(false) == v) 82 93 return "false"; -
trunk/JavaScriptCore/runtime/JSImmediate.h
r39879 r39958 26 26 #include <wtf/AlwaysInline.h> 27 27 #include <wtf/MathExtras.h> 28 #include <wtf/StdLibExtras.h> 28 29 #include "JSValue.h" 29 30 #include <limits> … … 68 69 JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i); 69 70 71 #if USE(ALTERNATE_JSIMMEDIATE) 72 inline intptr_t reinterpretDoubleToIntptr(double value) 73 { 74 return WTF::bitwise_cast<intptr_t>(value); 75 } 76 77 inline double reinterpretIntptrToDouble(intptr_t value) 78 { 79 return WTF::bitwise_cast<double>(value); 80 } 81 #endif 82 70 83 /* 71 84 * A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged … … 112 125 /* 113 126 * On 64-bit platforms, we support an alternative encoding form for immediates, if 114 * USE(ALTERNATE_JSIMMEDIATE) is defined. 115 * 116 * The top 16-bits denote the type: 127 * USE(ALTERNATE_JSIMMEDIATE) is defined. When this format is used, double precision 128 * floating point values may also be encoded as JSImmediates. 129 * 130 * The encoding makes use of unused NaN space in the IEEE754 representation. Any value 131 * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values 132 * can encode a 51-bit payload. Hardware produced and C-library payloads typically 133 * have a payload of zero. We assume that non-zero payloads are available to encode 134 * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are 135 * all set represents a NaN with a non-zero payload, we can use this space in the NaN 136 * ranges to encode other values (however there are also other ranges of NaN space that 137 * could have been selected). This range of NaN space is represented by 64-bit numbers 138 * begining with the 16-bit hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no 139 * valid double-precision numbers will begin fall in these ranges. 140 * 141 * The scheme we have implemented encodes double precision values by adding 2^48 to the 142 * 64-bit integer representation of the number. After this manipulation, no encoded 143 * double-precision value will begin with the pattern 0x0000 or 0xFFFF. 144 * 145 * The top 16-bits denote the type of the encoded JSImmediate: 117 146 * 118 147 * Pointer: 0000:PPPP:PPPP:PPPP 148 * 0001:****:****:**** 149 * Double:{ ... 150 * FFFE:****:****:**** 119 151 * Integer: FFFF:0000:IIII:IIII 120 152 * 121 * 32-bit signed integers are marked with the 16-bit tag '0xFFFF'. The tag '0x0000'153 * 32-bit signed integers are marked with the 16-bit tag 0xFFFF. The tag 0x0000 122 154 * denotes a pointer, or another form of tagged immediate. Boolean, null and undefined 123 155 * values are encoded in the same manner as the default format. … … 156 188 157 189 #if USE(ALTERNATE_JSIMMEDIATE) 158 static const intptr_t TagTypeInteger = 0xffff000000000000ll; // bottom bit set indicates integer, this dominates the following bit 159 #else 160 static const intptr_t TagTypeInteger = 0x1; // bottom bit set indicates integer, this dominates the following bit 190 // If all bits in the mask are set, this indicates an integer number, 191 // if any but not all are set this value is a double precision number. 192 static const intptr_t TagTypeNumber = 0xffff000000000000ll; 193 // This value is 2^48, used to encode doubles such that the encoded value will begin 194 // with a 16-bit pattern within the range 0x0001..0xFFFE. 195 static const intptr_t DoubleEncodeOffset = 0x1000000000000ll; 196 #else 197 static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit 161 198 #endif 162 199 static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer 163 static const intptr_t TagMask = TagType Integer | TagBitTypeOther;200 static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther; 164 201 165 202 static const intptr_t ExtendedTagMask = 0xC; // extended tag holds a further two bits … … 190 227 static ALWAYS_INLINE bool isNumber(JSValuePtr v) 191 228 { 192 return rawValue(v) & TagTypeInteger; 193 } 194 195 static ALWAYS_INLINE bool isPositiveNumber(JSValuePtr v) 229 return rawValue(v) & TagTypeNumber; 230 } 231 232 static ALWAYS_INLINE bool isIntegerNumber(JSValuePtr v) 233 { 234 #if USE(ALTERNATE_JSIMMEDIATE) 235 return (rawValue(v) & TagTypeNumber) == TagTypeNumber; 236 #else 237 return isNumber(v); 238 #endif 239 } 240 241 #if USE(ALTERNATE_JSIMMEDIATE) 242 static ALWAYS_INLINE bool isDoubleNumber(JSValuePtr v) 243 { 244 return isNumber(v) && !isIntegerNumber(v); 245 } 246 #endif 247 248 static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValuePtr v) 196 249 { 197 250 // A single mask to check for the sign bit and the number tag all at once. 198 return (rawValue(v) & (signBit | TagType Integer)) == TagTypeInteger;251 return (rawValue(v) & (signBit | TagTypeNumber)) == TagTypeNumber; 199 252 } 200 253 … … 208 261 // Undefined and null share the same value, bar the 'undefined' bit in the extended tag. 209 262 return (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull; 210 }211 212 static bool isNegative(JSValuePtr v)213 {214 ASSERT(isNumber(v));215 return rawValue(v) & signBit;216 263 } 217 264 … … 239 286 } 240 287 241 static ALWAYS_INLINE bool areBothImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 242 { 243 return rawValue(v1) & rawValue(v2) & TagTypeInteger; 288 static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValuePtr v1, JSValuePtr v2) 289 { 290 #if USE(ALTERNATE_JSIMMEDIATE) 291 return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber; 292 #else 293 return rawValue(v1) & rawValue(v2) & TagTypeNumber; 294 #endif 244 295 } 245 296 … … 283 334 } 284 335 336 // With USE(ALTERNATE_JSIMMEDIATE) we want the argument to be zero extended, so the 337 // integer doesn't interfere with the tag bits in the upper word. In the default encoding, 338 // if intptr_t id larger then int32_t we sign extend the value through the upper word. 285 339 #if USE(ALTERNATE_JSIMMEDIATE) 286 340 static ALWAYS_INLINE JSValuePtr makeInt(uint32_t value) … … 289 343 #endif 290 344 { 291 return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeInteger); 292 } 345 return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber); 346 } 347 348 #if USE(ALTERNATE_JSIMMEDIATE) 349 static ALWAYS_INLINE JSValuePtr makeDouble(double value) 350 { 351 return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset); 352 } 353 #endif 293 354 294 355 static ALWAYS_INLINE JSValuePtr makeBool(bool b) … … 306 367 return makeValue(FullTagTypeNull); 307 368 } 308 369 370 template<typename T> 371 static JSValuePtr fromNumberOutsideIntegerRange(T); 372 373 #if USE(ALTERNATE_JSIMMEDIATE) 374 static ALWAYS_INLINE double doubleValue(JSValuePtr v) 375 { 376 return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset); 377 } 378 #endif 379 309 380 static ALWAYS_INLINE int32_t intValue(JSValuePtr v) 310 381 { … … 340 411 ALWAYS_INLINE JSValuePtr JSImmediate::impossibleValue() { return makeValue(0x4); } 341 412 413 #if USE(ALTERNATE_JSIMMEDIATE) 414 inline bool doubleToBoolean(double value) 415 { 416 return value < 0.0 || value > 0.0; 417 } 418 342 419 ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v) 343 420 { 344 421 ASSERT(isImmediate(v)); 345 intptr_t bits = rawValue(v); 346 return (bits & TagTypeInteger) 347 ? bits != TagTypeInteger // !0 ints 348 : bits == (FullTagTypeBool | ExtendedPayloadBitBoolValue); // bool true 349 } 422 return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate() 423 : doubleToBoolean(doubleValue(v)) : v == trueImmediate(); 424 } 425 #else 426 ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v) 427 { 428 ASSERT(isImmediate(v)); 429 return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate(); 430 } 431 #endif 350 432 351 433 ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValuePtr v) 352 434 { 353 ASSERT(isNumber(v)); 435 // FIXME: should probably be asserting isPositiveIntegerNumber here. 436 ASSERT(isIntegerNumber(v)); 354 437 return intValue(v); 355 438 } 356 439 440 #if USE(ALTERNATE_JSIMMEDIATE) 441 template<typename T> 442 inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T value) 443 { 444 return makeDouble(static_cast<double>(value)); 445 } 446 #else 447 template<typename T> 448 inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T) 449 { 450 return noValue(); 451 } 452 #endif 453 357 454 ALWAYS_INLINE JSValuePtr JSImmediate::from(char i) 358 455 { … … 382 479 ALWAYS_INLINE JSValuePtr JSImmediate::from(int i) 383 480 { 481 #if !USE(ALTERNATE_JSIMMEDIATE) 384 482 if ((i < minImmediateInt) | (i > maxImmediateInt)) 385 return noValue(); 483 return fromNumberOutsideIntegerRange(i); 484 #endif 386 485 return makeInt(i); 387 486 } … … 390 489 { 391 490 if (i > maxImmediateUInt) 392 return noValue();491 return fromNumberOutsideIntegerRange(i); 393 492 return makeInt(i); 394 493 } … … 397 496 { 398 497 if ((i < minImmediateInt) | (i > maxImmediateInt)) 399 return noValue();498 return fromNumberOutsideIntegerRange(i); 400 499 return makeInt(i); 401 500 } … … 404 503 { 405 504 if (i > maxImmediateUInt) 406 return noValue();505 return fromNumberOutsideIntegerRange(i); 407 506 return makeInt(i); 408 507 } … … 418 517 { 419 518 if (i > maxImmediateUInt) 420 return noValue();519 return fromNumberOutsideIntegerRange(i); 421 520 return makeInt(static_cast<intptr_t>(i)); 422 521 } … … 425 524 { 426 525 const int intVal = static_cast<int>(d); 427 428 if ((intVal < minImmediateInt) | (intVal > maxImmediateInt))429 return noValue();430 526 431 527 // Check for data loss from conversion to int. 432 528 if (intVal != d || (!intVal && signbit(d))) 433 return noValue();434 435 return makeInt(intVal);529 return fromNumberOutsideIntegerRange(d); 530 531 return from(intVal); 436 532 } 437 533 438 534 ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValuePtr v) 439 535 { 440 ASSERT(is Number(v));536 ASSERT(isIntegerNumber(v)); 441 537 return intValue(v); 442 538 } … … 445 541 { 446 542 ASSERT(isImmediate(v)); 447 int i; 448 if (isNumber(v)) 449 i = intValue(v); 450 else if (rawValue(v) == FullTagTypeUndefined) 543 544 if (isIntegerNumber(v)) 545 return intValue(v); 546 547 #if USE(ALTERNATE_JSIMMEDIATE) 548 if (isNumber(v)) { 549 ASSERT(isDoubleNumber(v)); 550 return doubleValue(v); 551 } 552 #else 553 ASSERT(!isNumber(v)); 554 #endif 555 556 if (rawValue(v) == FullTagTypeUndefined) 451 557 return nonInlineNaN(); 452 else 453 i = rawValue(v) >> ExtendedPayloadShift;454 return i;558 559 ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate())); 560 return rawValue(v) >> ExtendedPayloadShift; 455 561 } 456 562 … … 458 564 { 459 565 i = uintValue(v); 460 return isPositive Number(v);566 return isPositiveIntegerNumber(v); 461 567 } 462 568 … … 464 570 { 465 571 i = intValue(v); 466 return is Number(v);572 return isIntegerNumber(v); 467 573 } 468 574 … … 601 707 inline bool JSValuePtr::isInt32Fast() const 602 708 { 603 return JSImmediate::is Number(asValue());709 return JSImmediate::isIntegerNumber(asValue()); 604 710 } 605 711 … … 612 718 inline bool JSValuePtr::isUInt32Fast() const 613 719 { 614 return JSImmediate::isPositive Number(asValue());720 return JSImmediate::isPositiveIntegerNumber(asValue()); 615 721 } 616 722 … … 628 734 inline bool JSValuePtr::areBothInt32Fast(JSValuePtr v1, JSValuePtr v2) 629 735 { 630 return JSImmediate::areBothImmediate Numbers(v1, v2);736 return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); 631 737 } 632 738 … … 635 741 static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValuePtr v1, JSValuePtr v2) 636 742 { 637 return JSImmediate::areBothImmediate Numbers(v1, v2);743 return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); 638 744 } 639 745 … … 659 765 { 660 766 ASSERT(canDoFastBitwiseOperations(v1, v2)); 661 return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagType Integer);767 return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeNumber); 662 768 } 663 769 … … 670 776 static ALWAYS_INLINE bool canDoFastRshift(JSValuePtr v1, JSValuePtr v2) 671 777 { 672 return JSImmediate::areBothImmediate Numbers(v1, v2);778 return JSImmediate::areBothImmediateIntegerNumbers(v1, v2); 673 779 } 674 780 675 781 static ALWAYS_INLINE bool canDoFastUrshift(JSValuePtr v1, JSValuePtr v2) 676 782 { 677 return JSImmediate::areBothImmediate Numbers(v1, v2) && !JSImmediate::isNegative(v1);783 return JSImmediate::areBothImmediateIntegerNumbers(v1, v2) && !(JSImmediate::rawValue(v1) & JSImmediate::signBit); 678 784 } 679 785 … … 682 788 ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift)); 683 789 #if USE(ALTERNATE_JSIMMEDIATE) 684 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::TagType Integer);685 #else 686 return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagType Integer);790 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); 791 #else 792 return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber); 687 793 #endif 688 794 } … … 692 798 // Number is non-negative and an operation involving two of these can't overflow. 693 799 // Checking for allowed negative numbers takes more time than it's worth on SunSpider. 694 return (JSImmediate::rawValue(v) & (JSImmediate::TagType Integer + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeInteger;800 return (JSImmediate::rawValue(v) & (JSImmediate::TagTypeNumber + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeNumber; 695 801 } 696 802 … … 705 811 { 706 812 ASSERT(canDoFastAdditiveOperations(v1, v2)); 707 return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagType Integer);813 return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeNumber); 708 814 } 709 815 … … 711 817 { 712 818 ASSERT(canDoFastAdditiveOperations(v1, v2)); 713 return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagType Integer);819 return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeNumber); 714 820 } 715 821 -
trunk/JavaScriptCore/runtime/JSNumberCell.cpp
r39670 r39958 28 28 29 29 namespace JSC { 30 31 #if !USE(ALTERNATE_JSIMMEDIATE) 30 32 31 33 JSValuePtr JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const … … 102 104 } 103 105 104 NEVER_INLINEJSValuePtr jsNumberCell(ExecState* exec, double d)106 JSValuePtr jsNumberCell(ExecState* exec, double d) 105 107 { 106 108 return new (exec) JSNumberCell(exec, d); 107 109 } 108 110 109 NEVER_INLINE JSValuePtr jsNaN(ExecState* exec) 110 { 111 return new (exec) JSNumberCell(exec, NaN); 112 } 113 114 NEVER_INLINE JSValuePtr jsNumberCell(JSGlobalData* globalData, double d) 111 JSValuePtr jsNumberCell(JSGlobalData* globalData, double d) 115 112 { 116 113 return new (globalData) JSNumberCell(globalData, d); 117 114 } 118 115 119 NEVER_INLINE JSValuePtr jsNaN(JSGlobalData* globalData) 116 #else 117 118 JSValuePtr jsNumberCell(ExecState*, double) 120 119 { 121 return new (globalData) JSNumberCell(globalData, NaN); 120 ASSERT_NOT_REACHED(); 121 return noValue(); 122 122 } 123 123 124 #endif 125 124 126 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSNumberCell.h
r39851 r39958 33 33 namespace JSC { 34 34 35 extern const double NaN; 36 extern const double Inf; 37 38 #if !USE(ALTERNATE_JSIMMEDIATE) 39 35 40 class Identifier; 36 41 class JSCell; … … 45 50 friend class JIT; 46 51 friend JSValuePtr jsNumberCell(JSGlobalData*, double); 47 friend JSValuePtr jsNaN(JSGlobalData*);48 52 friend JSValuePtr jsNumberCell(ExecState*, double); 49 friend JSValuePtr jsNaN(ExecState*);50 53 public: 51 54 double value() const { return m_value; } … … 61 64 virtual JSObject* toThisObject(ExecState*) const; 62 65 virtual JSValuePtr getJSNumber(); 63 64 int32_t toInt32() const;65 uint32_t toUInt32() const;66 66 67 67 void* operator new(size_t size, ExecState* exec) … … 105 105 }; 106 106 107 extern const double NaN;108 extern const double Inf;109 110 107 JSValuePtr jsNumberCell(JSGlobalData*, double); 111 JSValuePtr jsNaN(JSGlobalData*);112 108 JSValuePtr jsNumberCell(ExecState*, double); 113 JSValuePtr jsNaN(ExecState*); 114 115 inline JSNumberCell* JSValuePtr::asNumberCell() const 116 { 117 ASSERT(isNumberCell()); 118 return static_cast<JSNumberCell*>(asCell()); 109 110 inline bool isNumberCell(JSValuePtr v) 111 { 112 return v.isCell() && v.asCell()->isNumber(); 113 } 114 115 inline JSNumberCell* asNumberCell(JSValuePtr v) 116 { 117 ASSERT(isNumberCell(v)); 118 return static_cast<JSNumberCell*>(v.asCell()); 119 119 } 120 120 … … 125 125 } 126 126 127 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i)128 {129 ASSERT(JSImmediate::from(i));130 return JSImmediate::from(i);131 }132 133 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i)134 {135 ASSERT(JSImmediate::from(i));136 return JSImmediate::from(i);137 }138 139 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i)140 {141 ASSERT(JSImmediate::from(i));142 return JSImmediate::from(i);143 }144 145 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i)146 {147 ASSERT(JSImmediate::from(i));148 return JSImmediate::from(i);149 }150 151 127 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, int i) 152 128 { … … 191 167 } 192 168 193 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, short i)169 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i) 194 170 { 195 171 JSValuePtr v = JSImmediate::from(i); … … 197 173 } 198 174 199 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned shorti)175 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i) 200 176 { 201 177 JSValuePtr v = JSImmediate::from(i); … … 203 179 } 204 180 205 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, inti)181 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i) 206 182 { 207 183 JSValuePtr v = JSImmediate::from(i); … … 209 185 } 210 186 211 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)187 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i) 212 188 { 213 189 JSValuePtr v = JSImmediate::from(i); … … 215 191 } 216 192 217 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)218 {219 JSValuePtr v = JSImmediate::from(i);220 return v ? v : jsNumberCell(globalData, i);221 }222 223 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)224 {225 JSValuePtr v = JSImmediate::from(i);226 return v ? v : jsNumberCell(globalData, i);227 }228 229 193 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long long i) 230 194 { … … 239 203 } 240 204 205 inline bool JSValuePtr::isDoubleNumber() const 206 { 207 return isNumberCell(asValue()); 208 } 209 210 inline double JSValuePtr::getDoubleNumber() const 211 { 212 return asNumberCell(asValue())->value(); 213 } 214 215 inline bool JSValuePtr::isNumber() const 216 { 217 return JSImmediate::isNumber(asValue()) || isDoubleNumber(); 218 } 219 220 inline double JSValuePtr::uncheckedGetNumber() const 221 { 222 ASSERT(isNumber()); 223 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber(); 224 } 225 226 #else 227 228 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, double d) 229 { 230 JSValuePtr v = JSImmediate::from(d); 231 ASSERT(v); 232 return v; 233 } 234 235 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, int i) 236 { 237 JSValuePtr v = JSImmediate::from(i); 238 ASSERT(v); 239 return v; 240 } 241 242 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned i) 243 { 244 JSValuePtr v = JSImmediate::from(i); 245 ASSERT(v); 246 return v; 247 } 248 249 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long i) 250 { 251 JSValuePtr v = JSImmediate::from(i); 252 ASSERT(v); 253 return v; 254 } 255 256 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long i) 257 { 258 JSValuePtr v = JSImmediate::from(i); 259 ASSERT(v); 260 return v; 261 } 262 263 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long long i) 264 { 265 JSValuePtr v = JSImmediate::from(static_cast<double>(i)); 266 ASSERT(v); 267 return v; 268 } 269 270 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long long i) 271 { 272 JSValuePtr v = JSImmediate::from(static_cast<double>(i)); 273 ASSERT(v); 274 return v; 275 } 276 277 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, double d) 278 { 279 JSValuePtr v = JSImmediate::from(d); 280 ASSERT(v); 281 return v; 282 } 283 284 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, int i) 285 { 286 JSValuePtr v = JSImmediate::from(i); 287 ASSERT(v); 288 return v; 289 } 290 291 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned i) 292 { 293 JSValuePtr v = JSImmediate::from(i); 294 ASSERT(v); 295 return v; 296 } 297 298 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long i) 299 { 300 JSValuePtr v = JSImmediate::from(i); 301 ASSERT(v); 302 return v; 303 } 304 305 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long i) 306 { 307 JSValuePtr v = JSImmediate::from(i); 308 ASSERT(v); 309 return v; 310 } 311 312 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long long i) 313 { 314 JSValuePtr v = JSImmediate::from(static_cast<double>(i)); 315 ASSERT(v); 316 return v; 317 } 318 319 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long long i) 320 { 321 JSValuePtr v = JSImmediate::from(static_cast<double>(i)); 322 ASSERT(v); 323 return v; 324 } 325 326 inline bool JSValuePtr::isDoubleNumber() const 327 { 328 return JSImmediate::isDoubleNumber(asValue()); 329 } 330 331 inline double JSValuePtr::getDoubleNumber() const 332 { 333 return JSImmediate::doubleValue(asValue()); 334 } 335 336 inline bool JSValuePtr::isNumber() const 337 { 338 return JSImmediate::isNumber(asValue()); 339 } 340 341 inline double JSValuePtr::uncheckedGetNumber() const 342 { 343 ASSERT(isNumber()); 344 return JSImmediate::toDouble(asValue()); 345 } 346 347 #endif 348 349 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i) 350 { 351 ASSERT(JSImmediate::from(i)); 352 return JSImmediate::from(i); 353 } 354 355 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i) 356 { 357 ASSERT(JSImmediate::from(i)); 358 return JSImmediate::from(i); 359 } 360 361 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i) 362 { 363 ASSERT(JSImmediate::from(i)); 364 return JSImmediate::from(i); 365 } 366 367 ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i) 368 { 369 ASSERT(JSImmediate::from(i)); 370 return JSImmediate::from(i); 371 } 372 373 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, short i) 374 { 375 ASSERT(JSImmediate::from(i)); 376 return JSImmediate::from(i); 377 } 378 379 ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned short i) 380 { 381 ASSERT(JSImmediate::from(i)); 382 return JSImmediate::from(i); 383 } 384 385 inline JSValuePtr jsNaN(ExecState* exec) 386 { 387 return jsNumber(exec, NaN); 388 } 389 390 inline JSValuePtr jsNaN(JSGlobalData* globalData) 391 { 392 return jsNumber(globalData, NaN); 393 } 394 241 395 // --- JSValue inlines ---------------------------- 242 243 inline double JSValuePtr::uncheckedGetNumber() const244 {245 ASSERT(isNumber());246 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell()->value();247 }248 249 inline int32_t JSNumberCell::toInt32() const250 {251 if (m_value >= -2147483648.0 && m_value < 2147483648.0)252 return static_cast<int32_t>(m_value);253 bool ignored;254 return toInt32SlowCase(m_value, ignored);255 }256 257 inline uint32_t JSNumberCell::toUInt32() const258 {259 if (m_value >= 0.0 && m_value < 4294967296.0)260 return static_cast<uint32_t>(m_value);261 bool ignored;262 return toUInt32SlowCase(m_value, ignored);263 }264 396 265 397 ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const … … 272 404 if (isInt32Fast()) 273 405 result = getInt32Fast(); 274 else if (LIKELY(is NumberCell()))275 result = asNumberCell()->value();406 else if (LIKELY(isDoubleNumber())) 407 result = getDoubleNumber(); 276 408 else { 277 409 ASSERT(!isNumber()); … … 285 417 if (isInt32Fast()) 286 418 arg = getInt32Fast(); 287 else if (LIKELY(is NumberCell()))288 arg = asNumberCell()->toInt32();419 else if (LIKELY(isDoubleNumber())) 420 arg = JSC::toInt32(getDoubleNumber()); 289 421 else { 290 422 ASSERT(!isNumber()); … … 298 430 if (isUInt32Fast()) 299 431 arg = getUInt32Fast(); 300 else if (LIKELY(is NumberCell()))301 arg = asNumberCell()->toUInt32();432 else if (LIKELY(isDoubleNumber())) 433 arg = JSC::toUInt32(getDoubleNumber()); 302 434 else if (isInt32Fast()) { 303 435 // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase -
trunk/JavaScriptCore/runtime/JSValue.h
r39851 r39958 34 34 class Identifier; 35 35 class JSCell; 36 class JSNumberCell;37 36 class JSObject; 38 37 class JSString; … … 207 206 inline const JSValuePtr asValue() const { return *this; } 208 207 209 bool is NumberCell() const;210 JSNumberCell* asNumberCell() const;208 bool isDoubleNumber() const; 209 double getDoubleNumber() const; 211 210 212 211 JSCell* m_ptr; -
trunk/JavaScriptCore/runtime/NumberConstructor.cpp
r39670 r39958 76 76 JSValuePtr numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&) 77 77 { 78 return jsNumber Cell(exec, -Inf);78 return jsNumber(exec, -Inf); 79 79 } 80 80 81 81 JSValuePtr numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&) 82 82 { 83 return jsNumber Cell(exec, Inf);83 return jsNumber(exec, Inf); 84 84 } 85 85 86 86 JSValuePtr numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&) 87 87 { 88 return jsNumber Cell(exec, 1.7976931348623157E+308);88 return jsNumber(exec, 1.7976931348623157E+308); 89 89 } 90 90 91 91 JSValuePtr numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&) 92 92 { 93 return jsNumber Cell(exec, 5E-324);93 return jsNumber(exec, 5E-324); 94 94 } 95 95 -
trunk/JavaScriptCore/runtime/NumberObject.cpp
r39670 r39958 42 42 } 43 43 44 NumberObject* constructNumber(ExecState* exec, JS NumberCell*number)44 NumberObject* constructNumber(ExecState* exec, JSValuePtr number) 45 45 { 46 46 NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure()); … … 49 49 } 50 50 51 NumberObject* constructNumberFromImmediateNumber(ExecState* exec, JSValuePtr value)52 {53 NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());54 object->setInternalValue(value);55 return object;56 }57 58 51 } // namespace JSC -
trunk/JavaScriptCore/runtime/NumberObject.h
r39670 r39958 26 26 namespace JSC { 27 27 28 class JSNumberCell;29 30 28 class NumberObject : public JSWrapperObject { 31 29 public: … … 40 38 }; 41 39 42 NumberObject* constructNumber(ExecState*, JSNumberCell*); 43 NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValuePtr); 40 NumberObject* constructNumber(ExecState*, JSValuePtr); 44 41 45 42 } // namespace JSC -
trunk/JavaScriptCore/runtime/Operations.h
r39851 r39958 32 32 inline bool JSValuePtr::equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 33 33 { 34 if (JSImmediate::areBothImmediate Numbers(v1, v2))34 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 35 35 return v1 == v2; 36 36 … … 40 40 ALWAYS_INLINE bool JSValuePtr::equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 41 41 { 42 ASSERT(!JSImmediate::areBothImmediate Numbers(v1, v2));42 ASSERT(!JSImmediate::areBothImmediateIntegerNumbers(v1, v2)); 43 43 44 44 do { … … 72 72 return false; 73 73 v1 = p1; 74 if (JSImmediate::areBothImmediate Numbers(v1, v2))74 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 75 75 return v1 == v2; 76 76 continue; … … 82 82 return false; 83 83 v2 = p2; 84 if (JSImmediate::areBothImmediate Numbers(v1, v2))84 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 85 85 return v1 == v2; 86 86 continue; … … 108 108 inline bool JSValuePtr::strictEqual(JSValuePtr v1, JSValuePtr v2) 109 109 { 110 if (JSImmediate::areBothImmediate (v1, v2))110 if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2)) 111 111 return v1 == v2; 112 112 113 if (JSImmediate::isEitherImmediate(v1, v2) & (v1 != js0()) & (v2 != js0())) 114 return false; 113 if (v1->isNumber() && v2->isNumber()) 114 return v1->uncheckedGetNumber() == v2->uncheckedGetNumber(); 115 116 if (JSImmediate::isEitherImmediate(v1, v2)) 117 return v1 == v2; 115 118 116 119 return strictEqualSlowCase(v1, v2); … … 119 122 ALWAYS_INLINE bool JSValuePtr::strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2) 120 123 { 121 ASSERT(!JSImmediate:: areBothImmediate(v1, v2));124 ASSERT(!JSImmediate::isEitherImmediate(v1, v2)); 122 125 123 if (JSImmediate::isEitherImmediate(v1, v2)) { 124 ASSERT(v1 == js0() || v2 == js0()); 125 ASSERT(v1 != v2); 126 127 // The reason we can't just return false here is that 0 === -0, 128 // and while the former is an immediate number, the latter is not. 129 if (v1 == js0()) 130 return v2->asCell()->isNumber() && v2->asNumberCell()->value() == 0; 131 return v1->asCell()->isNumber() && v1->asNumberCell()->value() == 0; 132 } 133 134 if (v1->asCell()->isNumber()) { 135 return v2->asCell()->isNumber() 136 && v1->asNumberCell()->value() == v2->asNumberCell()->value(); 137 } 138 139 if (v1->asCell()->isString()) { 140 return v2->asCell()->isString() 141 && asString(v1)->value() == asString(v2)->value(); 142 } 126 if (v1->asCell()->isString() && v2->asCell()->isString()) 127 return asString(v1)->value() == asString(v2)->value(); 143 128 144 129 return v1 == v2;
Note:
See TracChangeset
for help on using the changeset viewer.