Changeset 10084 in webkit for trunk/JavaScriptCore/kjs/value.cpp
- Timestamp:
- Aug 7, 2005, 9:07:46 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/value.cpp
r9768 r10084 1 // -*- c-basic-offset: 2 -*-2 1 /* 3 2 * This file is part of the KDE libraries … … 24 23 25 24 #include "value.h" 25 26 26 #include "object.h" 27 27 #include "types.h" 28 28 #include "interpreter.h" 29 29 30 #include <assert.h>31 30 #include <math.h> 32 31 #include <stdio.h> … … 38 37 #include "error_object.h" 39 38 #include "nodes.h" 40 #include "simple_number.h"41 39 42 40 namespace KJS { 43 41 44 // ----------------------------- ValueImp ------------------------------------- 45 46 void ValueImp::mark() 47 { 48 _marked = true; 49 } 50 51 void* ValueImp::operator new(size_t s) 52 { 53 return Collector::allocate(s); 54 } 55 56 void ValueImp::operator delete(void*) 57 { 58 // Do nothing. So far. 59 } 60 61 bool ValueImp::toUInt32(unsigned&) const 62 { 63 return false; 42 AllocatedValueImp *ConstantValues::undefined = NULL; 43 AllocatedValueImp *ConstantValues::null = NULL; 44 AllocatedValueImp *ConstantValues::jsTrue = NULL; 45 AllocatedValueImp *ConstantValues::jsFalse = NULL; 46 AllocatedValueImp *ConstantValues::NaN = NULL; 47 48 static const double D16 = 65536; 49 static const double D32 = 4294967296.0; 50 51 void *AllocatedValueImp::operator new(size_t size) 52 { 53 return Collector::allocate(size); 54 } 55 56 bool AllocatedValueImp::getUInt32(unsigned&) const 57 { 58 return false; 64 59 } 65 60 … … 67 62 double ValueImp::toInteger(ExecState *exec) const 68 63 { 69 uint32_t i;70 if (dispatchToUInt32(i))71 return i;72 return roundValue(exec, Value(const_cast<ValueImp*>(this)));64 uint32_t i; 65 if (getUInt32(i)) 66 return i; 67 return roundValue(exec, const_cast<ValueImp*>(this)); 73 68 } 74 69 75 70 int32_t ValueImp::toInt32(ExecState *exec) const 76 71 { 77 uint32_t i;78 if (dispatchToUInt32(i))79 return i;80 81 double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));82 if (isNaN(d) || isInf(d))83 return 0;84 double d32 = fmod(d, D32);85 86 if (d32 >= D32 / 2.0)87 d32 -= D32;88 else if (d32 < -D32 / 2.0)89 d32 += D32;90 91 return static_cast<int32_t>(d32);72 uint32_t i; 73 if (getUInt32(i)) 74 return i; 75 76 double d = roundValue(exec, const_cast<ValueImp*>(this)); 77 if (isNaN(d) || isInf(d)) 78 return 0; 79 double d32 = fmod(d, D32); 80 81 if (d32 >= D32 / 2) 82 d32 -= D32; 83 else if (d32 < -D32 / 2) 84 d32 += D32; 85 86 return static_cast<int32_t>(d32); 92 87 } 93 88 94 89 uint32_t ValueImp::toUInt32(ExecState *exec) const 95 90 { 96 uint32_t i;97 if (dispatchToUInt32(i))98 return i;99 100 double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));101 if (isNaN(d) || isInf(d))102 return 0;103 double d32 = fmod(d, D32);104 105 if (d32 < 0)106 d32 += D32;107 108 return static_cast<uint32_t>(d32);91 uint32_t i; 92 if (getUInt32(i)) 93 return i; 94 95 double d = roundValue(exec, const_cast<ValueImp*>(this)); 96 if (isNaN(d) || isInf(d)) 97 return 0; 98 double d32 = fmod(d, D32); 99 100 if (d32 < 0) 101 d32 += D32; 102 103 return static_cast<uint32_t>(d32); 109 104 } 110 105 111 106 uint16_t ValueImp::toUInt16(ExecState *exec) const 112 107 { 113 uint32_t i; 114 if (dispatchToUInt32(i)) 115 return i; 116 117 double d = roundValue(exec, Value(const_cast<ValueImp*>(this))); 118 if (isNaN(d) || isInf(d)) 119 return 0; 120 double d16 = fmod(d, D16); 121 122 if (d16 < 0) 123 d16 += D16; 124 125 return static_cast<uint16_t>(d16); 126 } 127 128 Object ValueImp::dispatchToObject(ExecState *exec) const 129 { 130 if (SimpleNumber::is(this)) 131 return static_cast<const NumberImp *>(this)->NumberImp::toObject(exec); 132 return toObject(exec); 133 } 134 135 bool ValueImp::isUndefinedOrNull() const 136 { 137 switch (dispatchType()) { 138 case BooleanType: 139 case NumberType: 140 case ObjectType: 141 case StringType: 142 break; 143 case NullType: 144 case UndefinedType: 145 return true; 146 case UnspecifiedType: 147 assert(false); 148 break; 149 } 150 return false; 151 } 152 153 bool ValueImp::isBoolean(bool &booleanValue) const 108 uint32_t i; 109 if (getUInt32(i)) 110 return i; 111 112 double d = roundValue(exec, const_cast<ValueImp*>(this)); 113 if (isNaN(d) || isInf(d)) 114 return 0; 115 double d16 = fmod(d, D16); 116 117 if (d16 < 0) 118 d16 += D16; 119 120 return static_cast<uint16_t>(d16); 121 } 122 123 ObjectImp *ValueImp::toObject(ExecState *exec) const 124 { 125 if (SimpleNumber::is(this)) 126 return static_cast<const NumberImp *>(this)->NumberImp::toObject(exec); 127 return downcast()->toObject(exec); 128 } 129 130 bool AllocatedValueImp::getBoolean(bool &booleanValue) const 154 131 { 155 132 if (!isBoolean()) … … 159 136 } 160 137 161 bool ValueImp::isNumber(double &numericValue) const138 bool AllocatedValueImp::getNumber(double &numericValue) const 162 139 { 163 140 if (!isNumber()) … … 167 144 } 168 145 169 bool ValueImp::isString(UString &stringValue) const 146 double AllocatedValueImp::getNumber() const 147 { 148 return isNumber() ? static_cast<const NumberImp *>(this)->value() : NaN; 149 } 150 151 bool AllocatedValueImp::getString(UString &stringValue) const 170 152 { 171 153 if (!isString()) … … 175 157 } 176 158 177 UString ValueImp::asString() const159 UString AllocatedValueImp::getString() const 178 160 { 179 161 return isString() ? static_cast<const StringImp *>(this)->value() : UString(); 180 162 } 181 163 182 bool ValueImp::isObject(ObjectImp *&object) 183 { 184 if (!isObject()) 185 return false; 186 object = static_cast<ObjectImp *>(this); 187 return true; 188 } 189 190 // ------------------------------ Value ---------------------------------------- 191 192 Value::Value(bool b) : rep(b ? BooleanImp::staticTrue : BooleanImp::staticFalse) { } 193 194 Value::Value(int i) 195 : rep(SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i))) { } 196 197 Value::Value(unsigned u) 198 : rep(SimpleNumber::fits(u) ? SimpleNumber::make(u) : new NumberImp(static_cast<double>(u))) { } 199 200 Value::Value(double d) 201 : rep(SimpleNumber::fits(d) 202 ? SimpleNumber::make(static_cast<long>(d)) 203 : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d))) 204 { } 205 206 Value::Value(double d, bool knownToBeInteger) 207 : rep((knownToBeInteger ? SimpleNumber::integerFits(d) : SimpleNumber::fits(d)) 208 ? SimpleNumber::make(static_cast<long>(d)) 209 : ((!knownToBeInteger && KJS::isNaN(d)) ? NumberImp::staticNaN : new NumberImp(d))) 210 { } 211 212 Value::Value(long l) 213 : rep(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { } 214 215 Value::Value(unsigned long l) 216 : rep(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { } 217 218 Value::Value(const char *s) : rep(new StringImp(s)) { } 219 220 Value::Value(const UString &s) : rep(new StringImp(s)) { } 221 222 // ------------------------------ Undefined ------------------------------------ 223 224 Undefined::Undefined() : Value(UndefinedImp::staticUndefined) 225 { 226 } 227 228 Undefined Undefined::dynamicCast(const Value &v) 229 { 230 if (v.isNull() || v.type() != UndefinedType) 231 return Undefined(0); 232 233 return Undefined(); 234 } 235 236 // ------------------------------ Null ----------------------------------------- 237 238 Null::Null() : Value(NullImp::staticNull) 239 { 240 } 241 242 Null Null::dynamicCast(const Value &v) 243 { 244 if (v.isNull() || v.type() != NullType) 245 return Null(0); 246 247 return Null(); 248 } 249 250 // ------------------------------ Boolean -------------------------------------- 251 252 Boolean::Boolean(bool b) 253 : Value(b ? BooleanImp::staticTrue : BooleanImp::staticFalse) 254 { 255 } 256 257 bool Boolean::value() const 258 { 259 assert(rep); 260 return ((BooleanImp*)rep)->value(); 261 } 262 263 Boolean Boolean::dynamicCast(const Value &v) 264 { 265 if (v.isNull() || v.type() != BooleanType) 266 return static_cast<BooleanImp*>(0); 267 268 return static_cast<BooleanImp*>(v.imp()); 269 } 270 271 // ------------------------------ String --------------------------------------- 272 273 String::String(const UString &s) : Value(new StringImp(s)) 274 { 275 } 276 277 UString String::value() const 278 { 279 assert(rep); 280 return ((StringImp*)rep)->value(); 281 } 282 283 String String::dynamicCast(const Value &v) 284 { 285 if (v.isNull() || v.type() != StringType) 286 return String(0); 287 288 return String(static_cast<StringImp*>(v.imp())); 289 } 290 291 // ------------------------------ Number --------------------------------------- 292 293 Number::Number(int i) 294 : Value(SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i))) { } 295 296 Number::Number(unsigned int u) 297 : Value(SimpleNumber::fits(u) ? SimpleNumber::make(u) : new NumberImp(static_cast<double>(u))) { } 298 299 Number::Number(double d) 300 : Value(SimpleNumber::fits(d) 301 ? SimpleNumber::make(static_cast<long>(d)) 302 : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d))) 303 { } 304 305 Number::Number(double d, bool knownToBeInteger) 306 : Value((knownToBeInteger ? SimpleNumber::integerFits(d) : SimpleNumber::fits(d)) 307 ? SimpleNumber::make(static_cast<long>(d)) 308 : ((!knownToBeInteger && KJS::isNaN(d)) ? NumberImp::staticNaN : new NumberImp(d))) 309 { } 310 311 Number::Number(long int l) 312 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { } 313 314 Number::Number(long unsigned int l) 315 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { } 316 317 Number Number::dynamicCast(const Value &v) 318 { 319 if (v.isNull() || v.type() != NumberType) 320 return Number((NumberImp*)0); 321 322 return Number(static_cast<NumberImp*>(v.imp())); 323 } 324 325 double Number::value() const 326 { 327 if (SimpleNumber::is(rep)) 328 return (double)SimpleNumber::value(rep); 329 assert(rep); 330 return ((NumberImp*)rep)->value(); 331 } 332 333 int Number::intValue() const 334 { 335 if (SimpleNumber::is(rep)) 336 return SimpleNumber::value(rep); 337 return (int)((NumberImp*)rep)->value(); 338 } 339 340 bool Number::isNaN() const 341 { 342 return rep == NumberImp::staticNaN; 343 } 344 345 bool Number::isInf() const 346 { 347 if (SimpleNumber::is(rep)) 348 return false; 349 return KJS::isInf(((NumberImp*)rep)->value()); 350 } 351 352 ValueImp *undefined() 353 { 354 return UndefinedImp::staticUndefined; 355 } 356 357 ValueImp *null() 358 { 359 return NullImp::staticNull; 360 } 361 362 ValueImp *boolean(bool b) 363 { 364 return b ? BooleanImp::staticTrue : BooleanImp::staticFalse; 365 } 366 367 ValueImp *string(const char *s) 164 ObjectImp *AllocatedValueImp::getObject() 165 { 166 return isObject() ? static_cast<ObjectImp *>(this) : 0; 167 } 168 169 const ObjectImp *AllocatedValueImp::getObject() const 170 { 171 return isObject() ? static_cast<const ObjectImp *>(this) : 0; 172 } 173 174 AllocatedValueImp *jsString(const char *s) 368 175 { 369 176 return new StringImp(s ? s : ""); 370 177 } 371 178 372 ValueImp *string(const UString &s)179 AllocatedValueImp *jsString(const UString &s) 373 180 { 374 181 return s.isNull() ? new StringImp("") : new StringImp(s); 375 182 } 376 183 377 ValueImp *zero() 378 { 379 return SimpleNumber::make(0); 380 } 381 382 ValueImp *one() 383 { 384 return SimpleNumber::make(1); 385 } 386 387 ValueImp *two() 388 { 389 return SimpleNumber::make(2); 390 } 391 392 ValueImp *number(int i) 393 { 394 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 395 } 396 397 ValueImp *number(unsigned i) 398 { 399 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 400 } 401 402 ValueImp *number(long i) 403 { 404 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 405 } 406 407 ValueImp *number(unsigned long i) 408 { 409 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 410 } 411 412 ValueImp *number(double d) 184 ValueImp *jsNumber(int i) 185 { 186 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 187 } 188 189 ValueImp *jsNumber(unsigned i) 190 { 191 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 192 } 193 194 ValueImp *jsNumber(long i) 195 { 196 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 197 } 198 199 ValueImp *jsNumber(unsigned long i) 200 { 201 return SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i)); 202 } 203 204 ValueImp *jsNumber(double d) 413 205 { 414 206 return SimpleNumber::fits(d) 415 207 ? SimpleNumber::make(static_cast<long>(d)) 416 : (isNaN(d) ? NumberImp::staticNaN: new NumberImp(d));417 } 418 419 ValueImp * number(double d, bool knownToBeInteger)208 : (isNaN(d) ? jsNaN() : new NumberImp(d)); 209 } 210 211 ValueImp *jsNumber(double d, bool knownToBeInteger) 420 212 { 421 213 return (knownToBeInteger ? SimpleNumber::integerFits(d) : SimpleNumber::fits(d)) 422 214 ? SimpleNumber::make(static_cast<long>(d)) 423 : ((!knownToBeInteger && isNaN(d)) ? NumberImp::staticNaN : new NumberImp(d)); 424 } 425 426 } 215 : ((!knownToBeInteger && isNaN(d)) ? jsNaN() : new NumberImp(d)); 216 } 217 218 void ConstantValues::init() 219 { 220 undefined = new UndefinedImp(); 221 null = new NullImp(); 222 jsTrue = new BooleanImp(true); 223 jsFalse = new BooleanImp(false); 224 NaN = new NumberImp(::KJS::NaN); 225 } 226 227 void ConstantValues::clear() 228 { 229 undefined = NULL; 230 null = NULL; 231 jsTrue = NULL; 232 jsFalse = NULL; 233 NaN = NULL; 234 } 235 236 void ConstantValues::mark() 237 { 238 if (AllocatedValueImp *v = undefined) 239 if (!v->marked()) 240 v->mark(); 241 if (AllocatedValueImp *v = null) 242 if (!v->marked()) 243 v->mark(); 244 if (AllocatedValueImp *v = jsTrue) 245 if (!v->marked()) 246 v->mark(); 247 if (AllocatedValueImp *v = jsFalse) 248 if (!v->marked()) 249 v->mark(); 250 if (AllocatedValueImp *v = NaN) 251 if (!v->marked()) 252 v->mark(); 253 } 254 255 }
Note:
See TracChangeset
for help on using the changeset viewer.