Changeset 34921 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Jul 1, 2008, 10:32:44 AM (17 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 7 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/AllInOneFile.cpp
r34897 r34921 91 91 #include "ustring.cpp" 92 92 #include "JSValue.cpp" 93 #include "JSCell.cpp" 93 94 #include "JSVariableObject.cpp" 94 95 #include "wtf/FastMalloc.cpp" -
trunk/JavaScriptCore/kjs/JSCell.cpp
r34892 r34921 22 22 23 23 #include "config.h" 24 #include "JS Value.h"24 #include "JSCell.h" 25 25 26 26 #include "JSFunction.h" 27 #include "nodes.h" 28 #include <stdio.h> 29 #include <string.h> 27 #include "JSString.h" 28 #include "JSObject.h" 30 29 #include <wtf/MathExtras.h> 31 30 … … 78 77 #endif // !(defined NAN && defined INFINITY) 79 78 80 static const double D16 = 65536.0;81 static const double D32 = 4294967296.0;82 83 79 void* JSCell::operator new(size_t size, ExecState* exec) 84 80 { … … 103 99 { 104 100 return false; 105 }106 107 // ECMA 9.4108 double JSValue::toInteger(ExecState* exec) const109 {110 int32_t i;111 if (getTruncatedInt32(i))112 return i;113 double d = toNumber(exec);114 return isnan(d) ? 0.0 : trunc(d);115 }116 117 double JSValue::toIntegerPreserveNaN(ExecState* exec) const118 {119 int32_t i;120 if (getTruncatedInt32(i))121 return i;122 return trunc(toNumber(exec));123 }124 125 int32_t JSValue::toInt32SlowCase(double d, bool& ok)126 {127 ok = true;128 129 if (d >= -D32 / 2 && d < D32 / 2)130 return static_cast<int32_t>(d);131 132 if (isnan(d) || isinf(d)) {133 ok = false;134 return 0;135 }136 137 double d32 = fmod(trunc(d), D32);138 if (d32 >= D32 / 2)139 d32 -= D32;140 else if (d32 < -D32 / 2)141 d32 += D32;142 return static_cast<int32_t>(d32);143 }144 145 int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const146 {147 return JSValue::toInt32SlowCase(toNumber(exec), ok);148 }149 150 uint32_t JSValue::toUInt32SlowCase(double d, bool& ok)151 {152 ok = true;153 154 if (d >= 0.0 && d < D32)155 return static_cast<uint32_t>(d);156 157 if (isnan(d) || isinf(d)) {158 ok = false;159 return 0;160 }161 162 double d32 = fmod(trunc(d), D32);163 if (d32 < 0)164 d32 += D32;165 return static_cast<uint32_t>(d32);166 }167 168 uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const169 {170 return JSValue::toUInt32SlowCase(toNumber(exec), ok);171 }172 173 float JSValue::toFloat(ExecState* exec) const174 {175 return static_cast<float>(toNumber(exec));176 101 } 177 102 … … 291 216 } 292 217 293 JSString* jsString(ExecState* exec, const char* s)294 {295 return new (exec) JSString(s ? s : "");296 }297 298 JSString* jsString(ExecState* exec, const UString& s)299 {300 return s.isNull() ? new (exec) JSString("") : new (exec) JSString(s);301 }302 303 JSString* jsOwnedString(ExecState* exec, const UString& s)304 {305 return s.isNull() ? new (exec) JSString("", JSString::HasOtherOwner) : new (exec) JSString(s, JSString::HasOtherOwner);306 }307 308 JSValue* call(ExecState* exec, JSValue* functionObject, CallType callType, const CallData& callData, JSValue* thisValue, const ArgList& args)309 {310 if (callType == CallTypeNative)311 return callData.native.function(exec, static_cast<JSObject*>(functionObject), thisValue, args);312 ASSERT(callType == CallTypeJS);313 // FIXME: Can this be done more efficiently using the callData?314 return static_cast<JSFunction*>(functionObject)->call(exec, thisValue, args);315 }316 317 JSObject* construct(ExecState* exec, JSValue* object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)318 {319 if (constructType == ConstructTypeNative)320 return constructData.native.function(exec, static_cast<JSObject*>(object), args);321 ASSERT(constructType == ConstructTypeJS);322 // FIXME: Can this be done more efficiently using the constructData?323 return static_cast<JSFunction*>(object)->construct(exec, args);324 }325 326 218 } // namespace KJS -
trunk/JavaScriptCore/kjs/JSCell.h
r34892 r34921 21 21 */ 22 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" 23 #ifndef JSCell_h 24 #define JSCell_h 25 26 #include "JSValue.h" 30 27 #include "collector.h" 31 #include "ustring.h"32 #include <stddef.h> // for size_t33 28 34 29 namespace KJS { 35 36 class ExecState;37 class Identifier;38 class JSCell;39 class JSObject;40 class JSString;41 class PropertySlot;42 43 struct ClassInfo;44 struct 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 types51 * only (all of which are provided internally by KJS). Instead, inherit from52 * JSObject.53 */54 class JSValue : Noncopyable {55 friend class JSCell; // so it can derive from this class56 friend class Heap; // so it can call asCell()57 private:58 JSValue();59 virtual ~JSValue();60 61 public: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 boolean76 bool getNumber(double&) const;77 double getNumber() const; // NaN if not a number78 double uncheckedGetNumber() const;79 bool getString(UString&) const;80 UString getString() const; // null string if not a string81 JSObject* getObject(); // NULL if not an object82 const JSObject* getObject() const; // NULL if not an object83 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 has99 // 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 object140 141 private: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 30 152 31 class JSCell : public JSValue { … … 217 96 }; 218 97 219 class JSNumberCell : public JSCell {220 friend JSValue* jsNumberCell(ExecState*, double);221 public: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_FILE240 return exec->heap()->inlineAllocateNumber(size);241 #else242 return exec->heap()->allocateNumber(size);243 #endif244 }245 246 private: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 259 JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string260 JSString* jsString(ExecState*, const char* = ""); // returns empty string if passed 0261 262 // should be used for strings that are owned by an object that will263 // likely outlive the JSValue this makes, such as the parse tree or a264 // DOM object that contains a UString265 JSString* jsOwnedString(ExecState*, const UString&);266 267 extern const double NaN;268 extern const double Inf;269 270 // Beware marking this function ALWAYS_INLINE: It takes a PIC branch, so271 // inlining it may not always be a win.272 inline JSValue* jsNumberCell(ExecState* exec, double d)273 {274 return new (exec) JSNumberCell(d);275 }276 277 inline JSValue* jsNaN(ExecState* exec)278 {279 return jsNumberCell(exec, NaN);280 }281 282 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)283 {284 JSValue* v = JSImmediate::from(d);285 return v ? v : jsNumberCell(exec, d);286 }287 288 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)289 {290 JSValue* v = JSImmediate::from(i);291 return v ? v : jsNumberCell(exec, i);292 }293 294 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)295 {296 JSValue* v = JSImmediate::from(i);297 return v ? v : jsNumberCell(exec, i);298 }299 300 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)301 {302 JSValue* v = JSImmediate::from(i);303 return v ? v : jsNumberCell(exec, i);304 }305 306 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)307 {308 JSValue* v = JSImmediate::from(i);309 return v ? v : jsNumberCell(exec, i);310 }311 312 ALWAYS_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 318 ALWAYS_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 324 inline JSValue::JSValue()325 {326 }327 328 inline JSValue::~JSValue()329 {330 }331 332 98 inline JSCell::JSCell() 333 99 { … … 375 141 } 376 142 377 inline bool JSValue::isUndefined() const 378 { 379 return this == jsUndefined(); 380 } 381 382 inline bool JSValue::isNull() const 383 { 384 return this == jsNull(); 385 } 386 387 inline bool JSValue::isUndefinedOrNull() const 388 { 389 return JSImmediate::isUndefinedOrNull(this); 390 } 391 392 inline bool JSValue::isBoolean() const 393 { 394 return JSImmediate::isBoolean(this); 395 } 143 144 // --- JSValue inlines ---------------------------- 396 145 397 146 inline bool JSValue::isNumber() const … … 408 157 { 409 158 return !JSImmediate::isImmediate(this) && asCell()->isObject(); 410 }411 412 inline bool JSValue::getBoolean(bool& v) const413 {414 if (JSImmediate::isBoolean(this)) {415 v = JSImmediate::toBoolean(this);416 return true;417 }418 419 return false;420 }421 422 inline bool JSValue::getBoolean() const423 {424 return JSImmediate::isBoolean(this) ? JSImmediate::toBoolean(this) : false;425 159 } 426 160 … … 437 171 { 438 172 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber(); 439 }440 441 inline double JSValue::uncheckedGetNumber() const442 {443 ASSERT(JSImmediate::isImmediate(this) || asCell()->isNumber());444 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : static_cast<const JSNumberCell*>(this)->value();445 173 } 446 174 … … 531 259 } 532 260 533 ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const534 {535 return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(exec, this->toNumber(exec));536 }537 538 261 inline UString JSValue::toString(ExecState *exec) const 539 262 { … … 544 267 { 545 268 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : asCell()->toObject(exec); 546 }547 548 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const549 {550 int32_t i;551 if (getTruncatedInt32(i))552 return i;553 bool ok;554 return toInt32SlowCase(exec, ok);555 }556 557 inline uint32_t JSValue::toUInt32(ExecState* exec) const558 {559 uint32_t i;560 if (getTruncatedUInt32(i))561 return i;562 bool ok;563 return toUInt32SlowCase(exec, ok);564 }565 566 inline 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 575 inline 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 584 inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const585 {586 int32_t i;587 if (getTruncatedInt32(i)) {588 ok = true;589 return i;590 }591 return toInt32SlowCase(exec, ok);592 }593 594 inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const595 {596 uint32_t i;597 if (getTruncatedUInt32(i)) {598 ok = true;599 return i;600 }601 return toUInt32SlowCase(exec, ok);602 269 } 603 270 … … 614 281 } 615 282 616 inline JSString* JSValue::toThisJSString(ExecState* exec)617 {618 return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec);619 }620 621 283 inline JSValue* JSValue::getJSNumber() 622 284 { 285 623 286 return JSImmediate::isNumber(this) ? this : (JSImmediate::isImmediate(this) ? 0 : asCell()->getJSNumber()); 624 287 } … … 626 289 } // namespace KJS 627 290 628 #endif // JS Value_h291 #endif // JSCell_h -
trunk/JavaScriptCore/kjs/JSNumberCell.cpp
r34893 r34921 22 22 23 23 #include "config.h" 24 #include "JS Value.h"24 #include "JSNumberCell.h" 25 25 26 26 #include "JSType.h" -
trunk/JavaScriptCore/kjs/JSNumberCell.h
r34892 r34921 21 21 */ 22 22 23 #ifndef JS Value_h24 #define JS Value_h23 #ifndef JSNumberCell_h 24 #define JSNumberCell_h 25 25 26 26 #include "CallData.h" 27 27 #include "ConstructData.h" 28 28 #include "ExecState.h" 29 #include "JSCell.h" 29 30 #include "JSImmediate.h" 30 31 #include "collector.h" … … 43 44 struct ClassInfo; 44 45 struct 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 types51 * only (all of which are provided internally by KJS). Instead, inherit from52 * JSObject.53 */54 class JSValue : Noncopyable {55 friend class JSCell; // so it can derive from this class56 friend class Heap; // so it can call asCell()57 private:58 JSValue();59 virtual ~JSValue();60 61 public: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 boolean76 bool getNumber(double&) const;77 double getNumber() const; // NaN if not a number78 double uncheckedGetNumber() const;79 bool getString(UString&) const;80 UString getString() const; // null string if not a string81 JSObject* getObject(); // NULL if not an object82 const JSObject* getObject() const; // NULL if not an object83 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 has99 // 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 object140 141 private: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 152 class 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;160 private:161 JSCell();162 virtual ~JSCell();163 164 public: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 number175 bool getString(UString&) const;176 UString getString() const; // null string if not a string177 JSObject* getObject(); // NULL if not an object178 const JSObject* getObject() const; // NULL if not an object179 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 213 private: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 46 219 47 class JSNumberCell : public JSCell { … … 256 84 double val; 257 85 }; 258 259 JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string260 JSString* jsString(ExecState*, const char* = ""); // returns empty string if passed 0261 262 // should be used for strings that are owned by an object that will263 // likely outlive the JSValue this makes, such as the parse tree or a264 // DOM object that contains a UString265 JSString* jsOwnedString(ExecState*, const UString&);266 86 267 87 extern const double NaN; … … 322 142 } 323 143 324 inline JSValue::JSValue() 325 { 326 } 327 328 inline JSValue::~JSValue() 329 { 330 } 331 332 inline JSCell::JSCell() 333 { 334 } 335 336 inline JSCell::~JSCell() 337 { 338 } 339 340 inline bool JSCell::isNumber() const 341 { 342 return type() == NumberType; 343 } 344 345 inline bool JSCell::isString() const 346 { 347 return type() == StringType; 348 } 349 350 inline bool JSCell::isObject() const 351 { 352 return type() == ObjectType; 353 } 354 355 inline bool JSCell::marked() const 356 { 357 return Heap::isCellMarked(this); 358 } 359 360 inline void JSCell::mark() 361 { 362 return Heap::markCell(this); 363 } 364 365 ALWAYS_INLINE JSCell* JSValue::asCell() 366 { 367 ASSERT(!JSImmediate::isImmediate(this)); 368 return static_cast<JSCell*>(this); 369 } 370 371 ALWAYS_INLINE const JSCell* JSValue::asCell() const 372 { 373 ASSERT(!JSImmediate::isImmediate(this)); 374 return static_cast<const JSCell*>(this); 375 } 376 377 inline bool JSValue::isUndefined() const 378 { 379 return this == jsUndefined(); 380 } 381 382 inline bool JSValue::isNull() const 383 { 384 return this == jsNull(); 385 } 386 387 inline bool JSValue::isUndefinedOrNull() const 388 { 389 return JSImmediate::isUndefinedOrNull(this); 390 } 391 392 inline bool JSValue::isBoolean() const 393 { 394 return JSImmediate::isBoolean(this); 395 } 396 397 inline bool JSValue::isNumber() const 398 { 399 return JSImmediate::isNumber(this) || (!JSImmediate::isImmediate(this) && asCell()->isNumber()); 400 } 401 402 inline bool JSValue::isString() const 403 { 404 return !JSImmediate::isImmediate(this) && asCell()->isString(); 405 } 406 407 inline bool JSValue::isObject() const 408 { 409 return !JSImmediate::isImmediate(this) && asCell()->isObject(); 410 } 411 412 inline 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 422 inline bool JSValue::getBoolean() const 423 { 424 return JSImmediate::isBoolean(this) ? JSImmediate::toBoolean(this) : false; 425 } 426 427 inline 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 436 inline double JSValue::getNumber() const 437 { 438 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber(); 439 } 144 // --- JSValue inlines ---------------------------- 440 145 441 146 inline double JSValue::uncheckedGetNumber() const … … 445 150 } 446 151 447 inline bool JSValue::getString(UString& s) const448 {449 return !JSImmediate::isImmediate(this) && asCell()->getString(s);450 }451 452 inline UString JSValue::getString() const453 {454 return JSImmediate::isImmediate(this) ? UString() : asCell()->getString();455 }456 457 inline JSObject *JSValue::getObject()458 {459 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();460 }461 462 inline const JSObject *JSValue::getObject() const463 {464 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();465 }466 467 inline CallType JSValue::getCallData(CallData& callData)468 {469 return JSImmediate::isImmediate(this) ? CallTypeNone : asCell()->getCallData(callData);470 }471 472 inline ConstructType JSValue::getConstructData(ConstructData& constructData)473 {474 return JSImmediate::isImmediate(this) ? ConstructTypeNone : asCell()->getConstructData(constructData);475 }476 477 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const478 {479 return JSImmediate::isImmediate(this) ? JSImmediate::getUInt32(this, v) : asCell()->getUInt32(v);480 }481 482 ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const483 {484 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedInt32(this, v) : asCell()->getTruncatedInt32(v);485 }486 487 inline bool JSValue::getTruncatedUInt32(uint32_t& v) const488 {489 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedUInt32(this, v) : asCell()->getTruncatedUInt32(v);490 }491 492 inline void JSValue::mark()493 {494 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark()495 asCell()->mark();496 }497 498 inline bool JSValue::marked() const499 {500 return JSImmediate::isImmediate(this) || asCell()->marked();501 }502 503 inline JSType JSValue::type() const504 {505 return JSImmediate::isImmediate(this) ? JSImmediate::type(this) : asCell()->type();506 }507 508 inline JSValue* JSValue::toPrimitive(ExecState* exec, JSType preferredType) const509 {510 return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);511 }512 513 inline 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 523 inline bool JSValue::toBoolean(ExecState *exec) const524 {525 return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean(exec);526 }527 528 ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const529 {530 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->toNumber(exec);531 }532 533 152 ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const 534 153 { … … 536 155 } 537 156 538 inline UString JSValue::toString(ExecState *exec) const 539 { 540 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toString(exec); 541 } 542 543 inline JSObject* JSValue::toObject(ExecState* exec) const 544 { 545 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : asCell()->toObject(exec); 546 } 547 548 ALWAYS_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 557 inline 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 566 inline 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 575 inline 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 584 inline 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 594 inline 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 604 inline 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 611 inline UString JSValue::toThisString(ExecState* exec) const 612 { 613 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toThisString(exec); 614 } 615 616 inline JSString* JSValue::toThisJSString(ExecState* exec) 617 { 618 return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec); 619 } 620 621 inline JSValue* JSValue::getJSNumber() 622 { 623 return JSImmediate::isNumber(this) ? this : (JSImmediate::isImmediate(this) ? 0 : asCell()->getJSNumber()); 624 } 157 // ------- 625 158 626 159 } // namespace KJS 627 160 628 #endif // JS Value_h161 #endif // JSNumberCell_h -
trunk/JavaScriptCore/kjs/JSObject.h
r34842 r34921 27 27 #include "CommonIdentifiers.h" 28 28 #include "ExecState.h" 29 #include "JSNumberCell.h" 29 30 #include "JSType.h" 30 #include "list.h"31 31 #include "PropertyMap.h" 32 32 #include "PropertySlot.h" 33 33 #include "ScopeChain.h" 34 #include "list.h" 34 35 35 36 namespace KJS { -
trunk/JavaScriptCore/kjs/JSString.cpp
r34893 r34921 125 125 } 126 126 127 JSString* jsString(ExecState* exec, const char* s) 128 { 129 return new (exec) JSString(s ? s : ""); 130 } 131 132 JSString* jsString(ExecState* exec, const UString& s) 133 { 134 return s.isNull() ? new (exec) JSString("") : new (exec) JSString(s); 135 } 136 137 JSString* jsOwnedString(ExecState* exec, const UString& s) 138 { 139 return s.isNull() ? new (exec) JSString("", JSString::HasOtherOwner) : new (exec) JSString(s, JSString::HasOtherOwner); 140 } 141 127 142 } // namespace KJS -
trunk/JavaScriptCore/kjs/JSString.h
r34893 r34921 26 26 27 27 #include "CommonIdentifiers.h" 28 #include "JS Value.h"28 #include "JSCell.h" 29 29 #include "PropertySlot.h" 30 30 #include "identifier.h" … … 69 69 }; 70 70 71 JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string 72 JSString* jsString(ExecState*, const char* = ""); // returns empty string if passed 0 73 74 // Should be used for strings that are owned by an object that will 75 // likely outlive the JSValue this makes, such as the parse tree or a 76 // DOM object that contains a UString 77 JSString* jsOwnedString(ExecState*, const UString&); 78 71 79 ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 72 80 { … … 96 104 } 97 105 98 } // namespace 106 // --- JSValue inlines ---------------------------- 107 108 inline JSString* JSValue::toThisJSString(ExecState* exec) 109 { 110 return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec); 111 } 112 113 } // namespace KJS 99 114 100 115 #endif // JSString_h -
trunk/JavaScriptCore/kjs/JSValue.cpp
r34878 r34921 25 25 26 26 #include "JSFunction.h" 27 #include "nodes.h"28 #include <stdio.h>29 #include <string.h>30 27 #include <wtf/MathExtras.h> 31 28 32 29 namespace KJS { 33 30 34 #if defined NAN && defined INFINITY 35 36 extern const double NaN = NAN; 37 extern const double Inf = INFINITY; 38 39 #else // !(defined NAN && defined INFINITY) 40 41 // The trick is to define the NaN and Inf globals with a different type than the declaration. 42 // This trick works because the mangled name of the globals does not include the type, although 43 // I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of 44 // characters don't necessarily need the same alignment doubles do, but for now it seems to work. 45 // It would be good to figure out a 100% clean way that still avoids code that runs at init time. 46 47 // Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere, 48 // while NaN_double has to be 4-byte aligned for 32-bits. 49 // With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading. 50 51 static const union { 52 struct { 53 unsigned char NaN_Bytes[8]; 54 unsigned char Inf_Bytes[8]; 55 } bytes; 56 57 struct { 58 double NaN_Double; 59 double Inf_Double; 60 } doubles; 61 62 } NaNInf = { { 63 #if PLATFORM(BIG_ENDIAN) 64 { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }, 65 { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } 66 #elif PLATFORM(MIDDLE_ENDIAN) 67 { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }, 68 { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } 69 #else 70 { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }, 71 { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } 72 #endif 73 } } ; 74 75 extern const double NaN = NaNInf.doubles.NaN_Double; 76 extern const double Inf = NaNInf.doubles.Inf_Double; 77 78 #endif // !(defined NAN && defined INFINITY) 79 80 static const double D16 = 65536.0; 31 static const double D16 = 65536.0; // FIXME: This seems to be unused. 81 32 static const double D32 = 4294967296.0; 82 83 void* JSCell::operator new(size_t size, ExecState* exec)84 {85 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE86 return exec->heap()->inlineAllocate(size);87 #else88 return exec->heap()->allocate(size);89 #endif90 }91 92 bool JSCell::getUInt32(uint32_t&) const93 {94 return false;95 }96 97 bool JSCell::getTruncatedInt32(int32_t&) const98 {99 return false;100 }101 102 bool JSCell::getTruncatedUInt32(uint32_t&) const103 {104 return false;105 }106 33 107 34 // ECMA 9.4 … … 176 103 } 177 104 178 bool JSCell::getNumber(double& numericValue) const 179 { 180 if (!isNumber()) 181 return false; 182 numericValue = static_cast<const JSNumberCell*>(this)->value(); 183 return true; 184 } 185 186 double JSCell::getNumber() const 187 { 188 return isNumber() ? static_cast<const JSNumberCell*>(this)->value() : NaN; 189 } 190 191 bool JSCell::getString(UString&stringValue) const 192 { 193 if (!isString()) 194 return false; 195 stringValue = static_cast<const JSString*>(this)->value(); 196 return true; 197 } 198 199 UString JSCell::getString() const 200 { 201 return isString() ? static_cast<const JSString*>(this)->value() : UString(); 202 } 203 204 JSObject* JSCell::getObject() 205 { 206 return isObject() ? static_cast<JSObject*>(this) : 0; 207 } 208 209 const JSObject* JSCell::getObject() const 210 { 211 return isObject() ? static_cast<const JSObject*>(this) : 0; 212 } 213 214 CallType JSCell::getCallData(CallData&) 215 { 216 return CallTypeNone; 217 } 218 219 ConstructType JSCell::getConstructData(ConstructData&) 220 { 221 return ConstructTypeNone; 222 } 223 224 bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot) 225 { 226 // This is not a general purpose implementation of getOwnPropertySlot. 227 // It should only be called by JSValue::get. 228 // It calls getPropertySlot, not getOwnPropertySlot. 229 JSObject* object = toObject(exec); 230 slot.setBase(object); 231 if (!object->getPropertySlot(exec, identifier, slot)) 232 slot.setUndefined(); 233 return true; 234 } 235 236 bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot) 237 { 238 // This is not a general purpose implementation of getOwnPropertySlot. 239 // It should only be called by JSValue::get. 240 // It calls getPropertySlot, not getOwnPropertySlot. 241 JSObject* object = toObject(exec); 242 slot.setBase(object); 243 if (!object->getPropertySlot(exec, identifier, slot)) 244 slot.setUndefined(); 245 return true; 246 } 247 248 void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value) 249 { 250 toObject(exec)->put(exec, identifier, value); 251 } 252 253 void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value) 254 { 255 toObject(exec)->put(exec, identifier, value); 256 } 257 258 bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier) 259 { 260 return toObject(exec)->deleteProperty(exec, identifier); 261 } 262 263 bool JSCell::deleteProperty(ExecState* exec, unsigned identifier) 264 { 265 return toObject(exec)->deleteProperty(exec, identifier); 266 } 267 268 JSObject* JSCell::toThisObject(ExecState* exec) const 269 { 270 return toObject(exec); 271 } 272 273 UString JSCell::toThisString(ExecState* exec) const 274 { 275 return toThisObject(exec)->toString(exec); 276 } 277 278 JSString* JSCell::toThisJSString(ExecState* exec) 279 { 280 return jsString(exec, toThisString(exec)); 281 } 282 283 const ClassInfo* JSCell::classInfo() const 284 { 285 return 0; 286 } 287 288 JSValue* JSCell::getJSNumber() 289 { 290 return 0; 291 } 292 293 JSString* jsString(ExecState* exec, const char* s) 294 { 295 return new (exec) JSString(s ? s : ""); 296 } 297 298 JSString* jsString(ExecState* exec, const UString& s) 299 { 300 return s.isNull() ? new (exec) JSString("") : new (exec) JSString(s); 301 } 302 303 JSString* jsOwnedString(ExecState* exec, const UString& s) 304 { 305 return s.isNull() ? new (exec) JSString("", JSString::HasOtherOwner) : new (exec) JSString(s, JSString::HasOtherOwner); 306 } 307 105 // Declared in CallData.h 308 106 JSValue* call(ExecState* exec, JSValue* functionObject, CallType callType, const CallData& callData, JSValue* thisValue, const ArgList& args) 309 107 { … … 315 113 } 316 114 115 // Declared in ConstructData.h 317 116 JSObject* construct(ExecState* exec, JSValue* object, ConstructType constructType, const ConstructData& constructData, const ArgList& args) 318 117 { -
trunk/JavaScriptCore/kjs/JSValue.h
r34821 r34921 28 28 #include "ExecState.h" 29 29 #include "JSImmediate.h" 30 #include "collector.h"31 30 #include "ustring.h" 32 31 #include <stddef.h> // for size_t … … 40 39 class JSString; 41 40 class PropertySlot; 42 43 41 struct ClassInfo; 44 42 struct Instruction; … … 150 148 }; 151 149 152 class 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;160 private:161 JSCell();162 virtual ~JSCell();163 164 public: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 number175 bool getString(UString&) const;176 UString getString() const; // null string if not a string177 JSObject* getObject(); // NULL if not an object178 const JSObject* getObject() const; // NULL if not an object179 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 213 private: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 219 class JSNumberCell : public JSCell {220 friend JSValue* jsNumberCell(ExecState*, double);221 public: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_FILE240 return exec->heap()->inlineAllocateNumber(size);241 #else242 return exec->heap()->allocateNumber(size);243 #endif244 }245 246 private: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 259 JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string260 JSString* jsString(ExecState*, const char* = ""); // returns empty string if passed 0261 262 // should be used for strings that are owned by an object that will263 // likely outlive the JSValue this makes, such as the parse tree or a264 // DOM object that contains a UString265 JSString* jsOwnedString(ExecState*, const UString&);266 267 extern const double NaN;268 extern const double Inf;269 270 // Beware marking this function ALWAYS_INLINE: It takes a PIC branch, so271 // inlining it may not always be a win.272 inline JSValue* jsNumberCell(ExecState* exec, double d)273 {274 return new (exec) JSNumberCell(d);275 }276 277 inline JSValue* jsNaN(ExecState* exec)278 {279 return jsNumberCell(exec, NaN);280 }281 282 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)283 {284 JSValue* v = JSImmediate::from(d);285 return v ? v : jsNumberCell(exec, d);286 }287 288 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)289 {290 JSValue* v = JSImmediate::from(i);291 return v ? v : jsNumberCell(exec, i);292 }293 294 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)295 {296 JSValue* v = JSImmediate::from(i);297 return v ? v : jsNumberCell(exec, i);298 }299 300 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)301 {302 JSValue* v = JSImmediate::from(i);303 return v ? v : jsNumberCell(exec, i);304 }305 306 ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)307 {308 JSValue* v = JSImmediate::from(i);309 return v ? v : jsNumberCell(exec, i);310 }311 312 ALWAYS_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 318 ALWAYS_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 324 150 inline JSValue::JSValue() 325 151 { … … 330 156 } 331 157 332 inline JSCell::JSCell()333 {334 }335 336 inline JSCell::~JSCell()337 {338 }339 340 inline bool JSCell::isNumber() const341 {342 return type() == NumberType;343 }344 345 inline bool JSCell::isString() const346 {347 return type() == StringType;348 }349 350 inline bool JSCell::isObject() const351 {352 return type() == ObjectType;353 }354 355 inline bool JSCell::marked() const356 {357 return Heap::isCellMarked(this);358 }359 360 inline void JSCell::mark()361 {362 return Heap::markCell(this);363 }364 365 ALWAYS_INLINE JSCell* JSValue::asCell()366 {367 ASSERT(!JSImmediate::isImmediate(this));368 return static_cast<JSCell*>(this);369 }370 371 ALWAYS_INLINE const JSCell* JSValue::asCell() const372 {373 ASSERT(!JSImmediate::isImmediate(this));374 return static_cast<const JSCell*>(this);375 }376 377 158 inline bool JSValue::isUndefined() const 378 159 { … … 393 174 { 394 175 return JSImmediate::isBoolean(this); 395 }396 397 inline bool JSValue::isNumber() const398 {399 return JSImmediate::isNumber(this) || (!JSImmediate::isImmediate(this) && asCell()->isNumber());400 }401 402 inline bool JSValue::isString() const403 {404 return !JSImmediate::isImmediate(this) && asCell()->isString();405 }406 407 inline bool JSValue::isObject() const408 {409 return !JSImmediate::isImmediate(this) && asCell()->isObject();410 176 } 411 177 … … 425 191 } 426 192 427 inline bool JSValue::getNumber(double& v) const428 {429 if (JSImmediate::isImmediate(this)) {430 v = JSImmediate::toDouble(this);431 return true;432 }433 return asCell()->getNumber(v);434 }435 436 inline double JSValue::getNumber() const437 {438 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber();439 }440 441 inline double JSValue::uncheckedGetNumber() const442 {443 ASSERT(JSImmediate::isImmediate(this) || asCell()->isNumber());444 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : static_cast<const JSNumberCell*>(this)->value();445 }446 447 inline bool JSValue::getString(UString& s) const448 {449 return !JSImmediate::isImmediate(this) && asCell()->getString(s);450 }451 452 inline UString JSValue::getString() const453 {454 return JSImmediate::isImmediate(this) ? UString() : asCell()->getString();455 }456 457 inline JSObject *JSValue::getObject()458 {459 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();460 }461 462 inline const JSObject *JSValue::getObject() const463 {464 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();465 }466 467 inline CallType JSValue::getCallData(CallData& callData)468 {469 return JSImmediate::isImmediate(this) ? CallTypeNone : asCell()->getCallData(callData);470 }471 472 inline ConstructType JSValue::getConstructData(ConstructData& constructData)473 {474 return JSImmediate::isImmediate(this) ? ConstructTypeNone : asCell()->getConstructData(constructData);475 }476 477 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const478 {479 return JSImmediate::isImmediate(this) ? JSImmediate::getUInt32(this, v) : asCell()->getUInt32(v);480 }481 482 ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const483 {484 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedInt32(this, v) : asCell()->getTruncatedInt32(v);485 }486 487 inline bool JSValue::getTruncatedUInt32(uint32_t& v) const488 {489 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedUInt32(this, v) : asCell()->getTruncatedUInt32(v);490 }491 492 inline void JSValue::mark()493 {494 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark()495 asCell()->mark();496 }497 498 inline bool JSValue::marked() const499 {500 return JSImmediate::isImmediate(this) || asCell()->marked();501 }502 503 inline JSType JSValue::type() const504 {505 return JSImmediate::isImmediate(this) ? JSImmediate::type(this) : asCell()->type();506 }507 508 inline JSValue* JSValue::toPrimitive(ExecState* exec, JSType preferredType) const509 {510 return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);511 }512 513 inline 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 523 inline bool JSValue::toBoolean(ExecState *exec) const524 {525 return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean(exec);526 }527 528 ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const529 {530 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->toNumber(exec);531 }532 533 ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const534 {535 return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(exec, this->toNumber(exec));536 }537 538 inline UString JSValue::toString(ExecState *exec) const539 {540 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toString(exec);541 }542 543 inline JSObject* JSValue::toObject(ExecState* exec) const544 {545 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : asCell()->toObject(exec);546 }547 548 193 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const 549 194 { … … 602 247 } 603 248 604 inline JSObject* JSValue::toThisObject(ExecState* exec) const605 {606 if (UNLIKELY(JSImmediate::isImmediate(this)))607 return JSImmediate::toObject(this, exec);608 return asCell()->toThisObject(exec);609 }610 611 inline UString JSValue::toThisString(ExecState* exec) const612 {613 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toThisString(exec);614 }615 616 inline JSString* JSValue::toThisJSString(ExecState* exec)617 {618 return JSImmediate::isImmediate(this) ? jsString(exec, JSImmediate::toString(this)) : asCell()->toThisJSString(exec);619 }620 621 inline JSValue* JSValue::getJSNumber()622 {623 return JSImmediate::isNumber(this) ? this : (JSImmediate::isImmediate(this) ? 0 : asCell()->getJSNumber());624 }625 626 249 } // namespace KJS 627 250
Note:
See TracChangeset
for help on using the changeset viewer.