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.0.