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