File indexing completed on 2024-05-12 15:43:37
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 0004 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 0005 * Copyright (C) 2003, 2004, 2005, 2007 Apple Inc. All rights reserved. 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Library General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Library General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Library General Public License 0018 * along with this library; see the file COPYING.LIB. If not, write to 0019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 * 0022 */ 0023 0024 #ifndef KJS_VALUE_H 0025 #define KJS_VALUE_H 0026 0027 #include "JSImmediate.h" 0028 #include "ustring.h" 0029 #include "collector.h" 0030 #include <wtf/Noncopyable.h> 0031 #include <stddef.h> // for size_t 0032 0033 #ifndef NDEBUG // protection against problems if committing with KJS_VERBOSE on 0034 0035 // Uncomment this to enable very verbose output from KJS 0036 //#define KJS_VERBOSE 0037 // Uncomment this to debug memory allocation and garbage collection 0038 //#define KJS_DEBUG_MEM 0039 0040 #endif 0041 0042 namespace KJS 0043 { 0044 0045 struct ClassInfo; 0046 class ExecState; 0047 class JSObject; 0048 class JSCell; 0049 0050 /** 0051 * JSValue is the base type for all primitives (Undefined, Null, Boolean, 0052 * String, Number) and objects in ECMAScript. 0053 * 0054 * Note: you should never inherit from JSValue as it is for primitive types 0055 * only (all of which are provided internally by KJS). Instead, inherit from 0056 * JSObject. 0057 */ 0058 class KJS_EXPORT JSValue : Noncopyable 0059 { 0060 friend class JSCell; // so it can derive from this class 0061 friend class Collector; // so it can call asCell() 0062 0063 private: 0064 JSValue(); 0065 virtual ~JSValue(); 0066 0067 public: 0068 // Querying the type. 0069 [[deprecated]] JSType type() const; 0070 static JSType type(const JSValue *value); 0071 [[deprecated]] bool isUndefined() const; 0072 static bool isUndefined(const JSValue *value); 0073 [[deprecated]] bool isNull() const; 0074 static bool isNull(const JSValue *value); 0075 [[deprecated]] bool isUndefinedOrNull() const; 0076 static bool isUndefinedOrNull(const JSValue *value); 0077 [[deprecated]] bool isBoolean() const; 0078 static bool isBoolean(const JSValue *value); 0079 [[deprecated]] bool isNumber() const; 0080 static bool isNumber(const JSValue *value); 0081 [[deprecated]] bool isString() const; 0082 static bool isString(const JSValue *value); 0083 [[deprecated]] bool isObject() const; 0084 static bool isObject(const JSValue *value); 0085 [[deprecated]] bool isObject(const ClassInfo *) const; 0086 static bool isObject(const JSValue *value, const ClassInfo *); 0087 0088 // Extracting the value. 0089 [[deprecated]] bool getBoolean(bool &) const; 0090 static bool getBoolean(const JSValue *value, bool &); 0091 [[deprecated]] bool getBoolean() const; // false if not a boolean 0092 static bool getBoolean(const JSValue *value); 0093 [[deprecated]] bool getNumber(double &) const; 0094 static bool getNumber(const JSValue *value, double &); 0095 [[deprecated]] double getNumber() const; // NaN if not a number 0096 static double getNumber(const JSValue *value); 0097 [[deprecated]] bool getString(UString &) const; 0098 static bool getString(const JSValue *value, UString &); 0099 [[deprecated]] UString getString() const; // null string if not a string 0100 static UString getString(const JSValue *value); // null string if not a string 0101 [[deprecated]] JSObject *getObject(); // NULL if not an object 0102 static JSObject *getObject(JSValue *value); 0103 [[deprecated]] const JSObject *getObject() const; // NULL if not an object 0104 static const JSObject *getObject(const JSValue *value); 0105 0106 // Extracting integer values. 0107 [[deprecated]] bool getUInt32(uint32_t &) const; 0108 static bool getUInt32(const JSValue *value, uint32_t &); 0109 [[deprecated]] bool getTruncatedInt32(int32_t &) const; 0110 static bool getTruncatedInt32(const JSValue *value, int32_t &v); 0111 [[deprecated]] bool getTruncatedUInt32(uint32_t &) const; 0112 static bool getTruncatedUInt32(const JSValue *value, uint32_t &v); 0113 0114 [[deprecated]] JSValue *getByIndex(ExecState *exec, unsigned propertyName) const; 0115 static JSValue *getByIndex(const JSValue *value, ExecState *exec, unsigned propertyName); 0116 0117 // Basic conversions. 0118 [[deprecated]] JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const; 0119 static JSValue *toPrimitive(const JSValue *value, ExecState *exec, JSType preferredType = UnspecifiedType); 0120 [[deprecated]] bool getPrimitiveNumber(ExecState *exec, double &number, JSValue *&value); 0121 static bool getPrimitiveNumber(JSValue *that, ExecState *exec, double &number, JSValue *&value); 0122 0123 [[deprecated]] bool toBoolean(ExecState *exec) const; 0124 static bool toBoolean(const JSValue *value, ExecState *exec); 0125 [[deprecated]] double toNumber(ExecState *exec) const; 0126 static double toNumber(const JSValue *value, ExecState *exec); 0127 JSValue *toJSNumber(ExecState *) const; // Fast path for when you expect that the value is an immediate number. 0128 [[deprecated]] UString toString(ExecState *exec) const; 0129 static UString toString(const JSValue *value, ExecState *exec); 0130 [[deprecated]] JSObject *toObject(ExecState *exec) const; 0131 static JSObject *toObject(const JSValue *value, ExecState *exec); 0132 0133 // Integer conversions. 0134 [[deprecated]] double toInteger(ExecState *) const; 0135 static double toInteger(const JSValue *value, ExecState *); 0136 [[deprecated]] double toIntegerPreserveNaN(ExecState *) const; 0137 static double toIntegerPreserveNaN(const JSValue *value, ExecState *); 0138 [[deprecated]] int32_t toInt32(ExecState *) const; 0139 static int32_t toInt32(const JSValue *value, ExecState *exec); 0140 [[deprecated]] int32_t toInt32(ExecState *, bool &ok) const; 0141 static int32_t toInt32(const JSValue *value, ExecState *, bool &ok); 0142 [[deprecated]] uint32_t toUInt32(ExecState *) const; 0143 static uint32_t toUInt32(const JSValue *value, ExecState *); 0144 [[deprecated]] uint32_t toUInt32(ExecState *, bool &ok) const; 0145 static uint32_t toUInt32(const JSValue *value, ExecState *, bool &ok); 0146 [[deprecated]] uint16_t toUInt16(ExecState *exec) const; 0147 static uint16_t toUInt16(const JSValue *value, ExecState *exec); 0148 0149 // These are identical logic to above, and faster than jsNumber(number)->toInt32(exec) 0150 static int32_t toInt32(double); 0151 static int32_t toUInt32(double); 0152 0153 // Floating point conversions. 0154 [[deprecated]] float toFloat(ExecState *) const; 0155 static float toFloat(const JSValue *value, ExecState *); 0156 0157 // Object-level properties... 0158 0159 /** 0160 * Whether or not the value implements the call() method. If it does, this also 0161 * implies this is an object, and hence it can be cast to a JSObject 0162 * and the call method can be invoked 0163 * 0164 * @return true if this is an object implementing the call() method, otherwise 0165 * false 0166 */ 0167 [[deprecated]] bool implementsCall() const; 0168 static bool implementsCall(const JSValue *value); 0169 0170 // Garbage collection. 0171 [[deprecated]] void mark(); 0172 static void mark(JSValue *value); 0173 [[deprecated]] bool marked() const; 0174 static bool marked(const JSValue *value); 0175 0176 static int32_t toInt32SlowCase(double, bool &ok); 0177 static uint32_t toUInt32SlowCase(double, bool &ok); 0178 0179 private: 0180 static int32_t toInt32SlowCase(const JSValue *value, ExecState *, bool &ok); 0181 static uint32_t toUInt32SlowCase(const JSValue *value, ExecState *, bool &ok); 0182 0183 // Implementation details. 0184 JSCell *asCell(); 0185 const JSCell *asCell() const; 0186 0187 // emulate Q_DISABLE_COPY to avoid msvc linker errors 0188 #if !defined(_MSC_VER) || !defined(MAKE_KJS_LIB) 0189 // Give a compile time error if we try to copy one of these. 0190 JSValue(const JSValue &); 0191 JSValue &operator=(const JSValue &); 0192 #endif 0193 }; 0194 0195 class KJS_EXPORT JSCell : public JSValue 0196 { 0197 friend class Collector; 0198 friend class NumberImp; 0199 friend class StringImp; 0200 friend class JSObject; 0201 friend class GetterSetterImp; 0202 private: 0203 explicit JSCell(); 0204 ~JSCell() override; 0205 public: 0206 // Querying the type. 0207 virtual JSType type() const = 0; 0208 bool isNumber() const; 0209 bool isString() const; 0210 bool isObject() const; 0211 bool isObject(const ClassInfo *) const; 0212 0213 // Extracting the value. 0214 bool getNumber(double &) const; 0215 double getNumber() const; // NaN if not a number 0216 bool getString(UString &) const; 0217 UString getString() const; // null string if not a string 0218 JSObject *getObject(); // NULL if not an object 0219 const JSObject *getObject() const; // NULL if not an object 0220 0221 // Extracting integer values. 0222 virtual bool getUInt32(uint32_t &) const; 0223 virtual bool getTruncatedInt32(int32_t &) const; 0224 virtual bool getTruncatedUInt32(uint32_t &) const; 0225 0226 // Basic conversions. 0227 virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const = 0; 0228 virtual bool getPrimitiveNumber(ExecState *exec, double &number, JSValue *&value) = 0; 0229 virtual bool toBoolean(ExecState *exec) const = 0; 0230 virtual double toNumber(ExecState *exec) const = 0; 0231 virtual UString toString(ExecState *exec) const = 0; 0232 virtual JSObject *toObject(ExecState *exec) const = 0; 0233 0234 // Higher-level (object-like) properties: 0235 virtual bool implementsCall() const; 0236 0237 // Garbage collection. 0238 void *operator new(size_t); 0239 virtual void mark(); 0240 bool marked() const; 0241 }; 0242 0243 KJS_EXPORT JSValue *jsNumberCell(double); 0244 0245 KJS_EXPORT JSCell *jsString(); // returns empty string 0246 KJS_EXPORT JSCell *jsString(const UString &); // returns empty string if passed null string 0247 KJS_EXPORT JSCell *jsString(const char * = ""); // returns empty string if passed 0 0248 KJS_EXPORT JSCell *jsString(const char *s, int len); 0249 0250 // should be used for strings that are owned by an object that will 0251 // likely outlive the JSValue this makes, such as the parse tree or a 0252 // DOM object that contains a UString 0253 JSCell *jsOwnedString(const UString &); 0254 0255 inline JSValue *jsUndefined() 0256 { 0257 return JSImmediate::undefinedImmediate(); 0258 } 0259 0260 inline JSValue *jsNull() 0261 { 0262 return JSImmediate::nullImmediate(); 0263 } 0264 0265 inline JSValue *jsNaN() 0266 { 0267 static const union { 0268 uint64_t bits; 0269 double d; 0270 } nan = { 0x7ff80000ULL << 32 }; 0271 return jsNumberCell(nan.d); 0272 } 0273 0274 inline JSValue *jsBoolean(bool b) 0275 { 0276 return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate(); 0277 } 0278 0279 ALWAYS_INLINE JSValue *jsNumber(double d) 0280 { 0281 JSValue *v = JSImmediate::from(d); 0282 return v ? v : jsNumberCell(d); 0283 } 0284 0285 ALWAYS_INLINE JSValue *jsNumber(int i) 0286 { 0287 JSValue *v = JSImmediate::from(i); 0288 return v ? v : jsNumberCell(i); 0289 } 0290 0291 ALWAYS_INLINE JSValue *jsNumber(unsigned i) 0292 { 0293 JSValue *v = JSImmediate::from(i); 0294 return v ? v : jsNumberCell(i); 0295 } 0296 0297 ALWAYS_INLINE JSValue *jsNumber(long i) 0298 { 0299 JSValue *v = JSImmediate::from(i); 0300 return v ? v : jsNumberCell(i); 0301 } 0302 0303 ALWAYS_INLINE JSValue *jsNumber(unsigned long i) 0304 { 0305 JSValue *v = JSImmediate::from(i); 0306 return v ? v : jsNumberCell(i); 0307 } 0308 0309 ALWAYS_INLINE JSValue *jsNumber(long long i) 0310 { 0311 JSValue *v = JSImmediate::from(i); 0312 return v ? v : jsNumberCell(static_cast<double>(i)); 0313 } 0314 0315 ALWAYS_INLINE JSValue *jsNumber(unsigned long long i) 0316 { 0317 JSValue *v = JSImmediate::from(i); 0318 return v ? v : jsNumberCell(static_cast<double>(i)); 0319 } 0320 0321 ALWAYS_INLINE JSValue *jsNumberFromAnd(ExecState *exec, JSValue *v1, JSValue *v2) 0322 { 0323 if (JSImmediate::areBothImmediateNumbers(v1, v2)) { 0324 return JSImmediate::andImmediateNumbers(v1, v2); 0325 } 0326 return jsNumber(JSValue::toInt32(v1, exec) & JSValue::toInt32(v2, exec)); 0327 } 0328 0329 inline JSValue::JSValue() 0330 { 0331 } 0332 0333 inline JSValue::~JSValue() 0334 { 0335 } 0336 0337 inline JSCell::JSCell() 0338 { 0339 } 0340 0341 inline JSCell::~JSCell() 0342 { 0343 } 0344 0345 inline bool JSCell::isNumber() const 0346 { 0347 return type() == NumberType; 0348 } 0349 0350 inline bool JSCell::isString() const 0351 { 0352 return type() == StringType; 0353 } 0354 0355 inline bool JSCell::isObject() const 0356 { 0357 return type() == ObjectType; 0358 } 0359 0360 inline bool JSCell::marked() const 0361 { 0362 return Collector::isCellMarked(this); 0363 } 0364 0365 inline void JSCell::mark() 0366 { 0367 return Collector::markCell(this); 0368 } 0369 0370 ALWAYS_INLINE JSCell *JSValue::asCell() 0371 { 0372 ASSERT(!JSImmediate::isImmediate(this)); 0373 return static_cast<JSCell *>(this); 0374 } 0375 0376 ALWAYS_INLINE const JSCell *JSValue::asCell() const 0377 { 0378 ASSERT(!JSImmediate::isImmediate(this)); 0379 return static_cast<const JSCell *>(this); 0380 } 0381 0382 inline bool JSValue::isUndefined() const 0383 { 0384 return isUndefined(this); 0385 } 0386 0387 inline bool JSValue::isUndefined(const JSValue *value) 0388 { 0389 return value == jsUndefined(); 0390 } 0391 0392 inline bool JSValue::isNull() const 0393 { 0394 return isNull(this); 0395 } 0396 0397 inline bool JSValue::isNull(const JSValue *value) 0398 { 0399 return value == jsNull(); 0400 } 0401 0402 inline bool JSValue::isUndefinedOrNull() const 0403 { 0404 return isUndefinedOrNull(this); 0405 } 0406 0407 inline bool JSValue::isUndefinedOrNull(const JSValue *value) 0408 { 0409 return JSImmediate::isUndefinedOrNull(value); 0410 } 0411 0412 inline bool JSValue::isBoolean() const 0413 { 0414 return isBoolean(this); 0415 } 0416 0417 inline bool JSValue::isBoolean(const JSValue *value) 0418 { 0419 return JSImmediate::isBoolean(value); 0420 } 0421 0422 inline bool JSValue::isNumber() const 0423 { 0424 return isNumber(this); 0425 } 0426 0427 inline bool JSValue::isNumber(const JSValue *value) 0428 { 0429 return JSImmediate::isNumber(value) || 0430 (!JSImmediate::isImmediate(value) && value->asCell()->isNumber()); 0431 } 0432 0433 inline bool JSValue::isString() const 0434 { 0435 return isString(this); 0436 } 0437 0438 inline bool JSValue::isString(const JSValue *value) 0439 { 0440 return !JSImmediate::isImmediate(value) && value->asCell()->isString(); 0441 } 0442 0443 inline bool JSValue::isObject() const 0444 { 0445 return isObject(this); 0446 } 0447 0448 inline bool JSValue::isObject(const JSValue *value) 0449 { 0450 return !JSImmediate::isImmediate(value) && value->asCell()->isObject(); 0451 } 0452 0453 inline bool JSValue::getBoolean(bool &v) const 0454 { 0455 return getBoolean(this, v); 0456 } 0457 0458 0459 inline bool JSValue::getBoolean(const JSValue *value, bool &v) 0460 { 0461 if (JSImmediate::isBoolean(value)) { 0462 v = JSImmediate::toBoolean(value); 0463 return true; 0464 } 0465 0466 return false; 0467 } 0468 0469 inline bool JSValue::getBoolean() const 0470 { 0471 return getBoolean(this); 0472 } 0473 0474 inline bool JSValue::getBoolean(const JSValue *value) 0475 { 0476 return JSImmediate::isBoolean(value) ? JSImmediate::toBoolean(value) : false; 0477 } 0478 0479 inline bool JSValue::getNumber(double &v) const 0480 { 0481 return getNumber(this, v); 0482 } 0483 0484 inline bool JSValue::getNumber(const JSValue *value, double &v) 0485 { 0486 if (JSImmediate::isImmediate(value)) { 0487 return JSImmediate::getNumber(value, v); 0488 } 0489 return value->asCell()->getNumber(v); 0490 } 0491 0492 inline double JSValue::getNumber() const 0493 { 0494 return getNumber(this); 0495 } 0496 0497 inline double JSValue::getNumber(const JSValue *value) 0498 { 0499 return JSImmediate::isImmediate(value) ? JSImmediate::getNumber(value) : value->asCell()->getNumber(); 0500 } 0501 0502 inline bool JSValue::getString(UString &s) const 0503 { 0504 return getString(this, s); 0505 } 0506 0507 inline bool JSValue::getString(const JSValue *value, UString &s) 0508 { 0509 return !JSImmediate::isImmediate(value) && value->asCell()->getString(s); 0510 } 0511 0512 inline UString JSValue::getString() const 0513 { 0514 return getString(this); 0515 } 0516 0517 inline UString JSValue::getString(const JSValue *value) 0518 { 0519 return JSImmediate::isImmediate(value) ? UString() : value->asCell()->getString(); 0520 } 0521 0522 inline JSObject *JSValue::getObject() 0523 { 0524 return getObject(this); 0525 } 0526 0527 inline const JSObject *JSValue::getObject() const 0528 { 0529 return getObject(this); 0530 } 0531 0532 inline JSObject *JSValue::getObject(JSValue *value) 0533 { 0534 return JSImmediate::isImmediate(value) ? nullptr : value->asCell()->getObject(); 0535 } 0536 0537 inline const JSObject *JSValue::getObject(const JSValue *value) 0538 { 0539 return JSImmediate::isImmediate(value) ? nullptr : value->asCell()->getObject(); 0540 } 0541 0542 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t &v) const 0543 { 0544 return getUInt32(this, v); 0545 } 0546 0547 ALWAYS_INLINE bool JSValue::getUInt32(const JSValue *value, uint32_t &v) 0548 { 0549 return JSImmediate::isImmediate(value) ? JSImmediate::getUInt32(value, v) : value->asCell()->getUInt32(v); 0550 } 0551 0552 ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t &v) const 0553 { 0554 return getTruncatedInt32(this, v); 0555 } 0556 0557 ALWAYS_INLINE bool JSValue::getTruncatedInt32(const JSValue *value, int32_t &v) 0558 { 0559 return JSImmediate::isImmediate(value) ? JSImmediate::getTruncatedInt32(value, v) : value->asCell()->getTruncatedInt32(v); 0560 } 0561 0562 inline bool JSValue::getTruncatedUInt32(uint32_t &v) const 0563 { 0564 return getTruncatedUInt32(this, v); 0565 } 0566 0567 inline bool JSValue::getTruncatedUInt32(const JSValue *value, uint32_t &v) 0568 { 0569 return JSImmediate::isImmediate(value) ? JSImmediate::getTruncatedUInt32(value, v) : value->asCell()->getTruncatedUInt32(v); 0570 } 0571 0572 inline void JSValue::mark() 0573 { 0574 mark(this); 0575 } 0576 0577 inline void JSValue::mark(JSValue *value) 0578 { 0579 ASSERT(!JSImmediate::isImmediate(value)); // callers should check !marked() before calling mark() 0580 value->asCell()->mark(); 0581 } 0582 0583 inline bool JSValue::marked() const 0584 { 0585 return marked(this); 0586 } 0587 0588 inline bool JSValue::marked(const JSValue *value) 0589 { 0590 return JSImmediate::isImmediate(value) || value->asCell()->marked(); 0591 } 0592 0593 inline JSType JSValue::type() const 0594 { 0595 return type(this); 0596 } 0597 0598 inline JSType JSValue::type(const JSValue *value) 0599 { 0600 return JSImmediate::isImmediate(value) ? JSImmediate::type(value) : value->asCell()->type(); 0601 } 0602 0603 inline JSValue *JSValue::toPrimitive(ExecState *exec, JSType preferredType) const 0604 { 0605 return toPrimitive(this, exec, preferredType); 0606 } 0607 0608 inline JSValue *JSValue::toPrimitive(const JSValue *value, ExecState *exec, JSType preferredType) 0609 { 0610 return JSImmediate::isImmediate(value) ? const_cast<JSValue *>(value) : value->asCell()->toPrimitive(exec, preferredType); 0611 } 0612 0613 inline bool JSValue::getPrimitiveNumber(ExecState *exec, double &number, JSValue *&value) 0614 { 0615 return getPrimitiveNumber(this, exec, number, value); 0616 } 0617 0618 inline bool JSValue::getPrimitiveNumber(JSValue *that, ExecState *exec, double &number, JSValue *&value) 0619 { 0620 if (JSImmediate::isImmediate(that)) { 0621 number = JSImmediate::toDouble(that); 0622 value = that; 0623 return true; 0624 } 0625 return that->asCell()->getPrimitiveNumber(exec, number, value); 0626 0627 } 0628 0629 inline bool JSValue::toBoolean(ExecState *exec) const 0630 { 0631 return toBoolean(this, exec); 0632 } 0633 0634 inline bool JSValue::toBoolean(const JSValue *value, ExecState *exec) 0635 { 0636 return JSImmediate::isImmediate(value) ? JSImmediate::toBoolean(value) : value->asCell()->toBoolean(exec); 0637 } 0638 0639 ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const 0640 { 0641 return toNumber(this, exec); 0642 } 0643 0644 ALWAYS_INLINE double JSValue::toNumber(const JSValue *value, ExecState *exec) 0645 { 0646 return JSImmediate::isImmediate(value) ? JSImmediate::toDouble(value) : value->asCell()->toNumber(exec); 0647 } 0648 0649 ALWAYS_INLINE JSValue *JSValue::toJSNumber(ExecState *exec) const 0650 { 0651 return JSImmediate::isNumber(this) ? const_cast<JSValue *>(this) : jsNumber(toNumber(this, exec)); 0652 } 0653 0654 inline UString JSValue::toString(ExecState *exec) const 0655 { 0656 return toString(this, exec); 0657 } 0658 0659 inline UString JSValue::toString(const JSValue *value, ExecState *exec) 0660 { 0661 return JSImmediate::isImmediate(value) ? JSImmediate::toString(value) : value->asCell()->toString(exec); 0662 } 0663 0664 inline JSObject *JSValue::toObject(ExecState *exec) const 0665 { 0666 return toObject(this, exec); 0667 } 0668 0669 inline JSObject *JSValue::toObject(const JSValue *value, ExecState *exec) 0670 { 0671 return JSImmediate::isImmediate(value) ? JSImmediate::toObject(value, exec) : value->asCell()->toObject(exec); 0672 } 0673 0674 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState *exec) const 0675 { 0676 return toInt32(this, exec); 0677 } 0678 0679 ALWAYS_INLINE int32_t JSValue::toInt32(const JSValue *value, ExecState *exec) 0680 { 0681 int32_t i; 0682 if (getTruncatedInt32(value, i)) { 0683 return i; 0684 } 0685 bool ok; 0686 return toInt32SlowCase(value, exec, ok); 0687 } 0688 0689 inline uint32_t JSValue::toUInt32(ExecState *exec) const 0690 { 0691 return toUInt32(this, exec); 0692 } 0693 0694 inline uint32_t JSValue::toUInt32(const JSValue *value, ExecState *exec) 0695 { 0696 uint32_t i; 0697 if (getTruncatedUInt32(value, i)) { 0698 return i; 0699 } 0700 bool ok; 0701 return toUInt32SlowCase(value, exec, ok); 0702 } 0703 0704 inline int32_t JSValue::toInt32(double val) 0705 { 0706 if (!(val >= -2147483648.0 && val < 2147483648.0)) { 0707 bool ignored; 0708 return toInt32SlowCase(val, ignored); 0709 } 0710 return static_cast<int32_t>(val); 0711 } 0712 0713 inline int32_t JSValue::toUInt32(double val) 0714 { 0715 if (!(val >= 0.0 && val < 4294967296.0)) { 0716 bool ignored; 0717 return toUInt32SlowCase(val, ignored); 0718 } 0719 return static_cast<uint32_t>(val); 0720 } 0721 0722 inline int32_t JSValue::toInt32(ExecState *exec, bool &ok) const 0723 { 0724 return toInt32(this, exec, ok); 0725 } 0726 0727 inline int32_t JSValue::toInt32(const JSValue *value, ExecState *exec, bool &ok) 0728 { 0729 int32_t i; 0730 if (getTruncatedInt32(value, i)) { 0731 ok = true; 0732 return i; 0733 } 0734 return toInt32SlowCase(value, exec, ok); 0735 } 0736 0737 inline uint32_t JSValue::toUInt32(ExecState *exec, bool &ok) const 0738 { 0739 return toUInt32(this, exec, ok); 0740 } 0741 0742 inline uint32_t JSValue::toUInt32(const JSValue *value, ExecState *exec, bool &ok) 0743 { 0744 uint32_t i; 0745 if (getTruncatedUInt32(value, i)) { 0746 ok = true; 0747 return i; 0748 } 0749 return toUInt32SlowCase(value, exec, ok); 0750 } 0751 0752 inline bool JSValue::implementsCall() const 0753 { 0754 return implementsCall(this); 0755 } 0756 0757 inline bool JSValue::implementsCall(const JSValue *value) 0758 { 0759 if (JSImmediate::isImmediate(value)) { 0760 return false; // immediate values are never calleable. 0761 } else { 0762 return value->asCell()->implementsCall(); 0763 } 0764 0765 } 0766 0767 } // namespace 0768 0769 #endif // KJS_VALUE_H