value.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "value.h"
00026 #include "object.h"
00027 #include "types.h"
00028 #include "interpreter.h"
00029
00030 #include <assert.h>
00031 #include <math.h>
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <limits.h>
00035
00036 #include "internal.h"
00037 #include "collector.h"
00038 #include "operations.h"
00039 #include "error_object.h"
00040 #include "nodes.h"
00041 #include "simple_number.h"
00042
00043 using namespace KJS;
00044
00045
00046
00047 ValueImp::ValueImp() :
00048 refcount(0),
00049
00050 _flags(VI_CREATED)
00051 {
00052
00053 }
00054
00055 ValueImp::~ValueImp()
00056 {
00057
00058 _flags |= VI_DESTRUCTED;
00059 }
00060
00061 void ValueImp::mark()
00062 {
00063
00064 _flags |= VI_MARKED;
00065 }
00066
00067 bool ValueImp::marked() const
00068 {
00069
00070 return SimpleNumber::is(this) || (_flags & VI_MARKED);
00071 }
00072
00073 void ValueImp::setGcAllowed()
00074 {
00075
00076
00077
00078 if (!SimpleNumber::is(this))
00079 _flags |= VI_GCALLOWED;
00080 }
00081
00082 void* ValueImp::operator new(size_t s)
00083 {
00084 return Collector::allocate(s);
00085 }
00086
00087 void ValueImp::operator delete(void*)
00088 {
00089
00090 }
00091
00092 bool ValueImp::toUInt32(unsigned&) const
00093 {
00094 return false;
00095 }
00096
00097
00098 int ValueImp::toInteger(ExecState *exec) const
00099 {
00100 unsigned i;
00101 if (dispatchToUInt32(i))
00102 return static_cast<int>(i);
00103 double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00104 if (isInf(d))
00105 return INT_MAX;
00106 return static_cast<int>(d);
00107 }
00108
00109 int ValueImp::toInt32(ExecState *exec) const
00110 {
00111 unsigned i;
00112 if (dispatchToUInt32(i))
00113 return (int)i;
00114
00115 double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00116 if (isNaN(d) || isInf(d) || d == 0.0)
00117 return 0;
00118 double d32 = fmod(d, D32);
00119
00120
00121
00122 if (d32 < 0)
00123 d32 += D32;
00124
00125 if (d32 >= D32 / 2.0)
00126 d32 -= D32;
00127
00128 return static_cast<int>(d32);
00129 }
00130
00131 unsigned int ValueImp::toUInt32(ExecState *exec) const
00132 {
00133 unsigned i;
00134 if (dispatchToUInt32(i))
00135 return i;
00136
00137 double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00138 if (isNaN(d) || isInf(d) || d == 0.0)
00139 return 0;
00140 double d32 = fmod(d, D32);
00141
00142 if (d32 < 0)
00143 d32 += D32;
00144
00145
00146
00147
00148
00149
00150 return static_cast<unsigned int>(d32);
00151 }
00152
00153 unsigned short ValueImp::toUInt16(ExecState *exec) const
00154 {
00155 unsigned i;
00156 if (dispatchToUInt32(i))
00157 return (unsigned short)i;
00158
00159 double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00160 double d16 = fmod(d, D16);
00161
00162
00163 int t_int = static_cast<int>(d16);
00164 return static_cast<unsigned short>(t_int);
00165 }
00166
00167
00168
00169
00170 Type ValueImp::dispatchType() const
00171 {
00172 if (SimpleNumber::is(this))
00173 return NumberType;
00174 return type();
00175 }
00176
00177 Value ValueImp::dispatchToPrimitive(ExecState *exec, Type preferredType) const
00178 {
00179 if (SimpleNumber::is(this))
00180 return Value(const_cast<ValueImp *>(this));
00181 return toPrimitive(exec, preferredType);
00182 }
00183
00184 bool ValueImp::dispatchToBoolean(ExecState *exec) const
00185 {
00186 if (SimpleNumber::is(this))
00187 return SimpleNumber::value(this);
00188 return toBoolean(exec);
00189 }
00190
00191 double ValueImp::dispatchToNumber(ExecState *exec) const
00192 {
00193 if (SimpleNumber::is(this))
00194 return SimpleNumber::value(this);
00195 return toNumber(exec);
00196 }
00197
00198 UString ValueImp::dispatchToString(ExecState *exec) const
00199 {
00200 if (SimpleNumber::is(this))
00201 return UString::from(SimpleNumber::value(this));
00202 return toString(exec);
00203 }
00204
00205 Object ValueImp::dispatchToObject(ExecState *exec) const
00206 {
00207 if (SimpleNumber::is(this))
00208 return static_cast<const NumberImp *>(this)->NumberImp::toObject(exec);
00209 return toObject(exec);
00210 }
00211
00212 bool ValueImp::dispatchToUInt32(unsigned& result) const
00213 {
00214 if (SimpleNumber::is(this)) {
00215 long i = SimpleNumber::value(this);
00216 if (i < 0)
00217 return false;
00218 result = (unsigned)i;
00219 return true;
00220 }
00221 return toUInt32(result);
00222 }
00223
00224
00225
00226 Value::Value(ValueImp *v)
00227 {
00228 rep = v;
00229 #ifdef DEBUG_COLLECTOR
00230 assert (!(rep && !SimpleNumber::is(rep) && *((uint32_t *)rep) == 0 ));
00231 assert (!(rep && !SimpleNumber::is(rep) && rep->_flags & ValueImp::VI_MARKED));
00232 #endif
00233 if (v)
00234 {
00235 v->ref();
00236
00237 v->setGcAllowed();
00238 }
00239 }
00240
00241 Value::Value(const Value &v)
00242 {
00243 rep = v.imp();
00244 #ifdef DEBUG_COLLECTOR
00245 assert (!(rep && !SimpleNumber::is(rep) && *((uint32_t *)rep) == 0 ));
00246 assert (!(rep && !SimpleNumber::is(rep) && rep->_flags & ValueImp::VI_MARKED));
00247 #endif
00248 if (rep)
00249 {
00250 rep->ref();
00251
00252 }
00253 }
00254
00255 Value::~Value()
00256 {
00257 if (rep)
00258 {
00259 rep->deref();
00260
00261 }
00262 }
00263
00264 Value& Value::operator=(const Value &v)
00265 {
00266 ValueImp *tmpRep = v.imp();
00267
00268
00269
00270 if (tmpRep) {
00271 tmpRep->ref();
00272
00273 }
00274
00275 if (rep) {
00276 rep->deref();
00277
00278 }
00279 rep = tmpRep;
00280
00281 return *this;
00282 }
00283
00284
00285
00286 Undefined::Undefined() : Value(UndefinedImp::staticUndefined)
00287 {
00288 }
00289
00290 Undefined Undefined::dynamicCast(const Value &v)
00291 {
00292 if (!v.isValid() || v.type() != UndefinedType)
00293 return Undefined(0);
00294
00295 return Undefined();
00296 }
00297
00298
00299
00300 Null::Null() : Value(NullImp::staticNull)
00301 {
00302 }
00303
00304 Null Null::dynamicCast(const Value &v)
00305 {
00306 if (!v.isValid() || v.type() != NullType)
00307 return Null(0);
00308
00309 return Null();
00310 }
00311
00312
00313
00314 Boolean::Boolean(bool b)
00315 : Value(b ? BooleanImp::staticTrue : BooleanImp::staticFalse)
00316 {
00317 }
00318
00319 bool Boolean::value() const
00320 {
00321 assert(rep);
00322 return ((BooleanImp*)rep)->value();
00323 }
00324
00325 Boolean Boolean::dynamicCast(const Value &v)
00326 {
00327 if (!v.isValid() || v.type() != BooleanType)
00328 return static_cast<BooleanImp*>(0);
00329
00330 return static_cast<BooleanImp*>(v.imp());
00331 }
00332
00333
00334
00335 String::String(const UString &s) : Value(new StringImp(s))
00336 {
00337 #ifndef NDEBUG
00338 if (s.isNull())
00339 fprintf(stderr, "WARNING: KJS::String constructed from null string\n");
00340 #endif
00341 }
00342
00343 UString String::value() const
00344 {
00345 assert(rep);
00346 return ((StringImp*)rep)->value();
00347 }
00348
00349 String String::dynamicCast(const Value &v)
00350 {
00351 if (!v.isValid() || v.type() != StringType)
00352 return String(0);
00353
00354 return String(static_cast<StringImp*>(v.imp()));
00355 }
00356
00357
00358
00359 Number::Number(int i)
00360 : Value(SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i))) { }
00361
00362 Number::Number(unsigned int u)
00363 : Value(SimpleNumber::fits(u) ? SimpleNumber::make(u) : new NumberImp(static_cast<double>(u))) { }
00364
00365 Number::Number(double d)
00366 #if defined(__alpha) && !defined(_IEEE_FP)
00367
00368 : Value(KJS::isNaN(d) ? NumberImp::staticNaN : (SimpleNumber::fits(d) ? SimpleNumber::make((long)d) : new NumberImp(d))) { }
00369 #else
00370 : Value(SimpleNumber::fits(d) ? SimpleNumber::make((long)d) : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d))) { }
00371 #endif
00372
00373 Number::Number(long int l)
00374 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
00375
00376 Number::Number(long unsigned int l)
00377 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
00378
00379 Number Number::dynamicCast(const Value &v)
00380 {
00381 if (!v.isValid() || v.type() != NumberType)
00382 return Number((NumberImp*)0);
00383
00384 return Number(static_cast<NumberImp*>(v.imp()));
00385 }
00386
00387 double Number::value() const
00388 {
00389 if (SimpleNumber::is(rep))
00390 return (double)SimpleNumber::value(rep);
00391 assert(rep);
00392 return ((NumberImp*)rep)->value();
00393 }
00394
00395 int Number::intValue() const
00396 {
00397 if (SimpleNumber::is(rep))
00398 return SimpleNumber::value(rep);
00399 return (int)((NumberImp*)rep)->value();
00400 }
00401
00402 bool Number::isNaN() const
00403 {
00404 return rep == NumberImp::staticNaN;
00405 }
00406
00407 bool Number::isInf() const
00408 {
00409 if (SimpleNumber::is(rep))
00410 return false;
00411 return KJS::isInf(((NumberImp*)rep)->value());
00412 }
|