Changeset 39670 in webkit for trunk/JavaScriptCore/runtime/JSImmediate.h
- Timestamp:
- Jan 6, 2009, 9:11:57 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/JSImmediate.h
r39554 r39670 26 26 #include <wtf/AlwaysInline.h> 27 27 #include <wtf/MathExtras.h> 28 #include "JSValue.h" 28 29 #include <limits> 29 30 #include <limits.h> … … 39 40 class JSValue; 40 41 class UString; 41 42 inline JSValue* noValue() { return 0; }43 inline void* asPointer(JSValue* value) { return value; }44 42 45 43 /* … … 114 112 115 113 public: 116 static ALWAYS_INLINE bool isImmediate(JSValue *v)114 static ALWAYS_INLINE bool isImmediate(JSValuePtr v) 117 115 { 118 116 return rawValue(v) & TagMask; 119 117 } 120 118 121 static ALWAYS_INLINE bool isNumber(JSValue *v)119 static ALWAYS_INLINE bool isNumber(JSValuePtr v) 122 120 { 123 121 return rawValue(v) & TagBitTypeInteger; 124 122 } 125 123 126 static ALWAYS_INLINE bool isPositiveNumber(JSValue *v)124 static ALWAYS_INLINE bool isPositiveNumber(JSValuePtr v) 127 125 { 128 126 // A single mask to check for the sign bit and the number tag all at once. … … 130 128 } 131 129 132 static ALWAYS_INLINE bool isBoolean(JSValue *v)130 static ALWAYS_INLINE bool isBoolean(JSValuePtr v) 133 131 { 134 132 return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool; 135 133 } 136 134 137 static ALWAYS_INLINE bool isUndefinedOrNull(JSValue *v)135 static ALWAYS_INLINE bool isUndefinedOrNull(JSValuePtr v) 138 136 { 139 137 // Undefined and null share the same value, bar the 'undefined' bit in the extended tag. … … 141 139 } 142 140 143 static bool isNegative(JSValue *v)141 static bool isNegative(JSValuePtr v) 144 142 { 145 143 ASSERT(isNumber(v)); … … 147 145 } 148 146 149 static JSValue *from(char);150 static JSValue *from(signed char);151 static JSValue *from(unsigned char);152 static JSValue *from(short);153 static JSValue *from(unsigned short);154 static JSValue *from(int);155 static JSValue *from(unsigned);156 static JSValue *from(long);157 static JSValue *from(unsigned long);158 static JSValue *from(long long);159 static JSValue *from(unsigned long long);160 static JSValue *from(double);161 162 static ALWAYS_INLINE bool isEitherImmediate(JSValue * v1, JSValue*v2)147 static JSValuePtr from(char); 148 static JSValuePtr from(signed char); 149 static JSValuePtr from(unsigned char); 150 static JSValuePtr from(short); 151 static JSValuePtr from(unsigned short); 152 static JSValuePtr from(int); 153 static JSValuePtr from(unsigned); 154 static JSValuePtr from(long); 155 static JSValuePtr from(unsigned long); 156 static JSValuePtr from(long long); 157 static JSValuePtr from(unsigned long long); 158 static JSValuePtr from(double); 159 160 static ALWAYS_INLINE bool isEitherImmediate(JSValuePtr v1, JSValuePtr v2) 163 161 { 164 162 return (rawValue(v1) | rawValue(v2)) & TagMask; 165 163 } 166 164 167 static ALWAYS_INLINE bool isAnyImmediate(JSValue * v1, JSValue* v2, JSValue*v3)165 static ALWAYS_INLINE bool isAnyImmediate(JSValuePtr v1, JSValuePtr v2, JSValuePtr v3) 168 166 { 169 167 return (rawValue(v1) | rawValue(v2) | rawValue(v3)) & TagMask; 170 168 } 171 169 172 static ALWAYS_INLINE bool areBothImmediate(JSValue * v1, JSValue*v2)170 static ALWAYS_INLINE bool areBothImmediate(JSValuePtr v1, JSValuePtr v2) 173 171 { 174 172 return isImmediate(v1) & isImmediate(v2); 175 173 } 176 174 177 static ALWAYS_INLINE bool areBothImmediateNumbers(JSValue * v1, JSValue*v2)175 static ALWAYS_INLINE bool areBothImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 178 176 { 179 177 return rawValue(v1) & rawValue(v2) & TagBitTypeInteger; 180 178 } 181 179 182 static ALWAYS_INLINE JSValue * andImmediateNumbers(JSValue* v1, JSValue*v2)180 static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 183 181 { 184 182 ASSERT(areBothImmediateNumbers(v1, v2)); … … 186 184 } 187 185 188 static ALWAYS_INLINE JSValue * xorImmediateNumbers(JSValue* v1, JSValue*v2)186 static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 189 187 { 190 188 ASSERT(areBothImmediateNumbers(v1, v2)); … … 192 190 } 193 191 194 static ALWAYS_INLINE JSValue * orImmediateNumbers(JSValue* v1, JSValue*v2)192 static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 195 193 { 196 194 ASSERT(areBothImmediateNumbers(v1, v2)); … … 198 196 } 199 197 200 static ALWAYS_INLINE JSValue * rightShiftImmediateNumbers(JSValue* val, JSValue*shift)198 static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift) 201 199 { 202 200 ASSERT(areBothImmediateNumbers(val, shift)); … … 204 202 } 205 203 206 static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue *v)204 static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v) 207 205 { 208 206 // Number is non-negative and an operation involving two of these can't overflow. … … 211 209 } 212 210 213 static ALWAYS_INLINE JSValue * addImmediateNumbers(JSValue* v1, JSValue*v2)211 static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 214 212 { 215 213 ASSERT(canDoFastAdditiveOperations(v1)); … … 218 216 } 219 217 220 static ALWAYS_INLINE JSValue * subImmediateNumbers(JSValue* v1, JSValue*v2)218 static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2) 221 219 { 222 220 ASSERT(canDoFastAdditiveOperations(v1)); … … 225 223 } 226 224 227 static ALWAYS_INLINE JSValue * incImmediateNumber(JSValue*v)225 static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v) 228 226 { 229 227 ASSERT(canDoFastAdditiveOperations(v)); … … 231 229 } 232 230 233 static ALWAYS_INLINE JSValue * decImmediateNumber(JSValue*v)231 static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v) 234 232 { 235 233 ASSERT(canDoFastAdditiveOperations(v)); … … 237 235 } 238 236 239 static double toDouble(JSValue *);240 static bool toBoolean(JSValue *);241 static JSObject* toObject(JSValue *, ExecState*);242 static JSObject* toThisObject(JSValue *, ExecState*);243 static UString toString(JSValue *);244 245 static bool getUInt32(JSValue *, uint32_t&);246 static bool getTruncatedInt32(JSValue *, int32_t&);247 static bool getTruncatedUInt32(JSValue *, uint32_t&);248 249 static int32_t getTruncatedInt32(JSValue *);250 static uint32_t getTruncatedUInt32(JSValue *);251 252 static JSValue *trueImmediate();253 static JSValue *falseImmediate();254 static JSValue *undefinedImmediate();255 static JSValue *nullImmediate();256 static JSValue *zeroImmediate();257 static JSValue *oneImmediate();258 259 static JSValue *impossibleValue();260 261 static JSObject* prototype(JSValue *, ExecState*);237 static double toDouble(JSValuePtr); 238 static bool toBoolean(JSValuePtr); 239 static JSObject* toObject(JSValuePtr, ExecState*); 240 static JSObject* toThisObject(JSValuePtr, ExecState*); 241 static UString toString(JSValuePtr); 242 243 static bool getUInt32(JSValuePtr, uint32_t&); 244 static bool getTruncatedInt32(JSValuePtr, int32_t&); 245 static bool getTruncatedUInt32(JSValuePtr, uint32_t&); 246 247 static int32_t getTruncatedInt32(JSValuePtr); 248 static uint32_t getTruncatedUInt32(JSValuePtr); 249 250 static JSValuePtr trueImmediate(); 251 static JSValuePtr falseImmediate(); 252 static JSValuePtr undefinedImmediate(); 253 static JSValuePtr nullImmediate(); 254 static JSValuePtr zeroImmediate(); 255 static JSValuePtr oneImmediate(); 256 257 static JSValuePtr impossibleValue(); 258 259 static JSObject* prototype(JSValuePtr, ExecState*); 262 260 263 261 private: … … 271 269 static const unsigned maxImmediateUInt = maxImmediateInt; 272 270 273 static ALWAYS_INLINE JSValue *makeValue(intptr_t integer)274 { 275 return reinterpret_cast<JSValue*>(integer);276 } 277 278 static ALWAYS_INLINE JSValue *makeInt(int32_t value)271 static ALWAYS_INLINE JSValuePtr makeValue(intptr_t integer) 272 { 273 return JSValuePtr::makeImmediate(integer); 274 } 275 276 static ALWAYS_INLINE JSValuePtr makeInt(int32_t value) 279 277 { 280 278 return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagBitTypeInteger); 281 279 } 282 280 283 static ALWAYS_INLINE JSValue *makeBool(bool b)281 static ALWAYS_INLINE JSValuePtr makeBool(bool b) 284 282 { 285 283 return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool); 286 284 } 287 285 288 static ALWAYS_INLINE JSValue *makeUndefined()286 static ALWAYS_INLINE JSValuePtr makeUndefined() 289 287 { 290 288 return makeValue(FullTagTypeUndefined); 291 289 } 292 290 293 static ALWAYS_INLINE JSValue *makeNull()291 static ALWAYS_INLINE JSValuePtr makeNull() 294 292 { 295 293 return makeValue(FullTagTypeNull); 296 294 } 297 295 298 static ALWAYS_INLINE int32_t intValue(JSValue *v)296 static ALWAYS_INLINE int32_t intValue(JSValuePtr v) 299 297 { 300 298 return static_cast<int32_t>(rawValue(v) >> IntegerPayloadShift); 301 299 } 302 300 303 static ALWAYS_INLINE uint32_t uintValue(JSValue *v)301 static ALWAYS_INLINE uint32_t uintValue(JSValuePtr v) 304 302 { 305 303 return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift); 306 304 } 307 305 308 static ALWAYS_INLINE bool boolValue(JSValue *v)306 static ALWAYS_INLINE bool boolValue(JSValuePtr v) 309 307 { 310 308 return rawValue(v) & ExtendedPayloadBitBoolValue; 311 309 } 312 310 313 static ALWAYS_INLINE intptr_t rawValue(JSValue *v)314 { 315 return reinterpret_cast<intptr_t>(v);311 static ALWAYS_INLINE intptr_t rawValue(JSValuePtr v) 312 { 313 return v.immediateValue(); 316 314 } 317 315 … … 319 317 }; 320 318 321 ALWAYS_INLINE JSValue *JSImmediate::trueImmediate() { return makeBool(true); }322 ALWAYS_INLINE JSValue *JSImmediate::falseImmediate() { return makeBool(false); }323 ALWAYS_INLINE JSValue *JSImmediate::undefinedImmediate() { return makeUndefined(); }324 ALWAYS_INLINE JSValue *JSImmediate::nullImmediate() { return makeNull(); }325 ALWAYS_INLINE JSValue *JSImmediate::zeroImmediate() { return makeInt(0); }326 ALWAYS_INLINE JSValue *JSImmediate::oneImmediate() { return makeInt(1); }319 ALWAYS_INLINE JSValuePtr JSImmediate::trueImmediate() { return makeBool(true); } 320 ALWAYS_INLINE JSValuePtr JSImmediate::falseImmediate() { return makeBool(false); } 321 ALWAYS_INLINE JSValuePtr JSImmediate::undefinedImmediate() { return makeUndefined(); } 322 ALWAYS_INLINE JSValuePtr JSImmediate::nullImmediate() { return makeNull(); } 323 ALWAYS_INLINE JSValuePtr JSImmediate::zeroImmediate() { return makeInt(0); } 324 ALWAYS_INLINE JSValuePtr JSImmediate::oneImmediate() { return makeInt(1); } 327 325 328 326 // This value is impossible because 0x4 is not a valid pointer but a tag of 0 would indicate non-immediate 329 ALWAYS_INLINE JSValue *JSImmediate::impossibleValue() { return makeValue(0x4); }330 331 ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue *v)327 ALWAYS_INLINE JSValuePtr JSImmediate::impossibleValue() { return makeValue(0x4); } 328 329 ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v) 332 330 { 333 331 ASSERT(isImmediate(v)); … … 338 336 } 339 337 340 ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue *v)338 ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValuePtr v) 341 339 { 342 340 ASSERT(isNumber(v)); … … 344 342 } 345 343 346 ALWAYS_INLINE JSValue *JSImmediate::from(char i)347 { 348 return makeInt(i); 349 } 350 351 ALWAYS_INLINE JSValue *JSImmediate::from(signed char i)352 { 353 return makeInt(i); 354 } 355 356 ALWAYS_INLINE JSValue *JSImmediate::from(unsigned char i)357 { 358 return makeInt(i); 359 } 360 361 ALWAYS_INLINE JSValue *JSImmediate::from(short i)362 { 363 return makeInt(i); 364 } 365 366 ALWAYS_INLINE JSValue *JSImmediate::from(unsigned short i)367 { 368 return makeInt(i); 369 } 370 371 ALWAYS_INLINE JSValue *JSImmediate::from(int i)344 ALWAYS_INLINE JSValuePtr JSImmediate::from(char i) 345 { 346 return makeInt(i); 347 } 348 349 ALWAYS_INLINE JSValuePtr JSImmediate::from(signed char i) 350 { 351 return makeInt(i); 352 } 353 354 ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned char i) 355 { 356 return makeInt(i); 357 } 358 359 ALWAYS_INLINE JSValuePtr JSImmediate::from(short i) 360 { 361 return makeInt(i); 362 } 363 364 ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned short i) 365 { 366 return makeInt(i); 367 } 368 369 ALWAYS_INLINE JSValuePtr JSImmediate::from(int i) 372 370 { 373 371 if ((i < minImmediateInt) | (i > maxImmediateInt)) … … 376 374 } 377 375 378 ALWAYS_INLINE JSValue *JSImmediate::from(unsigned i)376 ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned i) 379 377 { 380 378 if (i > maxImmediateUInt) … … 383 381 } 384 382 385 ALWAYS_INLINE JSValue *JSImmediate::from(long i)383 ALWAYS_INLINE JSValuePtr JSImmediate::from(long i) 386 384 { 387 385 if ((i < minImmediateInt) | (i > maxImmediateInt)) … … 390 388 } 391 389 392 ALWAYS_INLINE JSValue *JSImmediate::from(unsigned long i)390 ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long i) 393 391 { 394 392 if (i > maxImmediateUInt) … … 397 395 } 398 396 399 ALWAYS_INLINE JSValue *JSImmediate::from(long long i)397 ALWAYS_INLINE JSValuePtr JSImmediate::from(long long i) 400 398 { 401 399 if ((i < minImmediateInt) | (i > maxImmediateInt)) … … 404 402 } 405 403 406 ALWAYS_INLINE JSValue *JSImmediate::from(unsigned long long i)404 ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long long i) 407 405 { 408 406 if (i > maxImmediateUInt) … … 411 409 } 412 410 413 ALWAYS_INLINE JSValue *JSImmediate::from(double d)411 ALWAYS_INLINE JSValuePtr JSImmediate::from(double d) 414 412 { 415 413 const int intVal = static_cast<int>(d); … … 425 423 } 426 424 427 ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue *v)425 ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValuePtr v) 428 426 { 429 427 ASSERT(isNumber(v)); … … 431 429 } 432 430 433 ALWAYS_INLINE double JSImmediate::toDouble(JSValue *v)431 ALWAYS_INLINE double JSImmediate::toDouble(JSValuePtr v) 434 432 { 435 433 ASSERT(isImmediate(v)); … … 444 442 } 445 443 446 ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue *v, uint32_t& i)444 ALWAYS_INLINE bool JSImmediate::getUInt32(JSValuePtr v, uint32_t& i) 447 445 { 448 446 i = uintValue(v); … … 450 448 } 451 449 452 ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue *v, int32_t& i)450 ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValuePtr v, int32_t& i) 453 451 { 454 452 i = intValue(v); … … 456 454 } 457 455 458 ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue *v, uint32_t& i)456 ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValuePtr v, uint32_t& i) 459 457 { 460 458 return getUInt32(v, i); 461 459 } 462 460 463 ALWAYS_INLINE JSValue* jsUndefined() 461 inline JSValuePtr jsNull() 462 { 463 return JSImmediate::nullImmediate(); 464 } 465 466 inline JSValuePtr jsBoolean(bool b) 467 { 468 return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate(); 469 } 470 471 inline JSValuePtr jsUndefined() 464 472 { 465 473 return JSImmediate::undefinedImmediate(); 466 474 } 467 475 468 inline JSValue* jsNull() 469 { 470 return JSImmediate::nullImmediate(); 471 } 472 473 inline JSValue* jsBoolean(bool b) 474 { 475 return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate(); 476 // These are identical logic to the JSValue functions above, and faster than jsNumber(number)->toInt32(). 477 int32_t toInt32(double); 478 uint32_t toUInt32(double); 479 int32_t toInt32SlowCase(double, bool& ok); 480 uint32_t toUInt32SlowCase(double, bool& ok); 481 482 inline bool JSValue::isUndefined() const 483 { 484 return asValue() == jsUndefined(); 485 } 486 487 inline bool JSValue::isNull() const 488 { 489 return asValue() == jsNull(); 490 } 491 492 inline bool JSValue::isUndefinedOrNull() const 493 { 494 return JSImmediate::isUndefinedOrNull(asValue()); 495 } 496 497 inline bool JSValue::isBoolean() const 498 { 499 return JSImmediate::isBoolean(asValue()); 500 } 501 502 inline bool JSValue::getBoolean(bool& v) const 503 { 504 if (JSImmediate::isBoolean(asValue())) { 505 v = JSImmediate::toBoolean(asValue()); 506 return true; 507 } 508 509 return false; 510 } 511 512 inline bool JSValue::getBoolean() const 513 { 514 return asValue() == jsBoolean(true); 515 } 516 517 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const 518 { 519 int32_t i; 520 if (getTruncatedInt32(i)) 521 return i; 522 bool ok; 523 return toInt32SlowCase(exec, ok); 524 } 525 526 inline uint32_t JSValue::toUInt32(ExecState* exec) const 527 { 528 uint32_t i; 529 if (getTruncatedUInt32(i)) 530 return i; 531 bool ok; 532 return toUInt32SlowCase(exec, ok); 533 } 534 535 inline int32_t toInt32(double val) 536 { 537 if (!(val >= -2147483648.0 && val < 2147483648.0)) { 538 bool ignored; 539 return toInt32SlowCase(val, ignored); 540 } 541 return static_cast<int32_t>(val); 542 } 543 544 inline uint32_t toUInt32(double val) 545 { 546 if (!(val >= 0.0 && val < 4294967296.0)) { 547 bool ignored; 548 return toUInt32SlowCase(val, ignored); 549 } 550 return static_cast<uint32_t>(val); 551 } 552 553 inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const 554 { 555 int32_t i; 556 if (getTruncatedInt32(i)) { 557 ok = true; 558 return i; 559 } 560 return toInt32SlowCase(exec, ok); 561 } 562 563 inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const 564 { 565 uint32_t i; 566 if (getTruncatedUInt32(i)) { 567 ok = true; 568 return i; 569 } 570 return toUInt32SlowCase(exec, ok); 476 571 } 477 572
Note:
See TracChangeset
for help on using the changeset viewer.