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 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(UString(s)))
00336 {
00337 }
00338
00339 UString String::value() const
00340 {
00341 assert(rep);
00342 return ((StringImp*)rep)->value();
00343 }
00344
00345 String String::dynamicCast(const Value &v)
00346 {
00347 if (!v.isValid() || v.type() != StringType)
00348 return String(0);
00349
00350 return String(static_cast<StringImp*>(v.imp()));
00351 }
00352
00353
00354
00355 Number::Number(int i)
00356 : Value(SimpleNumber::fits(i) ? SimpleNumber::make(i) : new NumberImp(static_cast<double>(i))) { }
00357
00358 Number::Number(unsigned int u)
00359 : Value(SimpleNumber::fits(u) ? SimpleNumber::make(u) : new NumberImp(static_cast<double>(u))) { }
00360
00361 Number::Number(double d)
00362 #if defined(__alpha) && !defined(_IEEE_FP)
00363
00364 : Value(KJS::isNaN(d) ? NumberImp::staticNaN : (SimpleNumber::fits(d) ? SimpleNumber::make((long)d) : new NumberImp(d))) { }
00365 #else
00366 : Value(SimpleNumber::fits(d) ? SimpleNumber::make((long)d) : (KJS::isNaN(d) ? NumberImp::staticNaN : new NumberImp(d))) { }
00367 #endif
00368
00369 Number::Number(long int l)
00370 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
00371
00372 Number::Number(long unsigned int l)
00373 : Value(SimpleNumber::fits(l) ? SimpleNumber::make(l) : new NumberImp(static_cast<double>(l))) { }
00374
00375 Number Number::dynamicCast(const Value &v)
00376 {
00377 if (v.isNull() || v.type() != NumberType)
00378 return Number((NumberImp*)0);
00379
00380 return Number(static_cast<NumberImp*>(v.imp()));
00381 }
00382
00383 double Number::value() const
00384 {
00385 if (SimpleNumber::is(rep))
00386 return (double)SimpleNumber::value(rep);
00387 assert(rep);
00388 return ((NumberImp*)rep)->value();
00389 }
00390
00391 int Number::intValue() const
00392 {
00393 if (SimpleNumber::is(rep))
00394 return SimpleNumber::value(rep);
00395 return (int)((NumberImp*)rep)->value();
00396 }
00397
00398 bool Number::isNaN() const
00399 {
00400 return rep == NumberImp::staticNaN;
00401 }
00402
00403 bool Number::isInf() const
00404 {
00405 if (SimpleNumber::is(rep))
00406 return false;
00407 return KJS::isInf(((NumberImp*)rep)->value());
00408 }
This file is part of the documentation for kjs Library Version 3.4.2.