source: webkit/trunk/JavaScriptCore/kjs/JSValue.h@ 34852

Last change on this file since 34852 was 34821, checked in by Darin Adler, 17 years ago

2008-06-26 Darin Adler <Darin Adler>

Reviewed by Geoff.

  • optimize UString append and the replace function a bit

SunSpider says 1.8% faster.

  • VM/JSPropertyNameIterator.cpp: Added include of JSString.h, now needed because jsString returns a JSString*.
  • VM/Machine.cpp: (KJS::Machine::privateExecute): Removed the toObject call from native function calls. Also removed code to put the this value into a register.
  • kjs/BooleanObject.cpp: (KJS::booleanProtoFuncToString): Rewrite to handle false and true separately.
  • kjs/FunctionPrototype.cpp: (KJS::constructFunction): Use single-character append rather than building a string for each character.
  • kjs/JSFunction.cpp: (KJS::globalFuncUnescape): Ditto.
  • kjs/JSImmediate.cpp: (KJS::JSImmediate::prototype): Added. Gets the appropriate prototype for use with an immediate value. To be used instead of toObject when doing a get on an immediate value.
  • kjs/JSImmediate.h: Added prototype.
  • kjs/JSObject.cpp: (KJS::JSObject::toString): Tweaked formatting.
  • kjs/JSObject.h: (KJS::JSValue::get): Use prototype instead of toObject to avoid creating an object wrapper just to search for properties. This also saves an unnecessary hash table lookup since the object wrappers themselves don't have any properties.
  • kjs/JSString.h: Added toThisString and toThisJSString.
  • kjs/JSValue.cpp: (KJS::JSCell::toThisString): Added. (KJS::JSCell::toThisJSString): Added. (KJS::JSCell::getJSNumber): Added. (KJS::jsString): Changed return type to JSString*. (KJS::jsOwnedString): Ditto.
  • kjs/JSValue.h: (KJS::JSValue::toThisString): Added. (KJS::JSValue::toThisJSString): Added. (KJS::JSValue::getJSNumber): Added.
  • kjs/NumberObject.cpp: (KJS::NumberObject::getJSNumber): Added. (KJS::integer_part_noexp): Append C string directly rather than first turning it into a UString. (KJS::numberProtoFuncToString): Use getJSNumber to check if the value is a number rather than isObject(&NumberObject::info). This works for immediate numbers, number cells, and NumberObject instances. (KJS::numberProtoFuncToLocaleString): Ditto. (KJS::numberProtoFuncValueOf): Ditto. (KJS::numberProtoFuncToFixed): Ditto. (KJS::numberProtoFuncToExponential): Ditto. (KJS::numberProtoFuncToPrecision): Ditto.
  • kjs/NumberObject.h: Added getJSNumber.
  • kjs/PropertySlot.cpp: Tweaked comment.
  • kjs/internal.cpp: (KJS::JSString::toThisString): Added. (KJS::JSString::toThisJSString): Added. (KJS::JSString::getOwnPropertySlot): Changed code that searches the prototype chain to start with the string prototype and not create a string object. (KJS::JSNumberCell::toThisString): Added. (KJS::JSNumberCell::getJSNumber): Added.
  • kjs/lookup.cpp: (KJS::staticFunctionGetter): Moved here, because there's no point in having a function that's only used for a function pointer be inline. (KJS::setUpStaticFunctionSlot): New function for getStaticFunctionSlot.
  • kjs/lookup.h: (KJS::staticValueGetter): Don't mark this inline. It doesn't make sense to have a function that's only used for a function pointer be inline. (KJS::getStaticFunctionSlot): Changed to get properties from the parent first before doing any handling of functions. This is the fastest way to return the function once the initial setup is done.
  • kjs/string_object.cpp: (KJS::StringObject::getPropertyNames): Call value() instead of getString(), avoiding an unnecessary virtual function call (the call to the type() function in the implementation of the isString() function). (KJS::StringObject::toString): Added. (KJS::StringObject::toThisString): Added. (KJS::StringObject::toThisJSString): Added. (KJS::substituteBackreferences): Rewrote to use a appending algorithm instead of a the old one that tried to replace in place. (KJS::stringProtoFuncReplace): Merged this function and the replace function. Replaced the hand-rolled dynamic arrays for source ranges and replacements with Vector. (KJS::stringProtoFuncToString): Handle JSString as well as StringObject. Removed the separate valueOf implementation, since it can just share this. (KJS::stringProtoFuncCharAt): Use toThisString, which handles JSString as well as StringObject, and is slightly more efficient than the old code too. (KJS::stringProtoFuncCharCodeAt): Ditto. (KJS::stringProtoFuncConcat): Ditto. (KJS::stringProtoFuncIndexOf): Ditto. (KJS::stringProtoFuncLastIndexOf): Ditto. (KJS::stringProtoFuncMatch): Ditto. (KJS::stringProtoFuncSearch): Ditto. (KJS::stringProtoFuncSlice): Ditto. (KJS::stringProtoFuncSplit): Ditto. (KJS::stringProtoFuncSubstr): Ditto. (KJS::stringProtoFuncSubstring): Ditto. (KJS::stringProtoFuncToLowerCase): Use toThisJSString. (KJS::stringProtoFuncToUpperCase): Ditto. (KJS::stringProtoFuncToLocaleLowerCase): Ditto. (KJS::stringProtoFuncToLocaleUpperCase): Ditto. (KJS::stringProtoFuncLocaleCompare): Ditto. (KJS::stringProtoFuncBig): Use toThisString. (KJS::stringProtoFuncSmall): Ditto. (KJS::stringProtoFuncBlink): Ditto. (KJS::stringProtoFuncBold): Ditto. (KJS::stringProtoFuncFixed): Ditto. (KJS::stringProtoFuncItalics): Ditto. (KJS::stringProtoFuncStrike): Ditto. (KJS::stringProtoFuncSub): Ditto. (KJS::stringProtoFuncSup): Ditto. (KJS::stringProtoFuncFontcolor): Ditto. (KJS::stringProtoFuncFontsize): Ditto. (KJS::stringProtoFuncAnchor): Ditto. (KJS::stringProtoFuncLink): Ditto.
  • kjs/string_object.h: Added toString, toThisString, and toThisJSString.
  • kjs/ustring.cpp: (KJS::UString::append): Added a version that takes a character pointer and size, so we don't have to create a UString just to append to another UString.
  • kjs/ustring.h:
  • Property svn:eol-style set to native
