value.cpp
00001
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
00143
00144
00145
00146
00147 int t_int = static_cast<int>(d32);
00148 return static_cast<unsigned int>(t_int);
00149 }
00150
00151 unsigned short ValueImp::toUInt16(ExecState *exec) const
00152 {
00153 unsigned i;
00154 if (dispatchToUInt32(i))
00155 return (unsigned short)i;
00156
00157 double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00158 double d16 = fmod(d, D16);
00159
00160
00161 int t_int = static_cast<int>(d16);
00162 return static_cast<unsigned short>(t_int);
00163 }
00164
00165
00166
00167
00168 Type ValueImp::dispatchType() const
00169 {
00170 if (SimpleNumber::is(this))
00171 return NumberType;
00172 return type();
00173 }
00174
00175 Value ValueImp::dispatchToPrimitive(ExecState *exec, Type preferredType) const
00176 {
00177 if (SimpleNumber::is(this))
00178 return Value(const_cast<ValueImp *>(this));
00179 return toPrimitive(exec, preferredType);
00180 }
00181
00182 bool ValueImp::dispatchToBoolean(ExecState *exec) const
00183 {
00184 if (SimpleNumber::is(this))
00185 return SimpleNumber::value(this);
00186 return toBoolean(exec);
00187 }
00188
00189 double ValueImp::dispatchToNumber(ExecState *exec) const
00190 {
00191 if (SimpleNumber::is(this))
00192 return SimpleNumber::value(this);
00193 return toNumber(exec);
00194 }
00195
00196 UString ValueImp::dispatchToString(ExecState *exec) const
00197 {
00198 if (SimpleNumber::is(this))
00199 return UString::from(SimpleNumber::value(this));
00200 return toString(exec);
00201 }
00202
00203 Object ValueImp::dispatchToObject(ExecState *exec) const
00204 {
00205 if (SimpleNumber::is(this))
00206 return static_cast<const NumberImp *>(this)->NumberImp::toObject(exec);
00207 return toObject(exec);
00208 }
00209
00210 bool ValueImp::dispatchToUInt32(unsigned& result) const
00211 {
00212 if (SimpleNumber::is(this)) {
00213 long i = SimpleNumber::value(this);
00214 if (i < 0)
00215 return false;
00216 result = (unsigned)i;
00217 return true;
00218 }
00219 return toUInt32(result);
00220 }
00221
00222
00223
00224 Value::Value(ValueImp *v)
00225 {
00226 rep = v;
00227 #ifdef DEBUG_COLLECTOR
00228 assert (!(rep && !SimpleNumber::is(rep) && *((uint32_t *)rep) == 0 ));
00229 assert (!(rep && !SimpleNumber::is(rep) && rep->_flags & ValueImp::VI_MARKED));
00230 #endif
00231 if (v)
00232 {
00233 v->ref();
00234
00235 v->setGcAllowed();
00236 }
00237 }
00238
00239 Value::Value(const Value &v)
00240 {
00241 rep = v.imp();
00242 #ifdef DEBUG_COLLECTOR
00243 assert (!(rep && !SimpleNumber::is(rep) && *((uint32_t *)rep) == 0 ));
00244 assert (!(rep && !SimpleNumber::is(rep) && rep->_flags & ValueImp::VI_MARKED));
00245 #endif
00246 if (rep)
00247 {
00248 rep->ref();
00249
00250 }
00251 }
00252
00253 Value::~Value()
00254 {
00255 if (rep)
00256 {
00257 rep->deref();
00258
00259 }
00260 }
00261
00262 Value& Value::operator=(const Value &v)
00263 {
00264 ValueImp *tmpRep = v.imp();
00265
00266
00267
00268 if (tmpRep) {
00269 tmpRep->ref();
00270
00271 }
00272
00273 if (rep) {
00274 rep->deref();
00275
00276 }
00277 rep = tmpRep;
00278
00279 return *this;
00280 }
00281
00282
00283
00284 Undefined::Undefined() : Value(UndefinedImp::staticUndefined)
00285 {
00286 }
00287
00288 Undefined Undefined::dynamicCast(const Value &v)
00289 {
00290 if (!v.isValid() || v.type() != UndefinedType)
00291 return Undefined(0);
00292
00293 return Undefined();
00294 }
00295
00296
00297
00298 Null::Null() : Value(NullImp::staticNull)
00299 {
00300 }
00301
00302 Null Null::dynamicCast(const Value &v)
00303 {
00304 if (!v.isValid() || v.type() != NullType)
00305 return Null(0);
00306
00307 return Null();
00308 }
00309
00310
00311
00312 Boolean::Boolean(bool b)
00313 : Value(b ? BooleanImp::staticTrue : BooleanImp::staticFalse)
00314 {
00315 }
00316
00317 bool Boolean::value() const
00318 {
00319 assert(rep);
00320 return ((BooleanImp*)rep)->value();
00321 }
00322
00323 Boolean Boolean::dynamicCast(const Value &v)
00324 {
00325 if (!v.isValid() || v.type() != BooleanType)
00326 return static_cast<BooleanImp*>(0);
00327
00328 return static_cast<BooleanImp*>(v.imp());
00329 }
00330
00331
00332
00333 String::String(const UString &s) : Value(new StringImp(UString(s)))
00334 {
00335 }
00336
00337 UString String::value() const
00338 {
00339 assert(rep);
00340 return ((StringImp*)rep)->value();
00341 }
00342
00343 String String::dynamicCast(const Value &v)
00344 {
00345 if (!v.isValid() || v.type() != StringType)
00346 return String(0);
00347
00348 return String(static_cast<StringImp*>(v.imp()));
00349 }
00350
00351
00352
00353 Number::Number(int i)
00354 : Value(SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i))) { }
00355
00356 Number::Number(unsigned int u)
00357 : Value(SimpleNumber::fits(u) ? SimpleNumber::make(u) : new NumberImp(static_cast<double>(u))) { }
00358
00359 Number::Number(double d)
00360 #if defined(__alpha) && !defined(_IEEE_FP)
00361
00362 : Value(KJS::isNaN(d) ? NumberImp::staticNaN : (SimpleNumber::fits(d) ? SimpleNumber::make((long)d) : new NumberImp(d))) { }
00363 #else
00364 : Value(SimpleNumber::fits(d) ? SimpleNumber::make((long)d) : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d))) { }
00365 #endif
00366
00367 Number::Number(long int l)
00368 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
00369
00370 Number::Number(long unsigned int l)
00371 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
00372
00373 Number Number::dynamicCast(const Value &v)
00374 {
00375 if (v.isNull() || v.type() != NumberType)
00376 return Number((NumberImp*)0);
00377
00378 return Number(static_cast<NumberImp*>(v.imp()));
00379 }
00380
00381 double Number::value() const
00382 {
00383 if (SimpleNumber::is(rep))
00384 return (double)SimpleNumber::value(rep);
00385 assert(rep);
00386 return ((NumberImp*)rep)->value();
00387 }
00388
00389 int Number::intValue() const
00390 {
00391 if (SimpleNumber::is(rep))
00392 return SimpleNumber::value(rep);
00393 return (int)((NumberImp*)rep)->value();
00394 }
00395
00396 bool Number::isNaN() const
00397 {
00398 return rep == NumberImp::staticNaN;
00399 }
00400
00401 bool Number::isInf() const
00402 {
00403 if (SimpleNumber::is(rep))
00404 return false;
00405 return KJS::isInf(((NumberImp*)rep)->value());
00406 }
This file is part of the documentation for kjs Library Version 3.2.3.