Changeset 39851 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- Jan 12, 2009, 8:51:16 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/runtime
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/ArrayPrototype.cpp
r39670 r39851 754 754 if (!e) 755 755 continue; 756 if ( strictEqual(searchElement, e))756 if (JSValuePtr::strictEqual(searchElement, e)) 757 757 return jsNumber(exec, index); 758 758 } … … 785 785 if (!e) 786 786 continue; 787 if ( strictEqual(searchElement, e))787 if (JSValuePtr::strictEqual(searchElement, e)) 788 788 return jsNumber(exec, index); 789 789 } -
trunk/JavaScriptCore/runtime/BooleanPrototype.cpp
r39670 r39851 71 71 JSValuePtr booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&) 72 72 { 73 if ( JSImmediate::isBoolean(thisValue))73 if (thisValue->isBoolean()) 74 74 return thisValue; 75 75 -
trunk/JavaScriptCore/runtime/Collector.cpp
r39707 r39851 809 809 ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance); 810 810 811 if ( JSImmediate::isImmediate(k))811 if (!k->isCell()) 812 812 return; 813 813 … … 826 826 ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance); 827 827 828 if ( JSImmediate::isImmediate(k))828 if (!k->isCell()) 829 829 return; 830 830 … … 840 840 Heap* Heap::heap(JSValuePtr v) 841 841 { 842 if ( JSImmediate::isImmediate(v))842 if (!v->isCell()) 843 843 return 0; 844 844 return Heap::cellBlock(v->asCell())->heap; -
trunk/JavaScriptCore/runtime/JSByteArray.cpp
r39670 r39851 53 53 unsigned index = propertyName.toUInt32(&ok, false); 54 54 if (ok && canAccessIndex(index)) { 55 slot.setValue(getIndex( index));55 slot.setValue(getIndex(exec, index)); 56 56 return true; 57 57 } … … 62 62 { 63 63 if (canAccessIndex(propertyName)) { 64 slot.setValue(getIndex( propertyName));64 slot.setValue(getIndex(exec, propertyName)); 65 65 return true; 66 66 } -
trunk/JavaScriptCore/runtime/JSByteArray.h
r39670 r39851 36 36 public: 37 37 bool canAccessIndex(unsigned i) { return i < m_storage->length(); } 38 JSValuePtr getIndex( unsigned i)38 JSValuePtr getIndex(ExecState* exec, unsigned i) 39 39 { 40 40 ASSERT(canAccessIndex(i)); 41 return JSImmediate::from(m_storage->data()[i]);41 return jsNumber(exec, m_storage->data()[i]); 42 42 } 43 43 -
trunk/JavaScriptCore/runtime/JSCell.cpp
r39670 r39851 101 101 } 102 102 103 bool JSCell::getNumber(double& numericValue) const104 {105 if (!isNumber())106 return false;107 numericValue = static_cast<const JSNumberCell*>(this)->value();108 return true;109 }110 111 double JSCell::getNumber() const112 {113 return isNumber() ? static_cast<const JSNumberCell*>(this)->value() : NaN;114 }115 116 103 bool JSCell::getString(UString&stringValue) const 117 104 { -
trunk/JavaScriptCore/runtime/JSCell.h
r39769 r39851 58 58 59 59 // Extracting the value. 60 bool getNumber(double&) const;61 double getNumber() const; // NaN if not a number62 60 bool getString(UString&) const; 63 61 UString getString() const; // null string if not a string … … 69 67 70 68 // Extracting integer values. 69 // FIXME: remove these methods, can check isNumberCell in JSValuePtr && then call asNumberCell::*. 71 70 virtual bool getUInt32(uint32_t&) const; 72 71 virtual bool getTruncatedInt32(int32_t&) const; … … 131 130 } 132 131 132 inline bool JSValuePtr::isNumberCell() const 133 { 134 return isCell() && asCell()->isNumber(); 135 } 136 133 137 inline bool JSCell::isObject() const 134 138 { … … 158 162 ALWAYS_INLINE JSCell* JSValuePtr::asCell() const 159 163 { 160 ASSERT( !JSImmediate::isImmediate(asValue()));164 ASSERT(isCell()); 161 165 return m_ptr; 162 166 } … … 175 179 inline bool JSValuePtr::isNumber() const 176 180 { 177 return JSImmediate::isNumber(asValue()) || ( !JSImmediate::isImmediate(asValue()) && asCell()->isNumber());181 return JSImmediate::isNumber(asValue()) || (isCell() && asCell()->isNumber()); 178 182 } 179 183 … … 191 195 { 192 196 return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(); 193 }194 195 inline double JSValuePtr::getNumber() const196 {197 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->getNumber();198 197 } 199 198 -
trunk/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r39670 r39851 300 300 301 301 if (value->isNumber() && (radix == 0 || radix == 10)) { 302 if ( JSImmediate::isImmediate(value))302 if (value->isInt32Fast()) 303 303 return value; 304 304 double d = value->uncheckedGetNumber(); 305 305 if (!isfinite(d)) 306 return JSImmediate::zeroImmediate();306 return js0(); 307 307 return jsNumber(exec, floor(d)); 308 308 } -
trunk/JavaScriptCore/runtime/JSImmediate.h
r39769 r39851 37 37 class ExecState; 38 38 class JSCell; 39 class JSFastMath; 40 class JSGlobalData; 39 41 class JSObject; 40 42 class UString; 43 44 JSValuePtr js0(); 45 JSValuePtr jsNull(); 46 JSValuePtr jsBoolean(bool b); 47 JSValuePtr jsUndefined(); 48 JSValuePtr jsImpossibleValue(); 49 JSValuePtr jsNumber(ExecState* exec, double d); 50 JSValuePtr jsNumber(ExecState*, char i); 51 JSValuePtr jsNumber(ExecState*, unsigned char i); 52 JSValuePtr jsNumber(ExecState*, short i); 53 JSValuePtr jsNumber(ExecState*, unsigned short i); 54 JSValuePtr jsNumber(ExecState* exec, int i); 55 JSValuePtr jsNumber(ExecState* exec, unsigned i); 56 JSValuePtr jsNumber(ExecState* exec, long i); 57 JSValuePtr jsNumber(ExecState* exec, unsigned long i); 58 JSValuePtr jsNumber(ExecState* exec, long long i); 59 JSValuePtr jsNumber(ExecState* exec, unsigned long long i); 60 JSValuePtr jsNumber(JSGlobalData* globalData, double d); 61 JSValuePtr jsNumber(JSGlobalData* globalData, short i); 62 JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i); 63 JSValuePtr jsNumber(JSGlobalData* globalData, int i); 64 JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i); 65 JSValuePtr jsNumber(JSGlobalData* globalData, long i); 66 JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i); 67 JSValuePtr jsNumber(JSGlobalData* globalData, long long i); 68 JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i); 41 69 42 70 /* … … 99 127 private: 100 128 friend class JIT; 101 129 friend class JSValuePtr; 130 friend class JSFastMath; 131 friend JSValuePtr js0(); 132 friend JSValuePtr jsNull(); 133 friend JSValuePtr jsBoolean(bool b); 134 friend JSValuePtr jsUndefined(); 135 friend JSValuePtr jsImpossibleValue(); 136 friend JSValuePtr jsNumber(ExecState* exec, double d); 137 friend JSValuePtr jsNumber(ExecState*, char i); 138 friend JSValuePtr jsNumber(ExecState*, unsigned char i); 139 friend JSValuePtr jsNumber(ExecState*, short i); 140 friend JSValuePtr jsNumber(ExecState*, unsigned short i); 141 friend JSValuePtr jsNumber(ExecState* exec, int i); 142 friend JSValuePtr jsNumber(ExecState* exec, unsigned i); 143 friend JSValuePtr jsNumber(ExecState* exec, long i); 144 friend JSValuePtr jsNumber(ExecState* exec, unsigned long i); 145 friend JSValuePtr jsNumber(ExecState* exec, long long i); 146 friend JSValuePtr jsNumber(ExecState* exec, unsigned long long i); 147 friend JSValuePtr jsNumber(JSGlobalData* globalData, double d); 148 friend JSValuePtr jsNumber(JSGlobalData* globalData, short i); 149 friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i); 150 friend JSValuePtr jsNumber(JSGlobalData* globalData, int i); 151 friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i); 152 friend JSValuePtr jsNumber(JSGlobalData* globalData, long i); 153 friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i); 154 friend JSValuePtr jsNumber(JSGlobalData* globalData, long long i); 155 friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i); 156 102 157 #if USE(ALTERNATE_JSIMMEDIATE) 103 158 static const intptr_t TagTypeInteger = 0xffff000000000000ll; // bottom bit set indicates integer, this dominates the following bit … … 128 183 static const int32_t signBit = 0x80000000; 129 184 130 public:131 185 static ALWAYS_INLINE bool isImmediate(JSValuePtr v) 132 186 { … … 180 234 } 181 235 182 static ALWAYS_INLINE bool isAnyImmediate(JSValuePtr v1, JSValuePtr v2, JSValuePtr v3)183 {184 return (rawValue(v1) | rawValue(v2) | rawValue(v3)) & TagMask;185 }186 187 236 static ALWAYS_INLINE bool areBothImmediate(JSValuePtr v1, JSValuePtr v2) 188 237 { … … 193 242 { 194 243 return rawValue(v1) & rawValue(v2) & TagTypeInteger; 195 }196 197 static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2)198 {199 ASSERT(areBothImmediateNumbers(v1, v2));200 return makeValue(rawValue(v1) & rawValue(v2));201 }202 203 static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2)204 {205 ASSERT(areBothImmediateNumbers(v1, v2));206 return makeValue((rawValue(v1) ^ rawValue(v2)) | TagTypeInteger);207 }208 209 static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2)210 {211 ASSERT(areBothImmediateNumbers(v1, v2));212 return makeValue(rawValue(v1) | rawValue(v2));213 }214 215 static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift)216 {217 ASSERT(areBothImmediateNumbers(val, shift));218 #if USE(ALTERNATE_JSIMMEDIATE)219 return makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(rawValue(val)) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f))) | TagTypeInteger);220 #else221 return makeValue((rawValue(val) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagTypeInteger);222 #endif223 }224 225 static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v)226 {227 // Number is non-negative and an operation involving two of these can't overflow.228 // Checking for allowed negative numbers takes more time than it's worth on SunSpider.229 return (rawValue(v) & (TagTypeInteger + (signBit | (signBit >> 1)))) == TagTypeInteger;230 }231 232 static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2)233 {234 ASSERT(canDoFastAdditiveOperations(v1));235 ASSERT(canDoFastAdditiveOperations(v2));236 return makeValue(rawValue(v1) + rawValue(v2) - TagTypeInteger);237 }238 239 static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2)240 {241 ASSERT(canDoFastAdditiveOperations(v1));242 ASSERT(canDoFastAdditiveOperations(v2));243 return makeValue(rawValue(v1) - rawValue(v2) + TagTypeInteger);244 }245 246 static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v)247 {248 ASSERT(canDoFastAdditiveOperations(v));249 return makeValue(rawValue(v) + (1 << IntegerPayloadShift));250 }251 252 static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v)253 {254 ASSERT(canDoFastAdditiveOperations(v));255 return makeValue(rawValue(v) - (1 << IntegerPayloadShift));256 244 } 257 245 … … 484 472 } 485 473 474 inline JSValuePtr js0() 475 { 476 return JSImmediate::zeroImmediate(); 477 } 478 486 479 inline JSValuePtr jsNull() 487 480 { … … 497 490 { 498 491 return JSImmediate::undefinedImmediate(); 492 } 493 494 inline JSValuePtr jsImpossibleValue() 495 { 496 return JSImmediate::impossibleValue(); 499 497 } 500 498 … … 545 543 if (getTruncatedInt32(i)) 546 544 return i; 547 bool ok;548 return toInt32SlowCase( exec, ok);545 bool ignored; 546 return toInt32SlowCase(toNumber(exec), ignored); 549 547 } 550 548 … … 554 552 if (getTruncatedUInt32(i)) 555 553 return i; 556 bool ok;557 return toUInt32SlowCase( exec, ok);554 bool ignored; 555 return toUInt32SlowCase(toNumber(exec), ignored); 558 556 } 559 557 … … 583 581 return i; 584 582 } 585 return toInt32SlowCase( exec, ok);583 return toInt32SlowCase(toNumber(exec), ok); 586 584 } 587 585 … … 593 591 return i; 594 592 } 595 return toUInt32SlowCase(exec, ok); 596 } 593 return toUInt32SlowCase(toNumber(exec), ok); 594 } 595 596 inline bool JSValuePtr::isCell() const 597 { 598 return !JSImmediate::isImmediate(asValue()); 599 } 600 601 inline bool JSValuePtr::isInt32Fast() const 602 { 603 return JSImmediate::isNumber(asValue()); 604 } 605 606 inline int32_t JSValuePtr::getInt32Fast() const 607 { 608 ASSERT(isInt32Fast()); 609 return JSImmediate::getTruncatedInt32(asValue()); 610 } 611 612 inline bool JSValuePtr::isUInt32Fast() const 613 { 614 return JSImmediate::isPositiveNumber(asValue()); 615 } 616 617 inline uint32_t JSValuePtr::getUInt32Fast() const 618 { 619 ASSERT(isUInt32Fast()); 620 return JSImmediate::getTruncatedUInt32(asValue()); 621 } 622 623 inline JSValuePtr JSValuePtr::makeInt32Fast(int32_t i) 624 { 625 return JSImmediate::from(i); 626 } 627 628 inline bool JSValuePtr::areBothInt32Fast(JSValuePtr v1, JSValuePtr v2) 629 { 630 return JSImmediate::areBothImmediateNumbers(v1, v2); 631 } 632 633 class JSFastMath { 634 public: 635 static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValuePtr v1, JSValuePtr v2) 636 { 637 return JSImmediate::areBothImmediateNumbers(v1, v2); 638 } 639 640 static ALWAYS_INLINE JSValuePtr equal(JSValuePtr v1, JSValuePtr v2) 641 { 642 ASSERT(canDoFastBitwiseOperations(v1, v2)); 643 return jsBoolean(v1 == v2); 644 } 645 646 static ALWAYS_INLINE JSValuePtr notEqual(JSValuePtr v1, JSValuePtr v2) 647 { 648 ASSERT(canDoFastBitwiseOperations(v1, v2)); 649 return jsBoolean(v1 != v2); 650 } 651 652 static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 653 { 654 ASSERT(canDoFastBitwiseOperations(v1, v2)); 655 return JSImmediate::makeValue(JSImmediate::rawValue(v1) & JSImmediate::rawValue(v2)); 656 } 657 658 static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 659 { 660 ASSERT(canDoFastBitwiseOperations(v1, v2)); 661 return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeInteger); 662 } 663 664 static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 665 { 666 ASSERT(canDoFastBitwiseOperations(v1, v2)); 667 return JSImmediate::makeValue(JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2)); 668 } 669 670 static ALWAYS_INLINE bool canDoFastRshift(JSValuePtr v1, JSValuePtr v2) 671 { 672 return JSImmediate::areBothImmediateNumbers(v1, v2); 673 } 674 675 static ALWAYS_INLINE bool canDoFastUrshift(JSValuePtr v1, JSValuePtr v2) 676 { 677 return JSImmediate::areBothImmediateNumbers(v1, v2) && !JSImmediate::isNegative(v1); 678 } 679 680 static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift) 681 { 682 ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift)); 683 #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::TagTypeInteger); 685 #else 686 return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeInteger); 687 #endif 688 } 689 690 static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v) 691 { 692 // Number is non-negative and an operation involving two of these can't overflow. 693 // Checking for allowed negative numbers takes more time than it's worth on SunSpider. 694 return (JSImmediate::rawValue(v) & (JSImmediate::TagTypeInteger + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeInteger; 695 } 696 697 static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v1, JSValuePtr v2) 698 { 699 // Number is non-negative and an operation involving two of these can't overflow. 700 // Checking for allowed negative numbers takes more time than it's worth on SunSpider. 701 return ((JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2)) & (JSImmediate::TagTypeInteger + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeInteger; 702 } 703 704 static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 705 { 706 ASSERT(canDoFastAdditiveOperations(v1, v2)); 707 return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeInteger); 708 } 709 710 static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 711 { 712 ASSERT(canDoFastAdditiveOperations(v1, v2)); 713 return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeInteger); 714 } 715 716 static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v) 717 { 718 ASSERT(canDoFastAdditiveOperations(v)); 719 return JSImmediate::makeValue(JSImmediate::rawValue(v) + (1 << JSImmediate::IntegerPayloadShift)); 720 } 721 722 static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v) 723 { 724 ASSERT(canDoFastAdditiveOperations(v)); 725 return JSImmediate::makeValue(JSImmediate::rawValue(v) - (1 << JSImmediate::IntegerPayloadShift)); 726 } 727 }; 597 728 598 729 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSNumberCell.h
r39769 r39851 108 108 extern const double Inf; 109 109 110 JSNumberCell* asNumberCell(JSValuePtr);111 112 110 JSValuePtr jsNumberCell(JSGlobalData*, double); 113 111 JSValuePtr jsNaN(JSGlobalData*); … … 115 113 JSValuePtr jsNaN(ExecState*); 116 114 117 inline JSNumberCell* asNumberCell(JSValuePtr value)118 { 119 ASSERT( asCell(value)->isNumber());120 return static_cast<JSNumberCell*>(asCell( value));115 inline JSNumberCell* JSValuePtr::asNumberCell() const 116 { 117 ASSERT(isNumberCell()); 118 return static_cast<JSNumberCell*>(asCell()); 121 119 } 122 120 … … 127 125 } 128 126 129 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, short i) 130 { 131 JSValuePtr v = JSImmediate::from(i); 132 return v ? v : jsNumberCell(exec, i); 133 } 134 135 ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned short i) 136 { 137 JSValuePtr v = JSImmediate::from(i); 138 return v ? v : jsNumberCell(exec, i); 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); 139 149 } 140 150 … … 233 243 inline double JSValuePtr::uncheckedGetNumber() const 234 244 { 235 ASSERT( JSImmediate::isImmediate(asValue()) || asCell()->isNumber());236 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell( asValue())->value();245 ASSERT(isNumber()); 246 return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell()->value(); 237 247 } 238 248 … … 241 251 if (m_value >= -2147483648.0 && m_value < 2147483648.0) 242 252 return static_cast<int32_t>(m_value); 243 bool scratch;244 return JSC::toInt32SlowCase(m_value, scratch);253 bool ignored; 254 return toInt32SlowCase(m_value, ignored); 245 255 } 246 256 … … 249 259 if (m_value >= 0.0 && m_value < 4294967296.0) 250 260 return static_cast<uint32_t>(m_value); 251 bool scratch;252 return JSC::toUInt32SlowCase(m_value, scratch);261 bool ignored; 262 return toUInt32SlowCase(m_value, ignored); 253 263 } 254 264 255 265 ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const 256 266 { 257 return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec)); 267 return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec)); 268 } 269 270 inline bool JSValuePtr::getNumber(double &result) const 271 { 272 if (isInt32Fast()) 273 result = getInt32Fast(); 274 else if (LIKELY(isNumberCell())) 275 result = asNumberCell()->value(); 276 else { 277 ASSERT(!isNumber()); 278 return false; 279 } 280 return true; 281 } 282 283 inline bool JSValuePtr::numberToInt32(int32_t& arg) 284 { 285 if (isInt32Fast()) 286 arg = getInt32Fast(); 287 else if (LIKELY(isNumberCell())) 288 arg = asNumberCell()->toInt32(); 289 else { 290 ASSERT(!isNumber()); 291 return false; 292 } 293 return true; 294 } 295 296 inline bool JSValuePtr::numberToUInt32(uint32_t& arg) 297 { 298 if (isUInt32Fast()) 299 arg = getUInt32Fast(); 300 else if (LIKELY(isNumberCell())) 301 arg = asNumberCell()->toUInt32(); 302 else if (isInt32Fast()) { 303 // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase 304 // on a negative value is equivalent to simple static_casting. 305 bool ignored; 306 arg = toUInt32SlowCase(getInt32Fast(), ignored); 307 } else { 308 ASSERT(!isNumber()); 309 return false; 310 } 311 return true; 258 312 } 259 313 -
trunk/JavaScriptCore/runtime/JSObject.h
r39769 r39851 271 271 inline bool JSValuePtr::isObject(const ClassInfo* classInfo) const 272 272 { 273 return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(classInfo);273 return isCell() && asCell()->isObject(classInfo); 274 274 } 275 275 … … 474 474 inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const 475 475 { 476 if (UNLIKELY( JSImmediate::isImmediate(asValue()))) {476 if (UNLIKELY(!isCell())) { 477 477 JSObject* prototype = JSImmediate::prototype(asValue(), exec); 478 478 if (!prototype->getPropertySlot(exec, propertyName, slot)) … … 500 500 inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const 501 501 { 502 if (UNLIKELY( JSImmediate::isImmediate(asValue()))) {502 if (UNLIKELY(!isCell())) { 503 503 JSObject* prototype = JSImmediate::prototype(asValue(), exec); 504 504 if (!prototype->getPropertySlot(exec, propertyName, slot)) … … 520 520 inline void JSValuePtr::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot) 521 521 { 522 if (UNLIKELY( JSImmediate::isImmediate(asValue()))) {522 if (UNLIKELY(!isCell())) { 523 523 JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot); 524 524 return; … … 529 529 inline void JSValuePtr::put(ExecState* exec, unsigned propertyName, JSValuePtr value) 530 530 { 531 if (UNLIKELY( JSImmediate::isImmediate(asValue()))) {531 if (UNLIKELY(!isCell())) { 532 532 JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value); 533 533 return; -
trunk/JavaScriptCore/runtime/JSValue.cpp
r39769 r39851 34 34 double JSValuePtr::toInteger(ExecState* exec) const 35 35 { 36 int32_t i; 37 if (getTruncatedInt32(i)) 38 return i; 36 if (isInt32Fast()) 37 return getInt32Fast(); 39 38 double d = toNumber(exec); 40 39 return isnan(d) ? 0.0 : trunc(d); … … 43 42 double JSValuePtr::toIntegerPreserveNaN(ExecState* exec) const 44 43 { 45 int32_t i; 46 if (getTruncatedInt32(i)) 47 return i; 44 if (isInt32Fast()) 45 return getInt32Fast(); 48 46 return trunc(toNumber(exec)); 49 47 } … … 69 67 } 70 68 71 int32_t JSValuePtr::toInt32SlowCase(ExecState* exec, bool& ok) const72 {73 return JSC::toInt32SlowCase(toNumber(exec), ok);74 }75 76 69 uint32_t toUInt32SlowCase(double d, bool& ok) 77 70 { … … 92 85 } 93 86 94 uint32_t JSValuePtr::toUInt32SlowCase(ExecState* exec, bool& ok) const95 {96 return JSC::toUInt32SlowCase(toNumber(exec), ok);97 }98 99 87 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSValue.h
r39769 r39851 34 34 class Identifier; 35 35 class JSCell; 36 class JSNumberCell; 36 37 class JSObject; 37 38 class JSString; … … 121 122 bool getBoolean(bool&) const; 122 123 bool getBoolean() const; // false if not a boolean 123 double getNumber() const; // NaN if not a number124 bool getNumber(double&) const; 124 125 double uncheckedGetNumber() const; 125 126 bool getString(UString&) const; … … 149 150 150 151 // Integer conversions. 152 // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)' 151 153 double toInteger(ExecState*) const; 152 154 double toIntegerPreserveNaN(ExecState*) const; 153 155 int32_t toInt32(ExecState*) const; 154 156 int32_t toInt32(ExecState*, bool& ok) const; 157 bool numberToInt32(int32_t& arg); 155 158 uint32_t toUInt32(ExecState*) const; 156 159 uint32_t toUInt32(ExecState*, bool& ok) const; 157 158 // Floating point conversions. 160 bool numberToUInt32(uint32_t& arg); 161 162 // Fast integer operations; these values return results where the value is trivially available 163 // in a convenient form, for use in optimizations. No assumptions should be made based on the 164 // results of these operations, for example !isInt32Fast() does not necessarily indicate the 165 // result of getNumber will not be 0. 166 bool isInt32Fast() const; 167 int32_t getInt32Fast() const; 168 bool isUInt32Fast() const; 169 uint32_t getUInt32Fast() const; 170 static JSValuePtr makeInt32Fast(int32_t); 171 static bool areBothInt32Fast(JSValuePtr, JSValuePtr); 172 173 // Floating point conversions (this is a convenience method for webcore; 174 // signle precision float is not a representation used in JS or JSC). 159 175 float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); } 160 176 … … 176 192 JSString* toThisJSString(ExecState*); 177 193 178 JSValuePtr getJSNumber(); // 0 if this is not a JSNumber or number object 179 194 static bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2); 195 static bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2); 196 static bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2); 197 static bool strictEqual(JSValuePtr v1, JSValuePtr v2); 198 static bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2); 199 static bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2); 200 201 JSValuePtr getJSNumber(); // noValue() if this is not a JSNumber or number object 202 203 bool isCell() const; 180 204 JSCell* asCell() const; 181 205 … … 183 207 inline const JSValuePtr asValue() const { return *this; } 184 208 185 int32_t toInt32SlowCase(ExecState*, bool& ok) const;186 uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;209 bool isNumberCell() const; 210 JSNumberCell* asNumberCell() const; 187 211 188 212 JSCell* m_ptr; -
trunk/JavaScriptCore/runtime/Operations.cpp
r39670 r39851 36 36 namespace JSC { 37 37 38 // ECMA 11.9.3 39 bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 40 { 41 if (JSImmediate::areBothImmediateNumbers(v1, v2)) 42 return v1 == v2; 43 44 return equalSlowCaseInline(exec, v1, v2); 45 } 46 47 bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 38 bool JSValuePtr::equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 48 39 { 49 40 return equalSlowCaseInline(exec, v1, v2); 50 41 } 51 42 52 bool strictEqual(JSValuePtr v1, JSValuePtr v2) 53 { 54 if (JSImmediate::areBothImmediate(v1, v2)) 55 return v1 == v2; 56 57 if (JSImmediate::isEitherImmediate(v1, v2) & (v1 != JSImmediate::from(0)) & (v2 != JSImmediate::from(0))) 58 return false; 59 60 return strictEqualSlowCaseInline(v1, v2); 61 } 62 63 bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2) 43 bool JSValuePtr::strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2) 64 44 { 65 45 return strictEqualSlowCaseInline(v1, v2); -
trunk/JavaScriptCore/runtime/Operations.h
r39670 r39851 29 29 namespace JSC { 30 30 31 // ECMA 11.9.3 32 bool equal(ExecState*, JSValuePtr, JSValuePtr); 33 bool equalSlowCase(ExecState*, JSValuePtr, JSValuePtr); 31 // ECMA 11.9.3 32 inline bool JSValuePtr::equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 33 { 34 if (JSImmediate::areBothImmediateNumbers(v1, v2)) 35 return v1 == v2; 34 36 35 ALWAYS_INLINE bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 36 { 37 ASSERT(!JSImmediate::areBothImmediateNumbers(v1, v2)); 37 return equalSlowCase(exec, v1, v2); 38 } 38 39 39 do {40 if (v1->isNumber() && v2->isNumber())41 return v1->uncheckedGetNumber() == v2->uncheckedGetNumber();40 ALWAYS_INLINE bool JSValuePtr::equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2) 41 { 42 ASSERT(!JSImmediate::areBothImmediateNumbers(v1, v2)); 42 43 43 bool s1 = v1->isString(); 44 bool s2 = v2->isString(); 45 if (s1 && s2) 46 return asString(v1)->value() == asString(v2)->value(); 44 do { 45 if (v1->isNumber() && v2->isNumber()) 46 return v1->uncheckedGetNumber() == v2->uncheckedGetNumber(); 47 47 48 if (v1->isUndefinedOrNull()) { 49 if (v2->isUndefinedOrNull()) 50 return true; 51 if (JSImmediate::isImmediate(v2)) 52 return false; 53 return v2->asCell()->structure()->typeInfo().masqueradesAsUndefined(); 54 } 48 bool s1 = v1->isString(); 49 bool s2 = v2->isString(); 50 if (s1 && s2) 51 return asString(v1)->value() == asString(v2)->value(); 55 52 56 if (v2->isUndefinedOrNull()) { 57 if (JSImmediate::isImmediate(v1)) 58 return false; 59 return v1->asCell()->structure()->typeInfo().masqueradesAsUndefined(); 60 } 53 if (v1->isUndefinedOrNull()) { 54 if (v2->isUndefinedOrNull()) 55 return true; 56 if (JSImmediate::isImmediate(v2)) 57 return false; 58 return v2->asCell()->structure()->typeInfo().masqueradesAsUndefined(); 59 } 61 60 62 if (v1->isObject()) { 63 if (v2->isObject()) 64 return v1 == v2; 65 JSValuePtr p1 = v1->toPrimitive(exec); 66 if (exec->hadException()) 67 return false; 68 v1 = p1; 69 if (JSImmediate::areBothImmediateNumbers(v1, v2)) 70 return v1 == v2; 71 continue; 72 } 61 if (v2->isUndefinedOrNull()) { 62 if (JSImmediate::isImmediate(v1)) 63 return false; 64 return v1->asCell()->structure()->typeInfo().masqueradesAsUndefined(); 65 } 73 66 74 if (v2->isObject()) { 75 JSValuePtr p2 = v2->toPrimitive(exec); 76 if (exec->hadException()) 77 return false; 78 v2 = p2; 79 if (JSImmediate::areBothImmediateNumbers(v1, v2)) 80 return v1 == v2; 81 continue; 82 } 67 if (v1->isObject()) { 68 if (v2->isObject()) 69 return v1 == v2; 70 JSValuePtr p1 = v1->toPrimitive(exec); 71 if (exec->hadException()) 72 return false; 73 v1 = p1; 74 if (JSImmediate::areBothImmediateNumbers(v1, v2)) 75 return v1 == v2; 76 continue; 77 } 83 78 84 if (s1 || s2) { 85 double d1 = v1->toNumber(exec); 86 double d2 = v2->toNumber(exec); 87 return d1 == d2; 88 } 79 if (v2->isObject()) { 80 JSValuePtr p2 = v2->toPrimitive(exec); 81 if (exec->hadException()) 82 return false; 83 v2 = p2; 84 if (JSImmediate::areBothImmediateNumbers(v1, v2)) 85 return v1 == v2; 86 continue; 87 } 89 88 90 if (v1->isBoolean()) { 91 if (v2->isNumber()) 92 return static_cast<double>(v1->getBoolean()) == v2->uncheckedGetNumber(); 93 } else if (v2->isBoolean()) { 94 if (v1->isNumber()) 95 return v1->uncheckedGetNumber() == static_cast<double>(v2->getBoolean()); 96 } 89 if (s1 || s2) { 90 double d1 = v1->toNumber(exec); 91 double d2 = v2->toNumber(exec); 92 return d1 == d2; 93 } 97 94 98 return v1 == v2; 99 } while (true); 100 } 95 if (v1->isBoolean()) { 96 if (v2->isNumber()) 97 return static_cast<double>(v1->getBoolean()) == v2->uncheckedGetNumber(); 98 } else if (v2->isBoolean()) { 99 if (v1->isNumber()) 100 return v1->uncheckedGetNumber() == static_cast<double>(v2->getBoolean()); 101 } 101 102 103 return v1 == v2; 104 } while (true); 105 } 102 106 103 bool strictEqual(JSValuePtr, JSValuePtr); 104 bool strictEqualSlowCase(JSValuePtr, JSValuePtr); 107 // ECMA 11.9.3 108 inline bool JSValuePtr::strictEqual(JSValuePtr v1, JSValuePtr v2) 109 { 110 if (JSImmediate::areBothImmediate(v1, v2)) 111 return v1 == v2; 105 112 106 inline bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2) 107 { 108 ASSERT(!JSImmediate::areBothImmediate(v1, v2)); 109 110 if (JSImmediate::isEitherImmediate(v1, v2)) { 111 ASSERT(v1 == JSImmediate::zeroImmediate() || v2 == JSImmediate::zeroImmediate()); 112 ASSERT(v1 != v2); 113 if (JSImmediate::isEitherImmediate(v1, v2) & (v1 != js0()) & (v2 != js0())) 114 return false; 113 115 114 // The reason we can't just return false here is that 0 === -0, 115 // and while the former is an immediate number, the latter is not. 116 if (v1 == JSImmediate::zeroImmediate()) 117 return asCell(v2)->isNumber() && asNumberCell(v2)->value() == 0; 118 return asCell(v1)->isNumber() && asNumberCell(v1)->value() == 0; 119 } 120 121 if (asCell(v1)->isNumber()) { 122 return asCell(v2)->isNumber() 123 && asNumberCell(v1)->value() == asNumberCell(v2)->value(); 124 } 116 return strictEqualSlowCase(v1, v2); 117 } 125 118 126 if (asCell(v1)->isString()) { 127 return asCell(v2)->isString() 128 && asString(v1)->value() == asString(v2)->value(); 129 } 119 ALWAYS_INLINE bool JSValuePtr::strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2) 120 { 121 ASSERT(!JSImmediate::areBothImmediate(v1, v2)); 130 122 131 return v1 == v2; 132 } 123 if (JSImmediate::isEitherImmediate(v1, v2)) { 124 ASSERT(v1 == js0() || v2 == js0()); 125 ASSERT(v1 != v2); 133 126 134 JSValuePtr throwOutOfMemoryError(ExecState*); 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 } 143 144 return v1 == v2; 145 } 146 147 JSValuePtr throwOutOfMemoryError(ExecState*); 148 135 149 } 136 137 150 #endif -
trunk/JavaScriptCore/runtime/Protect.h
r39670 r39851 52 52 inline void gcProtect(JSValuePtr value) 53 53 { 54 if (!value || JSImmediate::isImmediate(value)) 55 return; 56 gcProtect(asCell(value)); 54 if (value && value->isCell()) 55 gcProtect(asCell(value)); 57 56 } 58 57 59 58 inline void gcUnprotect(JSValuePtr value) 60 59 { 61 if (!value || JSImmediate::isImmediate(value)) 62 return; 63 gcUnprotect(asCell(value)); 60 if (value && value->isCell()) 61 gcUnprotect(asCell(value)); 64 62 } 65 63 -
trunk/JavaScriptCore/runtime/StringPrototype.cpp
r39670 r39851 329 329 unsigned len = s.size(); 330 330 JSValuePtr a0 = args.at(exec, 0); 331 if ( JSImmediate::isNumber(a0)) {332 uint32_t i ;333 if ( JSImmediate::getUInt32(a0, i) &&i < len)331 if (a0->isUInt32Fast()) { 332 uint32_t i = a0->getUInt32Fast(); 333 if (i < len) 334 334 return jsSingleCharacterSubstring(exec, s, i); 335 335 return jsEmptyString(exec); … … 346 346 unsigned len = s.size(); 347 347 JSValuePtr a0 = args.at(exec, 0); 348 if ( JSImmediate::isNumber(a0)) {349 uint32_t i ;350 if ( JSImmediate::getUInt32(a0, i) &&i < len)348 if (a0->isUInt32Fast()) { 349 uint32_t i = a0->getUInt32Fast(); 350 if (i < len) 351 351 return jsNumber(exec, s.data()[i]); 352 352 return jsNaN(exec); -
trunk/JavaScriptCore/runtime/Structure.cpp
r39670 r39851 541 541 542 542 JSValuePtr prototype = storedPrototype(); 543 if ( JSImmediate::isImmediate(prototype))543 if (!prototype->isCell()) 544 544 return 0; 545 545
Note:
See TracChangeset
for help on using the changeset viewer.