Changeset 34921 in webkit for trunk/JavaScriptCore/kjs/JSNumberCell.h
- Timestamp:
- Jul 1, 2008, 10:32:44 AM (17 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/JSNumberCell.h
r34892 r34921 21 21 */ 22 22 23 #ifndef JS Value_h24 #define JS Value_h23 #ifndef JSNumberCell_h 24 #define JSNumberCell_h 25 25 26 26 #include "CallData.h" 27 27 #include "ConstructData.h" 28 28 #include "ExecState.h" 29 #include "JSCell.h" 29 30 #include "JSImmediate.h" 30 31 #include "collector.h" … … 43 44 struct ClassInfo; 44 45 struct Instruction; 45 46 /**47 * JSValue is the base type for all primitives (Undefined, Null, Boolean,48 * String, Number) and objects in ECMAScript.49 *50 * Note: you should never inherit from JSValue as it is for primitive types51 * only (all of which are provided internally by KJS). Instead, inherit from52 * JSObject.53 */54 class JSValue : Noncopyable {55 friend class JSCell; // so it can derive from this class56 friend class Heap; // so it can call asCell()57 private:58 JSValue();59 virtual ~JSValue();60 61 public:62 // Querying the type.63 JSType type() const;64 bool isUndefined() const;65 bool isNull() const;66 bool isUndefinedOrNull() const;67 bool isBoolean() const;68 bool isNumber() const;69 bool isString() const;70 bool isObject() const;71 bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.72 73 // Extracting the value.74 bool getBoolean(bool&) const;75 bool getBoolean() const; // false if not a boolean76 bool getNumber(double&) const;77 double getNumber() const; // NaN if not a number78 double uncheckedGetNumber() const;79 bool getString(UString&) const;80 UString getString() const; // null string if not a string81 JSObject* getObject(); // NULL if not an object82 const JSObject* getObject() const; // NULL if not an object83 84 CallType getCallData(CallData&);85 ConstructType getConstructData(ConstructData&);86 87 // Extracting integer values.88 bool getUInt32(uint32_t&) const;89 bool getTruncatedInt32(int32_t&) const;90 bool getTruncatedUInt32(uint32_t&) const;91 92 // Basic conversions.93 JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;94 bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);95 96 bool toBoolean(ExecState*) const;97 98 // toNumber conversion is expected to be side effect free if an exception has99 // been set in the ExecState already.100 double toNumber(ExecState*) const;101 JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.102 UString toString(ExecState*) const;103 JSObject* toObject(ExecState*) const;104 105 // Integer conversions.106 double toInteger(ExecState*) const;107 double toIntegerPreserveNaN(ExecState*) const;108 int32_t toInt32(ExecState*) const;109 int32_t toInt32(ExecState*, bool& ok) const;110 uint32_t toUInt32(ExecState*) const;111 uint32_t toUInt32(ExecState*, bool& ok) const;112 113 // These are identical logic to above, and faster than jsNumber(number)->toInt32(exec)114 static int32_t toInt32(double);115 static int32_t toUInt32(double);116 117 // Floating point conversions.118 float toFloat(ExecState*) const;119 120 // Garbage collection.121 void mark();122 bool marked() const;123 124 static int32_t toInt32SlowCase(double, bool& ok);125 static uint32_t toUInt32SlowCase(double, bool& ok);126 127 // Object operations, with the toObject operation included.128 JSValue* get(ExecState*, const Identifier& propertyName) const;129 JSValue* get(ExecState*, unsigned propertyName) const;130 void put(ExecState*, const Identifier& propertyName, JSValue*);131 void put(ExecState*, unsigned propertyName, JSValue*);132 bool deleteProperty(ExecState*, const Identifier& propertyName);133 bool deleteProperty(ExecState*, unsigned propertyName);134 135 JSObject* toThisObject(ExecState*) const;136 UString toThisString(ExecState*) const;137 JSString* toThisJSString(ExecState*);138 139 JSValue* getJSNumber(); // 0 if this is not a JSNumber or number object140 141 private:142 bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);143 bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);144 int32_t toInt32SlowCase(ExecState*, bool& ok) const;145 uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;146 147 // Implementation details.148 JSCell* asCell();149 const JSCell* asCell() const;150 };151 152 class JSCell : public JSValue {153 friend class Heap;154 friend class GetterSetter;155 friend class JSObject;156 friend class JSPropertyNameIterator;157 friend class JSValue;158 friend class JSNumberCell;159 friend class JSString;160 private:161 JSCell();162 virtual ~JSCell();163 164 public:165 // Querying the type.166 virtual JSType type() const = 0;167 bool isNumber() const;168 bool isString() const;169 bool isObject() const;170 bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.171 172 // Extracting the value.173 bool getNumber(double&) const;174 double getNumber() const; // NaN if not a number175 bool getString(UString&) const;176 UString getString() const; // null string if not a string177 JSObject* getObject(); // NULL if not an object178 const JSObject* getObject() const; // NULL if not an object179 180 virtual CallType getCallData(CallData&);181 virtual ConstructType getConstructData(ConstructData&);182 183 // Extracting integer values.184 virtual bool getUInt32(uint32_t&) const;185 virtual bool getTruncatedInt32(int32_t&) const;186 virtual bool getTruncatedUInt32(uint32_t&) const;187 188 // Basic conversions.189 virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const = 0;190 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0;191 virtual bool toBoolean(ExecState*) const = 0;192 virtual double toNumber(ExecState*) const = 0;193 virtual UString toString(ExecState*) const = 0;194 virtual JSObject* toObject(ExecState*) const = 0;195 196 // Garbage collection.197 void* operator new(size_t, ExecState*);198 virtual void mark();199 bool marked() const;200 201 // Object operations, with the toObject operation included.202 virtual const ClassInfo* classInfo() const;203 virtual void put(ExecState*, const Identifier& propertyName, JSValue*);204 virtual void put(ExecState*, unsigned propertyName, JSValue*);205 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);206 virtual bool deleteProperty(ExecState*, unsigned propertyName);207 208 virtual JSObject* toThisObject(ExecState*) const;209 virtual UString toThisString(ExecState*) const;210 virtual JSString* toThisJSString(ExecState*);211 virtual JSValue* getJSNumber();212 213 private:214 // Base implementation, but for non-object classes implements getPropertySlot.215 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);216 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);217 };218 46 219 47 class JSNumberCell : public JSCell { … … 256 84 double val; 257 85 }; 258 259 JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string260 JSString* jsString(ExecState*, const char* = ""); // returns empty string if passed 0261 262 // should be used for strings that are owned by an object that will263 // likely outlive the JSValue this makes, such as the parse tree or a264 // DOM object that contains a UString265 JSString* jsOwnedString(ExecState*, const UString&);266 86 267 87 extern const double NaN; … … 322 142 } 323 143 324 inline JSValue::JSValue() 325 { 326 } 327 328 inline JSValue::~JSValue() 329 { 330 } 331 332 inline JSCell::JSCell() 333 { 334 } 335 336 inline JSCell::~JSCell() 337 { 338 } 339 340 inline bool JSCell::isNumber() const 341 { 342 return type() == NumberType; 343 } 344 345 inline bool JSCell::isString() const 346 { 347 return type() == StringType; 348 } 349 350 inline bool JSCell::isObject() const 351 { 352 return type() == ObjectType; 353 } 354 355 inline bool JSCell::marked() const 356 { 357 return Heap::isCellMarked(this); 358 } 359 360 inline void JSCell::mark() 361 { 362 return Heap::markCell(this); 363 } 364 365 ALWAYS_INLINE JSCell* JSValue::asCell() 366 { 367 ASSERT(!JSImmediate::isImmediate(this)); 368 return static_cast<JSCell*>(this); 369 } 370 371 ALWAYS_INLINE const JSCell* JSValue::asCell() const 372 { 373 ASSERT(!JSImmediate::isImmediate(this)); 374 return static_cast<const JSCell*>(this); 375 } 376 377 inline bool JSValue::isUndefined() const 378 { 379 return this == jsUndefined(); 380 } 381 382 inline bool JSValue::isNull() const 383 { 384 return this == jsNull(); 385 } 386 387 inline bool JSValue::isUndefinedOrNull() const 388 { 389 return JSImmediate::isUndefinedOrNull(this); 390 } 391 392 inline bool JSValue::isBoolean() const 393 { 394 return JSImmediate::isBoolean(this); 395 } 396 397 inline bool JSValue::isNumber() const 398 { 399 return JSImmediate::isNumber(this) || (!JSImmediate::isImmediate(this) && asCell()->isNumber()); 400 } 401 402 inline bool JSValue::isString() const 403 { 404 return !JSImmediate::isImmediate(this) && asCell()->isString(); 405 } 406 407 inline bool JSValue::isObject() const 408 { 409 return !JSImmediate::isImmediate(this) && asCell()->isObject(); 410 } 411 412 inline bool JSValue::getBoolean(bool& v) const 413 { 414 if (JSImmediate::isBoolean(this)) { 415 v = JSImmediate::toBoolean(this); 416 return true; 417 } 418 419 return false; 420 } 421 422 inline bool JSValue::getBoolean() const 423 { 424 return JSImmediate::isBoolean(this) ? JSImmediate::toBoolean(this) : false; 425 } 426 427 inline bool JSValue::getNumber(double& v) const 428 { 429 if (JSImmediate::isImmediate(this)) { 430 v = JSImmediate::toDouble(this); 431 return true; 432 } 433 return asCell()->getNumber(v); 434 } 435 436 inline double JSValue::getNumber() const 437 { 438 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber(); 439 } 144 // --- JSValue inlines ---------------------------- 440 145 441 146 inline double JSValue::uncheckedGetNumber() const … … 445 150 } 446 151 447 inline bool JSValue::getString(UString& s) const448 {449 return !JSImmediate::isImmediate(this) && asCell()->getString(s);450 }451 452 inline UString JSValue::getString() const453 {454 return JSImmediate::isImmediate(this) ? UString() : asCell()->getString();455 }456 457 inline JSObject *JSValue::getObject()458 {459 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();460 }461 462 inline const JSObject *JSValue::getObject() const463 {464 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();465 }466 467 inline CallType JSValue::getCallData(CallData& callData)468 {469 return JSImmediate::isImmediate(this) ? CallTypeNone : asCell()->getCallData(callData);470 }471 472 inline ConstructType JSValue::getConstructData(ConstructData& constructData)473 {474 return JSImmediate::isImmediate(this) ? ConstructTypeNone : asCell()->getConstructData(constructData);475 }476 477 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const478 {479 return JSImmediate::isImmediate(this) ? JSImmediate::getUInt32(this, v) : asCell()->getUInt32(v);480 }481 482 ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const483 {484 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedInt32(this, v) : asCell()->getTruncatedInt32(v);485 }486 487 inline bool JSValue::getTruncatedUInt32(uint32_t& v) const488 {489 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedUInt32(this, v) : asCell()->getTruncatedUInt32(v);490 }491 492 inline void JSValue::mark()493 {494 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark()495 asCell()->mark();496 }497 498 inline bool JSValue::marked() const499 {500 return JSImmediate::isImmediate(this) || asCell()->marked();501 }502 503 inline JSType JSValue::type() const504 {505 return JSImmediate::isImmediate(this) ? JSImmediate::type(this) : asCell()->type();506 }507 508 inline JSValue* JSValue::toPrimitive(ExecState* exec, JSType preferredType) const509 {510 return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);511 }512 513 inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)514 {515 if (JSImmediate::isImmediate(this)) {516 number = JSImmediate::toDouble(this);517 value = this;518 return true;519 }520 return asCell()->getPrimitiveNumber(exec, number, value);521 }522 523 inline bool JSValue::toBoolean(ExecState *exec) const524 {525 return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean(exec);526 }527 528 ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const529 {530 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->toNumber(exec);531 }532 533 152 ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const 534 153 { … … 536 155 } 537 156 538 inline UString JSValue::toString(ExecState *exec) const 539 { 540 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toString(exec); 541 } 542 543 inline JSObject* JSValue::toObject(ExecState* exec) const 544 { 545 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : asCell()->toObject(exec); 546 } 547 548 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const 549 { 550 int32_t i; 551 if (getTruncatedInt32(i)) 552 return i; 553 bool ok; 554 return toInt32SlowCase(exec, ok); 555 } 556 557 inline uint32_t JSValue::toUInt32(ExecState* exec) const 558 { 559 uint32_t i; 560 if (getTruncatedUInt32(i)) 561 return i; 562 bool ok; 563 return toUInt32SlowCase(exec, ok); 564 } 565 566 inline int32_t JSValue::toInt32(double val) 567 { 568 if (!(val >= -2147483648.0 && val < 2147483648.0)) { 569 bool ignored; 570 return toInt32SlowCase(val, ignored); 571 } 572 return static_cast<int32_t>(val); 573 } 574 575 inline int32_t JSValue::toUInt32(double val) 576 { 577 if (!(val >= 0.0 && val < 4294967296.0)) { 578 bool ignored; 579 return toUInt32SlowCase(val, ignored); 580 } 581 return static_cast<uint32_t>(val); 582 } 583 584 inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const 585 { 586 int32_t i; 587 if (getTruncatedInt32(i)) { 588 ok = true; 589 return i; 590 } 591 return toInt32SlowCase(exec, ok); 592 } 593 594 inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const 595 { 596 uint32_t i; 597 if (getTruncatedUInt32(i)) { 598 ok = true; 599 return i; 600 } 601 return toUInt32SlowCase(exec, ok); 602 } 603 604 inline JSObject* JSValue::toThisObject(ExecState* exec) const 605 { 606 if (UNLIKELY(JSImmediate::isImmediate(this))) 607 return JSImmediate::toObject(this, exec); 608 return asCell()->toThisObject(exec); 609 } 610 611 inline UString JSValue::toThisString(ExecState* exec) const 612 { 613 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toThisString(exec); 614 } 615 616 inline JSString* JSValue::toThisJSString(ExecState* exec) 617 { 618 return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec); 619 } 620 621 inline JSValue* JSValue::getJSNumber() 622 { 623 return JSImmediate::isNumber(this) ? this : (JSImmediate::isImmediate(this) ? 0 : asCell()->getJSNumber()); 624 } 157 // ------- 625 158 626 159 } // namespace KJS 627 160 628 #endif // JS Value_h161 #endif // JSNumberCell_h
Note:
See TracChangeset
for help on using the changeset viewer.