File size: 17.7 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef JSValue_h
24#define JSValue_h
25
26#include "CallData.h"
27#include "ConstructData.h"
28#include "ExecState.h"
29#include "JSImmediate.h"
30#include "collector.h"
31#include "ustring.h"
32#include <stddef.h> // for size_t
33
34namespace KJS {
35
36class ExecState;
37class Identifier;
38class JSCell;
39class JSObject;
40class JSString;
41class PropertySlot;
42
43struct ClassInfo;
44struct Instruction;
45
46/**
47 * JSValue is the base type for all primitives (Undefined, Null, Boolean,
48 * String, Number) and objects in ECMAScript.
49 *
50 * Note: you should never inherit from JSValue as it is for primitive types
51 * only (all of which are provided internally by KJS). Instead, inherit from
52 * JSObject.
53 */
54class JSValue : Noncopyable {
55 friend class JSCell; // so it can derive from this class
56 friend class Heap; // so it can call asCell()
57private:
58 JSValue();
59 virtual ~JSValue();
60
61public:
62 // Querying the type.
63 JSType type() const;
64 bool isUndefined() const;
65 bool isNull() const;
66 bool isUndefinedOrNull() const;
67 bool isBoolean() const;
68 bool isNumber() const;
69 bool isString() const;
70 bool isObject() const;
71 bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
72
73 // Extracting the value.
74 bool getBoolean(bool&) const;
75 bool getBoolean() const; // false if not a boolean
76 bool getNumber(double&) const;
77 double getNumber() const; // NaN if not a number
78 double uncheckedGetNumber() const;
79 bool getString(UString&) const;
80 UString getString() const; // null string if not a string
81 JSObject* getObject(); // NULL if not an object
82 const JSObject* getObject() const; // NULL if not an object
83
84 CallType getCallData(CallData&);
85 ConstructType getConstructData(ConstructData&);
86
87 // Extracting integer values.
88 bool getUInt32(uint32_t&) const;
89 bool getTruncatedInt32(int32_t&) const;
90 bool getTruncatedUInt32(uint32_t&) const;
91
92 // Basic conversions.
93 JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;
94 bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
95
96 bool toBoolean(ExecState*) const;
97
98 // toNumber conversion is expected to be side effect free if an exception has
99 // been set in the ExecState already.
100 double toNumber(ExecState*) const;
101 JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
102 UString toString(ExecState*) const;
103 JSObject* toObject(ExecState*) const;
104
105 // Integer conversions.
106 double toInteger(ExecState*) const;
107 double toIntegerPreserveNaN(ExecState*) const;
108 int32_t toInt32(ExecState*) const;
109 int32_t toInt32(ExecState*, bool& ok) const;
110 uint32_t toUInt32(ExecState*) const;
111 uint32_t toUInt32(ExecState*, bool& ok) const;
112
113 // These are identical logic to above, and faster than jsNumber(number)->toInt32(exec)
114 static int32_t toInt32(double);
115 static int32_t toUInt32(double);
116
117 // Floating point conversions.
118 float toFloat(ExecState*) const;
119
120 // Garbage collection.
121 void mark();
122 bool marked() const;
123
124 static int32_t toInt32SlowCase(double, bool& ok);
125 static uint32_t toUInt32SlowCase(double, bool& ok);
126
127 // Object operations, with the toObject operation included.
128 JSValue* get(ExecState*, const Identifier& propertyName) const;
129 JSValue* get(ExecState*, unsigned propertyName) const;
130 void put(ExecState*, const Identifier& propertyName, JSValue*);
131 void put(ExecState*, unsigned propertyName, JSValue*);
132 bool deleteProperty(ExecState*, const Identifier& propertyName);
133 bool deleteProperty(ExecState*, unsigned propertyName);
134
135 JSObject* toThisObject(ExecState*) const;
136 UString toThisString(ExecState*) const;
137 JSString* toThisJSString(ExecState*);
138
139 JSValue* getJSNumber(); // 0 if this is not a JSNumber or number object
140
141private:
142 bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
143 bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
144 int32_t toInt32SlowCase(ExecState*, bool& ok) const;
145 uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
146
147 // Implementation details.
148 JSCell* asCell();
149 const JSCell* asCell() const;
150};
151
152class JSCell : public JSValue {
153 friend class Heap;
154 friend class GetterSetter;
155 friend class JSObject;
156 friend class JSPropertyNameIterator;
157 friend class JSValue;
158 friend class JSNumberCell;
159 friend class JSString;
160private:
161 JSCell();
162 virtual ~JSCell();
163
164public:
165 // Querying the type.
166 virtual JSType type() const = 0;
167 bool isNumber() const;
168 bool isString() const;
169 bool isObject() const;
170 bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
171
172 // Extracting the value.
173 bool getNumber(double&) const;
174 double getNumber() const; // NaN if not a number
175 bool getString(UString&) const;
176 UString getString() const; // null string if not a string
177 JSObject* getObject(); // NULL if not an object
178 const JSObject* getObject() const; // NULL if not an object
179
180 virtual CallType getCallData(CallData&);
181 virtual ConstructType getConstructData(ConstructData&);
182
183 // Extracting integer values.
184 virtual bool getUInt32(uint32_t&) const;
185 virtual bool getTruncatedInt32(int32_t&) const;
186 virtual bool getTruncatedUInt32(uint32_t&) const;
187
188 // Basic conversions.
189 virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const = 0;
190 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0;
191 virtual bool toBoolean(ExecState*) const = 0;
192 virtual double toNumber(ExecState*) const = 0;
193 virtual UString toString(ExecState*) const = 0;
194 virtual JSObject* toObject(ExecState*) const = 0;
195
196 // Garbage collection.
197 void* operator new(size_t, ExecState*);
198 virtual void mark();
199 bool marked() const;
200
201 // Object operations, with the toObject operation included.
202 virtual const ClassInfo* classInfo() const;
203 virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
204 virtual void put(ExecState*, unsigned propertyName, JSValue*);
205 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
206 virtual bool deleteProperty(ExecState*, unsigned propertyName);
207
208 virtual JSObject* toThisObject(ExecState*) const;
209 virtual UString toThisString(ExecState*) const;
210 virtual JSString* toThisJSString(ExecState*);
211 virtual JSValue* getJSNumber();
212
213private:
214 // Base implementation, but for non-object classes implements getPropertySlot.
215 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
216 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
217};
218
219class JSNumberCell : public JSCell {
220 friend JSValue* jsNumberCell(ExecState*, double);
221public:
222 double value() const { return val; }
223
224 virtual JSType type() const;
225
226 virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
227 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
228 virtual bool toBoolean(ExecState*) const;
229 virtual double toNumber(ExecState*) const;
230 virtual UString toString(ExecState*) const;
231 virtual JSObject* toObject(ExecState*) const;
232
233 virtual UString toThisString(ExecState*) const;
234 virtual JSObject* toThisObject(ExecState*) const;
235 virtual JSValue* getJSNumber();
236
237 void* operator new(size_t size, ExecState* exec)
238 {
239#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
240 return exec->heap()->inlineAllocateNumber(size);
241#else
242 return exec->heap()->allocateNumber(size);
243#endif
244 }
245
246private:
247 JSNumberCell(double v)
248 : val(v)
249 {
250 }
251
252 virtual bool getUInt32(uint32_t&) const;
253 virtual bool getTruncatedInt32(int32_t&) const;
254 virtual bool getTruncatedUInt32(uint32_t&) const;
255
256 double val;
257};
258
259JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string
260JSString* jsString(ExecState*, const char* = ""); // returns empty string if passed 0
261
262// should be used for strings that are owned by an object that will
263// likely outlive the JSValue this makes, such as the parse tree or a
264// DOM object that contains a UString
265JSString* jsOwnedString(ExecState*, const UString&);
266
267extern const double NaN;
268extern const double Inf;
269
270// Beware marking this function ALWAYS_INLINE: It takes a PIC branch, so
271// inlining it may not always be a win.
272inline JSValue* jsNumberCell(ExecState* exec, double d)
273{
274 return new (exec) JSNumberCell(d);
275}
276
277inline JSValue* jsNaN(ExecState* exec)
278{
279 return jsNumberCell(exec, NaN);
280}
281
282ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
283{
284 JSValue* v = JSImmediate::from(d);
285 return v ? v : jsNumberCell(exec, d);
286}
287
288ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
289{
290 JSValue* v = JSImmediate::from(i);
291 return v ? v : jsNumberCell(exec, i);
292}
293
294ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
295{
296 JSValue* v = JSImmediate::from(i);
297 return v ? v : jsNumberCell(exec, i);
298}
299
300ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
301{
302 JSValue* v = JSImmediate::from(i);
303 return v ? v : jsNumberCell(exec, i);
304}
305
306ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
307{
308 JSValue* v = JSImmediate::from(i);
309 return v ? v : jsNumberCell(exec, i);
310}
311
312ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
313{
314 JSValue* v = JSImmediate::from(i);
315 return v ? v : jsNumberCell(exec, static_cast<double>(i));
316}
317
318ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
319{
320 JSValue* v = JSImmediate::from(i);
321 return v ? v : jsNumberCell(exec, static_cast<double>(i));
322}
323
324inline JSValue::JSValue()
325{
326}
327
328inline JSValue::~JSValue()
329{
330}
331
332inline JSCell::JSCell()
333{
334}
335
336inline JSCell::~JSCell()
337{
338}
339
340inline bool JSCell::isNumber() const
341{
342 return type() == NumberType;
343}
344
345inline bool JSCell::isString() const
346{
347 return type() == StringType;
348}
349
350inline bool JSCell::isObject() const
351{
352 return type() == ObjectType;
353}
354
355inline bool JSCell::marked() const
356{
357 return Heap::isCellMarked(this);
358}
359
360inline void JSCell::mark()
361{
362 return Heap::markCell(this);
363}
364
365ALWAYS_INLINE JSCell* JSValue::asCell()
366{
367 ASSERT(!JSImmediate::isImmediate(this));
368 return static_cast<JSCell*>(this);
369}
370
371ALWAYS_INLINE const JSCell* JSValue::asCell() const
372{
373 ASSERT(!JSImmediate::isImmediate(this));
374 return static_cast<const JSCell*>(this);
375}
376
377inline bool JSValue::isUndefined() const
378{
379 return this == jsUndefined();
380}
381
382inline bool JSValue::isNull() const
383{
384 return this == jsNull();
385}
386
387inline bool JSValue::isUndefinedOrNull() const
388{
389 return JSImmediate::isUndefinedOrNull(this);
390}
391
392inline bool JSValue::isBoolean() const
393{
394 return JSImmediate::isBoolean(this);
395}
396
397inline bool JSValue::isNumber() const
398{
399 return JSImmediate::isNumber(this) || (!JSImmediate::isImmediate(this) && asCell()->isNumber());
400}
401
402inline bool JSValue::isString() const
403{
404 return !JSImmediate::isImmediate(this) && asCell()->isString();
405}
406
407inline bool JSValue::isObject() const
408{
409 return !JSImmediate::isImmediate(this) && asCell()->isObject();
410}
411
412inline bool JSValue::getBoolean(bool& v) const
413{
414 if (JSImmediate::isBoolean(this)) {
415 v = JSImmediate::toBoolean(this);
416 return true;
417 }
418
419 return false;
420}
421
422inline bool JSValue::getBoolean() const
423{
424 return JSImmediate::isBoolean(this) ? JSImmediate::toBoolean(this) : false;
425}
426
427inline bool JSValue::getNumber(double& v) const
428{
429 if (JSImmediate::isImmediate(this)) {
430 v = JSImmediate::toDouble(this);
431 return true;
432 }
433 return asCell()->getNumber(v);
434}
435
436inline double JSValue::getNumber() const
437{
438 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber();
439}
440
441inline double JSValue::uncheckedGetNumber() const
442{
443 ASSERT(JSImmediate::isImmediate(this) || asCell()->isNumber());
444 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : static_cast<const JSNumberCell*>(this)->value();
445}
446
447inline bool JSValue::getString(UString& s) const
448{
449 return !JSImmediate::isImmediate(this) && asCell()->getString(s);
450}
451
452inline UString JSValue::getString() const
453{
454 return JSImmediate::isImmediate(this) ? UString() : asCell()->getString();
455}
456
457inline JSObject *JSValue::getObject()
458{
459 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();
460}
461
462inline const JSObject *JSValue::getObject() const
463{
464 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();
465}
466
467inline CallType JSValue::getCallData(CallData& callData)
468{
469 return JSImmediate::isImmediate(this) ? CallTypeNone : asCell()->getCallData(callData);
470}
471
472inline ConstructType JSValue::getConstructData(ConstructData& constructData)
473{
474 return JSImmediate::isImmediate(this) ? ConstructTypeNone : asCell()->getConstructData(constructData);
475}
476
477ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
478{
479 return JSImmediate::isImmediate(this) ? JSImmediate::getUInt32(this, v) : asCell()->getUInt32(v);
480}
481
482ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const
483{
484 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedInt32(this, v) : asCell()->getTruncatedInt32(v);
485}
486
487inline bool JSValue::getTruncatedUInt32(uint32_t& v) const
488{
489 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedUInt32(this, v) : asCell()->getTruncatedUInt32(v);
490}
491
492inline void JSValue::mark()
493{
494 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark()
495 asCell()->mark();
496}
497
498inline bool JSValue::marked() const
499{
500 return JSImmediate::isImmediate(this) || asCell()->marked();
501}
502
503inline JSType JSValue::type() const
504{
505 return JSImmediate::isImmediate(this) ? JSImmediate::type(this) : asCell()->type();
506}
507
508inline JSValue* JSValue::toPrimitive(ExecState* exec, JSType preferredType) const
509{
510 return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);
511}
512
513inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)
514{
515 if (JSImmediate::isImmediate(this)) {
516 number = JSImmediate::toDouble(this);
517 value = this;
518 return true;
519 }
520 return asCell()->getPrimitiveNumber(exec, number, value);
521}
522
523inline bool JSValue::toBoolean(ExecState *exec) const
524{
525 return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean(exec);
526}
527
528ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const
529{
530 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->toNumber(exec);
531}
532
533ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
534{
535 return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(exec, this->toNumber(exec));
536}
537
538inline UString JSValue::toString(ExecState *exec) const
539{
540 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toString(exec);
541}
542
543inline JSObject* JSValue::toObject(ExecState* exec) const
544{
545 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : asCell()->toObject(exec);
546}
547
548ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
549{
550 int32_t i;
551 if (getTruncatedInt32(i))
552 return i;
553 bool ok;
554 return toInt32SlowCase(exec, ok);
555}
556
557inline uint32_t JSValue::toUInt32(ExecState* exec) const
558{
559 uint32_t i;
560 if (getTruncatedUInt32(i))
561 return i;
562 bool ok;
563 return toUInt32SlowCase(exec, ok);
564}
565
566inline int32_t JSValue::toInt32(double val)
567{
568 if (!(val >= -2147483648.0 && val < 2147483648.0)) {
569 bool ignored;
570 return toInt32SlowCase(val, ignored);
571 }
572 return static_cast<int32_t>(val);
573}
574
575inline int32_t JSValue::toUInt32(double val)
576{
577 if (!(val >= 0.0 && val < 4294967296.0)) {
578 bool ignored;
579 return toUInt32SlowCase(val, ignored);
580 }
581 return static_cast<uint32_t>(val);
582}
583
584inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
585{
586 int32_t i;
587 if (getTruncatedInt32(i)) {
588 ok = true;
589 return i;
590 }
591 return toInt32SlowCase(exec, ok);
592}
593
594inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
595{
596 uint32_t i;
597 if (getTruncatedUInt32(i)) {
598 ok = true;
599 return i;
600 }
601 return toUInt32SlowCase(exec, ok);
602}
603
604inline JSObject* JSValue::toThisObject(ExecState* exec) const
605{
606 if (UNLIKELY(JSImmediate::isImmediate(this)))
607 return JSImmediate::toObject(this, exec);
608 return asCell()->toThisObject(exec);
609}
610
611inline UString JSValue::toThisString(ExecState* exec) const
612{
613 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toThisString(exec);
614}
615
616inline JSString* JSValue::toThisJSString(ExecState* exec)
617{
618 return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec);
619}
620
621inline JSValue* JSValue::getJSNumber()
622{
623 return JSImmediate::isNumber(this) ? this : (JSImmediate::isImmediate(this) ? 0 : asCell()->getJSNumber());
624}
625
626} // namespace KJS
627
628#endif // JSValue_h
Note: See TracBrowser for help on using the repository browser.