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