1 /*
2  *  This file is part of the KDE libraries
3  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *  Copyright (C) 2003, 2004, 2005, 2007 Apple Inc. All rights reserved.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Library General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Library General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Library General Public License
18  *  along with this library; see the file COPYING.LIB.  If not, write to
19  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301, USA.
21  *
22  */
23 
24 #ifndef KJS_VALUE_H
25 #define KJS_VALUE_H
26 
27 #include "JSImmediate.h"
28 #include "ustring.h"
29 #include "collector.h"
30 #include <wtf/Noncopyable.h>
31 #include <stddef.h> // for size_t
32 
33 #ifndef NDEBUG // protection against problems if committing with KJS_VERBOSE on
34 
35 // Uncomment this to enable very verbose output from KJS
36 //#define KJS_VERBOSE
37 // Uncomment this to debug memory allocation and garbage collection
38 //#define KJS_DEBUG_MEM
39 
40 #endif
41 
42 namespace KJS
43 {
44 
45 struct ClassInfo;
46 class ExecState;
47 class JSObject;
48 class JSCell;
49 
50 /**
51  * JSValue is the base type for all primitives (Undefined, Null, Boolean,
52  * String, Number) and objects in ECMAScript.
53  *
54  * Note: you should never inherit from JSValue as it is for primitive types
55  * only (all of which are provided internally by KJS). Instead, inherit from
56  * JSObject.
57  */
58 class KJS_EXPORT JSValue : Noncopyable
59 {
60     friend class JSCell; // so it can derive from this class
61     friend class Collector; // so it can call asCell()
62 
63 private:
64     JSValue();
65     virtual ~JSValue();
66 
67 public:
68     // Querying the type.
69     [[deprecated]] JSType type() const;
70     static JSType type(const JSValue *value);
71     [[deprecated]] bool isUndefined() const;
72     static bool isUndefined(const JSValue *value);
73     [[deprecated]] bool isNull() const;
74     static bool isNull(const JSValue *value);
75     [[deprecated]] bool isUndefinedOrNull() const;
76     static bool isUndefinedOrNull(const JSValue *value);
77     [[deprecated]] bool isBoolean() const;
78     static bool isBoolean(const JSValue *value);
79     [[deprecated]] bool isNumber() const;
80     static bool isNumber(const JSValue *value);
81     [[deprecated]] bool isString() const;
82     static bool isString(const JSValue *value);
83     [[deprecated]] bool isObject() const;
84     static bool isObject(const JSValue *value);
85     [[deprecated]] bool isObject(const ClassInfo *) const;
86     static bool isObject(const JSValue *value, const ClassInfo *);
87 
88     // Extracting the value.
89     [[deprecated]] bool getBoolean(bool &) const;
90     static bool getBoolean(const JSValue *value, bool &);
91     [[deprecated]] bool getBoolean() const; // false if not a boolean
92     static bool getBoolean(const JSValue *value);
93     [[deprecated]] bool getNumber(double &) const;
94     static bool getNumber(const JSValue *value, double &);
95     [[deprecated]] double getNumber() const; // NaN if not a number
96     static double getNumber(const JSValue *value);
97     [[deprecated]] bool getString(UString &) const;
98     static bool getString(const JSValue *value, UString &);
99     [[deprecated]] UString getString() const; // null string if not a string
100     static UString getString(const JSValue *value); // null string if not a string
101     [[deprecated]] JSObject *getObject(); // NULL if not an object
102     static JSObject *getObject(JSValue *value);
103     [[deprecated]] const JSObject *getObject() const; // NULL if not an object
104     static const JSObject *getObject(const JSValue *value);
105 
106     // Extracting integer values.
107     [[deprecated]] bool getUInt32(uint32_t &) const;
108     static bool getUInt32(const JSValue *value, uint32_t &);
109     [[deprecated]] bool getTruncatedInt32(int32_t &) const;
110     static bool getTruncatedInt32(const JSValue *value, int32_t &v);
111     [[deprecated]] bool getTruncatedUInt32(uint32_t &) const;
112     static bool getTruncatedUInt32(const JSValue *value, uint32_t &v);
113 
114     [[deprecated]] JSValue *getByIndex(ExecState *exec, unsigned propertyName) const;
115     static JSValue *getByIndex(const JSValue *value, ExecState *exec, unsigned propertyName);
116 
117     // Basic conversions.
118     [[deprecated]] JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const;
119     static JSValue *toPrimitive(const JSValue *value, ExecState *exec, JSType preferredType = UnspecifiedType);
120     [[deprecated]] bool getPrimitiveNumber(ExecState *exec, double &number, JSValue *&value);
121     static bool getPrimitiveNumber(JSValue *that, ExecState *exec, double &number, JSValue *&value);
122 
123     [[deprecated]] bool toBoolean(ExecState *exec) const;
124     static bool toBoolean(const JSValue *value, ExecState *exec);
125     [[deprecated]] double toNumber(ExecState *exec) const;
126     static double toNumber(const JSValue *value, ExecState *exec);
127     JSValue *toJSNumber(ExecState *) const; // Fast path for when you expect that the value is an immediate number.
128     [[deprecated]] UString toString(ExecState *exec) const;
129     static UString toString(const JSValue *value, ExecState *exec);
130     [[deprecated]] JSObject *toObject(ExecState *exec) const;
131     static JSObject *toObject(const JSValue *value, ExecState *exec);
132 
133     // Integer conversions.
134     [[deprecated]] double toInteger(ExecState *) const;
135     static double toInteger(const JSValue *value, ExecState *);
136     [[deprecated]] double toIntegerPreserveNaN(ExecState *) const;
137     static double toIntegerPreserveNaN(const JSValue *value, ExecState *);
138     [[deprecated]] int32_t toInt32(ExecState *) const;
139     static int32_t toInt32(const JSValue *value, ExecState *exec);
140     [[deprecated]] int32_t toInt32(ExecState *, bool &ok) const;
141     static int32_t toInt32(const JSValue *value, ExecState *, bool &ok);
142     [[deprecated]] uint32_t toUInt32(ExecState *) const;
143     static uint32_t toUInt32(const JSValue *value, ExecState *);
144     [[deprecated]] uint32_t toUInt32(ExecState *, bool &ok) const;
145     static uint32_t toUInt32(const JSValue *value, ExecState *, bool &ok);
146     [[deprecated]] uint16_t toUInt16(ExecState *exec) const;
147     static uint16_t toUInt16(const JSValue *value, ExecState *exec);
148 
149     // These are identical logic to above, and faster than jsNumber(number)->toInt32(exec)
150     static int32_t toInt32(double);
151     static int32_t toUInt32(double);
152 
153     // Floating point conversions.
154     [[deprecated]] float toFloat(ExecState *) const;
155     static float toFloat(const JSValue *value, ExecState *);
156 
157     // Object-level properties...
158 
159     /**
160      * Whether or not the value implements the call() method. If it does, this also
161      * implies this is an object, and hence it can be cast to a JSObject
162      * and the call method can be invoked
163      *
164      * @return true if this is an object implementing the call() method, otherwise
165      * false
166      */
167     [[deprecated]] bool implementsCall() const;
168     static bool implementsCall(const JSValue *value);
169 
170     // Garbage collection.
171     [[deprecated]] void mark();
172     static void mark(JSValue *value);
173     [[deprecated]] bool marked() const;
174     static bool marked(const JSValue *value);
175 
176     static int32_t toInt32SlowCase(double, bool &ok);
177     static uint32_t toUInt32SlowCase(double, bool &ok);
178 
179 private:
180     static int32_t toInt32SlowCase(const JSValue *value, ExecState *, bool &ok);
181     static uint32_t toUInt32SlowCase(const JSValue *value, ExecState *, bool &ok);
182 
183     // Implementation details.
184     JSCell *asCell();
185     const JSCell *asCell() const;
186 
187     // emulate Q_DISABLE_COPY to avoid msvc linker errors
188 #if !defined(_MSC_VER) || !defined(MAKE_KJS_LIB)
189     // Give a compile time error if we try to copy one of these.
190     JSValue(const JSValue &);
191     JSValue &operator=(const JSValue &);
192 #endif
193 };
194 
195 class KJS_EXPORT JSCell : public JSValue
196 {
197     friend class Collector;
198     friend class NumberImp;
199     friend class StringImp;
200     friend class JSObject;
201     friend class GetterSetterImp;
202 private:
203     explicit JSCell();
204     ~JSCell() override;
205 public:
206     // Querying the type.
207     virtual JSType type() const = 0;
208     bool isNumber() const;
209     bool isString() const;
210     bool isObject() const;
211     bool isObject(const ClassInfo *) const;
212 
213     // Extracting the value.
214     bool getNumber(double &) const;
215     double getNumber() const; // NaN if not a number
216     bool getString(UString &) const;
217     UString getString() const; // null string if not a string
218     JSObject *getObject(); // NULL if not an object
219     const JSObject *getObject() const; // NULL if not an object
220 
221     // Extracting integer values.
222     virtual bool getUInt32(uint32_t &) const;
223     virtual bool getTruncatedInt32(int32_t &) const;
224     virtual bool getTruncatedUInt32(uint32_t &) const;
225 
226     // Basic conversions.
227     virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const = 0;
228     virtual bool getPrimitiveNumber(ExecState *exec, double &number, JSValue *&value) = 0;
229     virtual bool toBoolean(ExecState *exec) const = 0;
230     virtual double toNumber(ExecState *exec) const = 0;
231     virtual UString toString(ExecState *exec) const = 0;
232     virtual JSObject *toObject(ExecState *exec) const = 0;
233 
234     // Higher-level (object-like) properties:
235     virtual bool implementsCall() const;
236 
237     // Garbage collection.
238     void *operator new(size_t);
239     virtual void mark();
240     bool marked() const;
241 };
242 
243 KJS_EXPORT JSValue *jsNumberCell(double);
244 
245 KJS_EXPORT JSCell *jsString(); // returns empty string
246 KJS_EXPORT JSCell *jsString(const UString &); // returns empty string if passed null string
247 KJS_EXPORT JSCell *jsString(const char * = ""); // returns empty string if passed 0
248 KJS_EXPORT JSCell *jsString(const char *s, int len);
249 
250 // should be used for strings that are owned by an object that will
251 // likely outlive the JSValue this makes, such as the parse tree or a
252 // DOM object that contains a UString
253 JSCell *jsOwnedString(const UString &);
254 
jsUndefined()255 inline JSValue *jsUndefined()
256 {
257     return JSImmediate::undefinedImmediate();
258 }
259 
jsNull()260 inline JSValue *jsNull()
261 {
262     return JSImmediate::nullImmediate();
263 }
264 
jsNaN()265 inline JSValue *jsNaN()
266 {
267     static const union {
268         uint64_t bits;
269         double d;
270     } nan = { 0x7ff80000ULL << 32 };
271     return jsNumberCell(nan.d);
272 }
273 
jsBoolean(bool b)274 inline JSValue *jsBoolean(bool b)
275 {
276     return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
277 }
278 
jsNumber(double d)279 ALWAYS_INLINE JSValue *jsNumber(double d)
280 {
281     JSValue *v = JSImmediate::from(d);
282     return v ? v : jsNumberCell(d);
283 }
284 
jsNumber(int i)285 ALWAYS_INLINE JSValue *jsNumber(int i)
286 {
287     JSValue *v = JSImmediate::from(i);
288     return v ? v : jsNumberCell(i);
289 }
290 
jsNumber(unsigned i)291 ALWAYS_INLINE JSValue *jsNumber(unsigned i)
292 {
293     JSValue *v = JSImmediate::from(i);
294     return v ? v : jsNumberCell(i);
295 }
296 
jsNumber(long i)297 ALWAYS_INLINE JSValue *jsNumber(long i)
298 {
299     JSValue *v = JSImmediate::from(i);
300     return v ? v : jsNumberCell(i);
301 }
302 
jsNumber(unsigned long i)303 ALWAYS_INLINE JSValue *jsNumber(unsigned long i)
304 {
305     JSValue *v = JSImmediate::from(i);
306     return v ? v : jsNumberCell(i);
307 }
308 
jsNumber(long long i)309 ALWAYS_INLINE JSValue *jsNumber(long long i)
310 {
311     JSValue *v = JSImmediate::from(i);
312     return v ? v : jsNumberCell(static_cast<double>(i));
313 }
314 
jsNumber(unsigned long long i)315 ALWAYS_INLINE JSValue *jsNumber(unsigned long long i)
316 {
317     JSValue *v = JSImmediate::from(i);
318     return v ? v : jsNumberCell(static_cast<double>(i));
319 }
320 
jsNumberFromAnd(ExecState * exec,JSValue * v1,JSValue * v2)321 ALWAYS_INLINE JSValue *jsNumberFromAnd(ExecState *exec, JSValue *v1, JSValue *v2)
322 {
323     if (JSImmediate::areBothImmediateNumbers(v1, v2)) {
324         return JSImmediate::andImmediateNumbers(v1, v2);
325     }
326     return jsNumber(JSValue::toInt32(v1, exec) & JSValue::toInt32(v2, exec));
327 }
328 
JSValue()329 inline JSValue::JSValue()
330 {
331 }
332 
~JSValue()333 inline JSValue::~JSValue()
334 {
335 }
336 
JSCell()337 inline JSCell::JSCell()
338 {
339 }
340 
~JSCell()341 inline JSCell::~JSCell()
342 {
343 }
344 
isNumber()345 inline bool JSCell::isNumber() const
346 {
347     return type() == NumberType;
348 }
349 
isString()350 inline bool JSCell::isString() const
351 {
352     return type() == StringType;
353 }
354 
isObject()355 inline bool JSCell::isObject() const
356 {
357     return type() == ObjectType;
358 }
359 
marked()360 inline bool JSCell::marked() const
361 {
362     return Collector::isCellMarked(this);
363 }
364 
mark()365 inline void JSCell::mark()
366 {
367     return Collector::markCell(this);
368 }
369 
asCell()370 ALWAYS_INLINE JSCell *JSValue::asCell()
371 {
372     ASSERT(!JSImmediate::isImmediate(this));
373     return static_cast<JSCell *>(this);
374 }
375 
asCell()376 ALWAYS_INLINE const JSCell *JSValue::asCell() const
377 {
378     ASSERT(!JSImmediate::isImmediate(this));
379     return static_cast<const JSCell *>(this);
380 }
381 
isUndefined()382 inline bool JSValue::isUndefined() const
383 {
384     return isUndefined(this);
385 }
386 
isUndefined(const JSValue * value)387 inline bool JSValue::isUndefined(const JSValue *value)
388 {
389     return value == jsUndefined();
390 }
391 
isNull()392 inline bool JSValue::isNull() const
393 {
394     return isNull(this);
395 }
396 
isNull(const JSValue * value)397 inline bool JSValue::isNull(const JSValue *value)
398 {
399     return value == jsNull();
400 }
401 
isUndefinedOrNull()402 inline bool JSValue::isUndefinedOrNull() const
403 {
404     return isUndefinedOrNull(this);
405 }
406 
isUndefinedOrNull(const JSValue * value)407 inline bool JSValue::isUndefinedOrNull(const JSValue *value)
408 {
409     return JSImmediate::isUndefinedOrNull(value);
410 }
411 
isBoolean()412 inline bool JSValue::isBoolean() const
413 {
414     return isBoolean(this);
415 }
416 
isBoolean(const JSValue * value)417 inline bool JSValue::isBoolean(const JSValue *value)
418 {
419     return JSImmediate::isBoolean(value);
420 }
421 
isNumber()422 inline bool JSValue::isNumber() const
423 {
424     return isNumber(this);
425 }
426 
isNumber(const JSValue * value)427 inline bool JSValue::isNumber(const JSValue *value)
428 {
429     return JSImmediate::isNumber(value) ||
430            (!JSImmediate::isImmediate(value) && value->asCell()->isNumber());
431 }
432 
isString()433 inline bool JSValue::isString() const
434 {
435     return isString(this);
436 }
437 
isString(const JSValue * value)438 inline bool JSValue::isString(const JSValue *value)
439 {
440     return !JSImmediate::isImmediate(value) && value->asCell()->isString();
441 }
442 
isObject()443 inline bool JSValue::isObject() const
444 {
445     return isObject(this);
446 }
447 
isObject(const JSValue * value)448 inline bool JSValue::isObject(const JSValue *value)
449 {
450     return !JSImmediate::isImmediate(value) && value->asCell()->isObject();
451 }
452 
getBoolean(bool & v)453 inline bool JSValue::getBoolean(bool &v) const
454 {
455     return getBoolean(this, v);
456 }
457 
458 
getBoolean(const JSValue * value,bool & v)459 inline bool JSValue::getBoolean(const JSValue *value, bool &v)
460 {
461     if (JSImmediate::isBoolean(value)) {
462         v = JSImmediate::toBoolean(value);
463         return true;
464     }
465 
466     return false;
467 }
468 
getBoolean()469 inline bool JSValue::getBoolean() const
470 {
471     return getBoolean(this);
472 }
473 
getBoolean(const JSValue * value)474 inline bool JSValue::getBoolean(const JSValue *value)
475 {
476     return JSImmediate::isBoolean(value) ? JSImmediate::toBoolean(value) : false;
477 }
478 
getNumber(double & v)479 inline bool JSValue::getNumber(double &v) const
480 {
481     return getNumber(this, v);
482 }
483 
getNumber(const JSValue * value,double & v)484 inline bool JSValue::getNumber(const JSValue *value, double &v)
485 {
486     if (JSImmediate::isImmediate(value)) {
487         return JSImmediate::getNumber(value, v);
488     }
489     return value->asCell()->getNumber(v);
490 }
491 
getNumber()492 inline double JSValue::getNumber() const
493 {
494     return getNumber(this);
495 }
496 
getNumber(const JSValue * value)497 inline double JSValue::getNumber(const JSValue *value)
498 {
499     return JSImmediate::isImmediate(value) ? JSImmediate::getNumber(value) : value->asCell()->getNumber();
500 }
501 
getString(UString & s)502 inline bool JSValue::getString(UString &s) const
503 {
504     return getString(this, s);
505 }
506 
getString(const JSValue * value,UString & s)507 inline bool JSValue::getString(const JSValue *value, UString &s)
508 {
509     return !JSImmediate::isImmediate(value) && value->asCell()->getString(s);
510 }
511 
getString()512 inline UString JSValue::getString() const
513 {
514     return getString(this);
515 }
516 
getString(const JSValue * value)517 inline UString JSValue::getString(const JSValue *value)
518 {
519     return JSImmediate::isImmediate(value) ? UString() : value->asCell()->getString();
520 }
521 
getObject()522 inline JSObject *JSValue::getObject()
523 {
524     return getObject(this);
525 }
526 
getObject()527 inline const JSObject *JSValue::getObject() const
528 {
529     return getObject(this);
530 }
531 
getObject(JSValue * value)532 inline JSObject *JSValue::getObject(JSValue *value)
533 {
534     return JSImmediate::isImmediate(value) ? nullptr : value->asCell()->getObject();
535 }
536 
getObject(const JSValue * value)537 inline const JSObject *JSValue::getObject(const JSValue *value)
538 {
539     return JSImmediate::isImmediate(value) ? nullptr : value->asCell()->getObject();
540 }
541 
getUInt32(uint32_t & v)542 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t &v) const
543 {
544     return getUInt32(this, v);
545 }
546 
getUInt32(const JSValue * value,uint32_t & v)547 ALWAYS_INLINE bool JSValue::getUInt32(const JSValue *value, uint32_t &v)
548 {
549     return JSImmediate::isImmediate(value) ? JSImmediate::getUInt32(value, v) : value->asCell()->getUInt32(v);
550 }
551 
getTruncatedInt32(int32_t & v)552 ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t &v) const
553 {
554     return getTruncatedInt32(this, v);
555 }
556 
getTruncatedInt32(const JSValue * value,int32_t & v)557 ALWAYS_INLINE bool JSValue::getTruncatedInt32(const JSValue *value, int32_t &v)
558 {
559     return JSImmediate::isImmediate(value) ? JSImmediate::getTruncatedInt32(value, v) : value->asCell()->getTruncatedInt32(v);
560 }
561 
getTruncatedUInt32(uint32_t & v)562 inline bool JSValue::getTruncatedUInt32(uint32_t &v) const
563 {
564     return getTruncatedUInt32(this, v);
565 }
566 
getTruncatedUInt32(const JSValue * value,uint32_t & v)567 inline bool JSValue::getTruncatedUInt32(const JSValue *value, uint32_t &v)
568 {
569     return JSImmediate::isImmediate(value) ? JSImmediate::getTruncatedUInt32(value, v) : value->asCell()->getTruncatedUInt32(v);
570 }
571 
mark()572 inline void JSValue::mark()
573 {
574     mark(this);
575 }
576 
mark(JSValue * value)577 inline void JSValue::mark(JSValue *value)
578 {
579     ASSERT(!JSImmediate::isImmediate(value)); // callers should check !marked() before calling mark()
580     value->asCell()->mark();
581 }
582 
marked()583 inline bool JSValue::marked() const
584 {
585     return marked(this);
586 }
587 
marked(const JSValue * value)588 inline bool JSValue::marked(const JSValue *value)
589 {
590     return JSImmediate::isImmediate(value) || value->asCell()->marked();
591 }
592 
type()593 inline JSType JSValue::type() const
594 {
595     return type(this);
596 }
597 
type(const JSValue * value)598 inline JSType JSValue::type(const JSValue *value)
599 {
600     return JSImmediate::isImmediate(value) ? JSImmediate::type(value) : value->asCell()->type();
601 }
602 
toPrimitive(ExecState * exec,JSType preferredType)603 inline JSValue *JSValue::toPrimitive(ExecState *exec, JSType preferredType) const
604 {
605     return toPrimitive(this, exec, preferredType);
606 }
607 
toPrimitive(const JSValue * value,ExecState * exec,JSType preferredType)608 inline JSValue *JSValue::toPrimitive(const JSValue *value, ExecState *exec, JSType preferredType)
609 {
610     return JSImmediate::isImmediate(value) ? const_cast<JSValue *>(value) : value->asCell()->toPrimitive(exec, preferredType);
611 }
612 
getPrimitiveNumber(ExecState * exec,double & number,JSValue * & value)613 inline bool JSValue::getPrimitiveNumber(ExecState *exec, double &number, JSValue *&value)
614 {
615     return getPrimitiveNumber(this, exec, number, value);
616 }
617 
getPrimitiveNumber(JSValue * that,ExecState * exec,double & number,JSValue * & value)618 inline bool JSValue::getPrimitiveNumber(JSValue *that, ExecState *exec, double &number, JSValue *&value)
619 {
620     if (JSImmediate::isImmediate(that)) {
621         number = JSImmediate::toDouble(that);
622         value = that;
623         return true;
624     }
625     return that->asCell()->getPrimitiveNumber(exec, number, value);
626 
627 }
628 
toBoolean(ExecState * exec)629 inline bool JSValue::toBoolean(ExecState *exec) const
630 {
631     return toBoolean(this, exec);
632 }
633 
toBoolean(const JSValue * value,ExecState * exec)634 inline bool JSValue::toBoolean(const JSValue *value, ExecState *exec)
635 {
636     return JSImmediate::isImmediate(value) ? JSImmediate::toBoolean(value) : value->asCell()->toBoolean(exec);
637 }
638 
toNumber(ExecState * exec)639 ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const
640 {
641     return toNumber(this, exec);
642 }
643 
toNumber(const JSValue * value,ExecState * exec)644 ALWAYS_INLINE double JSValue::toNumber(const JSValue *value, ExecState *exec)
645 {
646     return JSImmediate::isImmediate(value) ? JSImmediate::toDouble(value) : value->asCell()->toNumber(exec);
647 }
648 
toJSNumber(ExecState * exec)649 ALWAYS_INLINE JSValue *JSValue::toJSNumber(ExecState *exec) const
650 {
651     return JSImmediate::isNumber(this) ? const_cast<JSValue *>(this) : jsNumber(toNumber(this, exec));
652 }
653 
toString(ExecState * exec)654 inline UString JSValue::toString(ExecState *exec) const
655 {
656     return toString(this, exec);
657 }
658 
toString(const JSValue * value,ExecState * exec)659 inline UString JSValue::toString(const JSValue *value, ExecState *exec)
660 {
661     return JSImmediate::isImmediate(value) ? JSImmediate::toString(value) : value->asCell()->toString(exec);
662 }
663 
toObject(ExecState * exec)664 inline JSObject *JSValue::toObject(ExecState *exec) const
665 {
666     return toObject(this, exec);
667 }
668 
toObject(const JSValue * value,ExecState * exec)669 inline JSObject *JSValue::toObject(const JSValue *value, ExecState *exec)
670 {
671     return JSImmediate::isImmediate(value) ? JSImmediate::toObject(value, exec) : value->asCell()->toObject(exec);
672 }
673 
toInt32(ExecState * exec)674 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState *exec) const
675 {
676     return toInt32(this, exec);
677 }
678 
toInt32(const JSValue * value,ExecState * exec)679 ALWAYS_INLINE int32_t JSValue::toInt32(const JSValue *value, ExecState *exec)
680 {
681     int32_t i;
682     if (getTruncatedInt32(value, i)) {
683         return i;
684     }
685     bool ok;
686     return toInt32SlowCase(value, exec, ok);
687 }
688 
toUInt32(ExecState * exec)689 inline uint32_t JSValue::toUInt32(ExecState *exec) const
690 {
691     return toUInt32(this, exec);
692 }
693 
toUInt32(const JSValue * value,ExecState * exec)694 inline uint32_t JSValue::toUInt32(const JSValue *value, ExecState *exec)
695 {
696     uint32_t i;
697     if (getTruncatedUInt32(value, i)) {
698         return i;
699     }
700     bool ok;
701     return toUInt32SlowCase(value, exec, ok);
702 }
703 
toInt32(double val)704 inline int32_t JSValue::toInt32(double val)
705 {
706     if (!(val >= -2147483648.0 && val < 2147483648.0)) {
707         bool ignored;
708         return toInt32SlowCase(val, ignored);
709     }
710     return static_cast<int32_t>(val);
711 }
712 
toUInt32(double val)713 inline int32_t JSValue::toUInt32(double val)
714 {
715     if (!(val >= 0.0 && val < 4294967296.0)) {
716         bool ignored;
717         return toUInt32SlowCase(val, ignored);
718     }
719     return static_cast<uint32_t>(val);
720 }
721 
toInt32(ExecState * exec,bool & ok)722 inline int32_t JSValue::toInt32(ExecState *exec, bool &ok) const
723 {
724     return toInt32(this, exec, ok);
725 }
726 
toInt32(const JSValue * value,ExecState * exec,bool & ok)727 inline int32_t JSValue::toInt32(const JSValue *value, ExecState *exec, bool &ok)
728 {
729     int32_t i;
730     if (getTruncatedInt32(value, i)) {
731         ok = true;
732         return i;
733     }
734     return toInt32SlowCase(value, exec, ok);
735 }
736 
toUInt32(ExecState * exec,bool & ok)737 inline uint32_t JSValue::toUInt32(ExecState *exec, bool &ok) const
738 {
739     return toUInt32(this, exec, ok);
740 }
741 
toUInt32(const JSValue * value,ExecState * exec,bool & ok)742 inline uint32_t JSValue::toUInt32(const JSValue *value, ExecState *exec, bool &ok)
743 {
744     uint32_t i;
745     if (getTruncatedUInt32(value, i)) {
746         ok = true;
747         return i;
748     }
749     return toUInt32SlowCase(value, exec, ok);
750 }
751 
implementsCall()752 inline bool JSValue::implementsCall() const
753 {
754     return implementsCall(this);
755 }
756 
implementsCall(const JSValue * value)757 inline bool JSValue::implementsCall(const JSValue *value)
758 {
759     if (JSImmediate::isImmediate(value)) {
760         return false;    // immediate values are never calleable.
761     } else {
762         return value->asCell()->implementsCall();
763     }
764 
765 }
766 
767 } // namespace
768 
769 #endif // KJS_VALUE_H
770