kjs Library API Documentation

value.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
00005  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
00006  *
00007  *  This library is free software; you can redistribute it and/or
00008  *  modify it under the terms of the GNU Lesser General Public
00009  *  License as published by the Free Software Foundation; either
00010  *  version 2 of the License, or (at your option) any later version.
00011  *
00012  *  This library is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *  Lesser General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU Lesser General Public License
00018  *  along with this library; see the file COPYING.LIB.  If not, write to
00019  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  *  Boston, MA 02111-1307, USA.
00021  *
00022  */
00023 
00024 #include "value.h"
00025 #include "object.h"
00026 #include "types.h"
00027 #include "interpreter.h"
00028 
00029 #include <assert.h>
00030 #include <math.h>
00031 #include <stdio.h>
00032 #include <string.h>
00033 
00034 #include "internal.h"
00035 #include "collector.h"
00036 #include "operations.h"
00037 #include "error_object.h"
00038 #include "nodes.h"
00039 
00040 using namespace KJS;
00041 
00042 // ----------------------------- ValueImp -------------------------------------
00043 
00044 ValueImp::ValueImp() :
00045   refcount(0),
00046   // Tell the garbage collector that this memory block corresponds to a real object now
00047   _flags(VI_CREATED)
00048 {
00049   //fprintf(stderr,"ValueImp::ValueImp %p\n",(void*)this);
00050 }
00051 
00052 ValueImp::~ValueImp()
00053 {
00054   //fprintf(stderr,"ValueImp::~ValueImp %p\n",(void*)this);
00055   _flags |= VI_DESTRUCTED;
00056 }
00057 
00058 void ValueImp::mark()
00059 {
00060   //fprintf(stderr,"ValueImp::mark %p\n",(void*)this);
00061   _flags |= VI_MARKED;
00062 }
00063 
00064 bool ValueImp::marked() const
00065 {
00066   return (_flags & VI_MARKED);
00067 }
00068 
00069 // TODO: inline
00070 void ValueImp::setGcAllowed()
00071 {
00072   //fprintf(stderr,"ValueImp::setGcAllowed %p\n",(void*)this);
00073   _flags |= VI_GCALLOWED;
00074 }
00075 
00076 void* ValueImp::operator new(size_t s)
00077 {
00078   return Collector::allocate(s);
00079 }
00080 
00081 void ValueImp::operator delete(void*)
00082 {
00083   // Do nothing. So far.
00084 }
00085 
00086 // ECMA 9.4
00087 int ValueImp::toInteger(ExecState *exec) const
00088 {
00089   return int(roundValue(exec, Value(const_cast<ValueImp*>(this))));
00090 }
00091 
00092 int ValueImp::toInt32(ExecState *exec) const
00093 {
00094   double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00095   double d32 = fmod(d, D32);
00096 
00097   if (d32 >= D32 / 2.0)
00098     d32 -= D32;
00099 
00100   return static_cast<int>(d32);
00101 }
00102 
00103 unsigned int ValueImp::toUInt32(ExecState *exec) const
00104 {
00105   double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00106   double d32 = fmod(d, D32);
00107 
00108   return static_cast<unsigned int>(d32);
00109 }
00110 
00111 unsigned short ValueImp::toUInt16(ExecState *exec) const
00112 {
00113   double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
00114   double d16 = fmod(d, D16);
00115 
00116   return static_cast<unsigned short>(d16);
00117 }
00118 
00119 // TODO: remove
00120 Value ValueImp::getBase(ExecState *) const
00121 {
00122 #ifndef NDEBUG
00123   fprintf(stderr, "ValueImp::getBase: deprecated\n");
00124 #endif
00125   return Undefined();
00126 }
00127 
00128 // TODO: remove
00129 UString ValueImp::getPropertyName(ExecState * /*exec*/) const
00130 {
00131   if (type() != ReferenceType)
00132     // the spec wants a runtime error here. But getValue() and putValue()
00133     // will catch this case on their own earlier. When returning a Null
00134     // string we should be on the safe side.
00135     return UString();
00136 
00137   return (static_cast<const ReferenceImp*>(this))->getPropertyName();
00138 }
00139 
00140 // TODO: remove
00141 Value ValueImp::getValue(ExecState *exec) const
00142 {
00143   if (type() != ReferenceType)
00144     return Value(const_cast<ValueImp*>(this));
00145 
00146   Value o = getBase(exec);
00147 
00148   if (o.isNull() || o.type() == NullType) {
00149     UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec);
00150     Object err = Error::create(exec, ReferenceError, m.ascii());
00151     exec->setException(err);
00152     return err;
00153   }
00154 
00155   if (o.type() != ObjectType) {
00156     UString m = I18N_NOOP("Base is not an object");
00157     Object err = Error::create(exec, ReferenceError, m.ascii());
00158     exec->setException(err);
00159     return err;
00160   }
00161 
00162   return static_cast<ObjectImp*>(o.imp())->get(exec,getPropertyName(exec));
00163 }
00164 
00165 // TODO: remove
00166 void ValueImp::putValue(ExecState *, const Value)
00167 {
00168 #ifndef NDEBUG
00169   fprintf(stderr, "ValueImp::putValue: deprecated\n");
00170 #endif
00171 }
00172 
00173 bool KJS::operator==(const Value &v1, const Value &v2)
00174 {
00175   return (v1.imp() == v2.imp());
00176 }
00177 
00178 bool KJS::operator!=(const Value &v1, const Value &v2)
00179 {
00180   return (v1.imp() != v2.imp());
00181 }
00182 
00183 
00184 
00185 
00186 // ------------------------------ Value ----------------------------------------
00187 
00188 Value::Value()
00189 {
00190   rep = 0;
00191 }
00192 
00193 Value::Value(ValueImp *v)
00194 {
00195   rep = v;
00196   if (rep)
00197   {
00198     rep->ref();
00199     //fprintf(stderr, "Value::Value(%p) imp=%p ref=%d\n", this, rep, rep->refcount);
00200     v->inlinedSetGcAllowed();
00201   }
00202 }
00203 
00204 Value::Value(const Value &v)
00205 {
00206   rep = v.imp();
00207   if (rep)
00208   {
00209     rep->ref();
00210     //fprintf(stderr, "Value::Value(%p)(copying %p) imp=%p ref=%d\n", this, &v, rep, rep->refcount);
00211   }
00212 }
00213 
00214 Value::~Value()
00215 {
00216   if (rep)
00217   {
00218     rep->deref();
00219     //fprintf(stderr, "Value::~Value(%p) imp=%p ref=%d\n", this, rep, rep->refcount);
00220   }
00221 }
00222 
00223 Value& Value::operator=(const Value &v)
00224 {
00225   if (rep) {
00226     rep->deref();
00227     //fprintf(stderr, "Value::operator=(%p)(copying %p) old imp=%p ref=%d\n", this, &v, rep, rep->refcount);
00228   }
00229   rep = v.imp();
00230   if (rep)
00231   {
00232     rep->ref();
00233     //fprintf(stderr, "Value::operator=(%p)(copying %p) imp=%p ref=%d\n", this, &v, rep, rep->refcount);
00234   }
00235   return *this;
00236 }
00237 
00238 bool Value::isValid() const
00239 {
00240   return rep;
00241 }
00242 
00243 bool Value::isNull() const
00244 {
00245   return (rep == 0);
00246 }
00247 
00248 ValueImp *Value::imp() const
00249 {
00250   return rep;
00251 }
00252 
00253 Type Value::type() const
00254 {
00255   return rep->type();
00256 }
00257 
00258 bool Value::isA(Type t) const
00259 {
00260   return (type() == t);
00261 }
00262 
00263 Value Value::toPrimitive(ExecState *exec, Type preferredType) const
00264 {
00265   return rep->toPrimitive(exec,preferredType);
00266 }
00267 
00268 bool Value::toBoolean(ExecState *exec) const
00269 {
00270   return rep->toBoolean(exec);
00271 }
00272 
00273 double Value::toNumber(ExecState *exec) const
00274 {
00275   return rep->toNumber(exec);
00276 }
00277 
00278 int Value::toInteger(ExecState *exec) const
00279 {
00280   return rep->toInteger(exec);
00281 }
00282 
00283 int Value::toInt32(ExecState *exec) const
00284 {
00285   return rep->toInt32(exec);
00286 }
00287 
00288 unsigned int Value::toUInt32(ExecState *exec) const
00289 {
00290   return rep->toUInt32(exec);
00291 }
00292 
00293 unsigned short Value::toUInt16(ExecState *exec) const
00294 {
00295   return rep->toUInt16(exec);
00296 }
00297 
00298 UString Value::toString(ExecState *exec) const
00299 {
00300   return rep->toString(exec);
00301 }
00302 
00303 Object Value::toObject(ExecState *exec) const
00304 {
00305   return rep->toObject(exec);
00306 }
00307 
00308 // TODO: remove
00309 Value Value::getBase(ExecState *exec) const
00310 {
00311   return rep->getBase(exec);
00312 }
00313 
00314 // TODO: remove
00315 UString Value::getPropertyName(ExecState *exec) const
00316 {
00317   return rep->getPropertyName(exec);
00318 }
00319 
00320 // TODO: remove
00321 Value Value::getValue(ExecState *exec) const
00322 {
00323   return rep->getValue(exec);
00324 }
00325 
00326 // TODO: remove
00327 void Value::putValue(ExecState *exec, const Value w)
00328 {
00329   rep->putValue(exec,w);
00330 }
00331 
00332 // ------------------------------ Undefined ------------------------------------
00333 
00334 Undefined::Undefined() : Value(UndefinedImp::staticUndefined)
00335 {
00336 }
00337 
00338 Undefined::~Undefined() {
00339 }
00340 
00341 Undefined::Undefined(UndefinedImp *v) : Value(v)
00342 {
00343 }
00344 
00345 Undefined::Undefined(const Undefined &v) : Value(v)
00346 {
00347 }
00348 
00349 Undefined& Undefined::operator=(const Undefined &v)
00350 {
00351   Value::operator=(v);
00352   return *this;
00353 }
00354 
00355 Undefined Undefined::dynamicCast(const Value &v)
00356 {
00357   if (v.isNull() || v.type() != UndefinedType)
00358     return Undefined(0);
00359 
00360   return Undefined();
00361 }
00362 
00363 // ------------------------------ Null -----------------------------------------
00364 
00365 Null::Null() : Value(NullImp::staticNull)
00366 {
00367 }
00368 
00369 Null::~Null() {
00370 }
00371 
00372 
00373 Null::Null(NullImp *v) : Value(v)
00374 {
00375 }
00376 
00377 Null::Null(const Null &v) : Value(v)
00378 {
00379 }
00380 
00381 Null& Null::operator=(const Null &v)
00382 {
00383   Value::operator=(v);
00384   return *this;
00385 }
00386 
00387 Null Null::dynamicCast(const Value &v)
00388 {
00389   if (v.isNull() || v.type() != NullType)
00390     return Null(0);
00391 
00392   return Null();
00393 }
00394 
00395 // ------------------------------ Boolean --------------------------------------
00396 
00397 Boolean::Boolean(bool b)
00398   : Value(b ? BooleanImp::staticTrue : BooleanImp::staticFalse)
00399 {
00400 }
00401 
00402 Boolean::~Boolean() { }
00403 
00404 
00405 
00406 Boolean::Boolean(BooleanImp *v) : Value(v)
00407 {
00408 }
00409 
00410 Boolean::Boolean(const Boolean &v) : Value(v)
00411 {
00412 }
00413 
00414 Boolean& Boolean::operator=(const Boolean &v)
00415 {
00416   Value::operator=(v);
00417   return *this;
00418 }
00419 
00420 
00421 bool Boolean::value() const
00422 {
00423   assert(rep);
00424   return ((BooleanImp*)rep)->value();
00425 }
00426 
00427 Boolean Boolean::dynamicCast(const Value &v)
00428 {
00429   if (v.isNull() || v.type() != BooleanType)
00430     return static_cast<BooleanImp*>(0);
00431 
00432   return static_cast<BooleanImp*>(v.imp());
00433 }
00434 
00435 // ------------------------------ String ---------------------------------------
00436 
00437 String::String(const UString &s) : Value(new StringImp(UString(s)))
00438 {
00439 }
00440 
00441 String::~String() { }
00442 
00443 String::String(StringImp *v) : Value(v)
00444 {
00445 }
00446 
00447 String::String(const String &v) : Value(v)
00448 {
00449 }
00450 
00451 String& String::operator=(const String &v)
00452 {
00453   Value::operator=(v);
00454   return *this;
00455 }
00456 
00457 UString String::value() const
00458 {
00459   assert(rep);
00460   return ((StringImp*)rep)->value();
00461 }
00462 
00463 String String::dynamicCast(const Value &v)
00464 {
00465   if (v.isNull() || v.type() != StringType)
00466     return String(0);
00467 
00468   return String(static_cast<StringImp*>(v.imp()));
00469 }
00470 
00471 // ------------------------------ Number ---------------------------------------
00472 
00473 Number::Number(int i)
00474   : Value(new NumberImp(static_cast<double>(i))) { }
00475 
00476 Number::Number(unsigned int u)
00477   : Value(new NumberImp(static_cast<double>(u))) { }
00478 
00479 Number::Number(double d)
00480   : Value(new NumberImp(d)) { }
00481 
00482 Number::Number(long int l)
00483   : Value(new NumberImp(static_cast<double>(l))) { }
00484 
00485 Number::Number(long unsigned int l)
00486   : Value(new NumberImp(static_cast<double>(l))) { }
00487 
00488 Number::~Number() { }
00489 
00490 Number::Number(NumberImp *v) : Value(v)
00491 {
00492 }
00493 
00494 Number::Number(const Number &v) : Value(v)
00495 {
00496 }
00497 
00498 Number& Number::operator=(const Number &v)
00499 {
00500   Value::operator=(v);
00501   return *this;
00502 }
00503 
00504 Number Number::dynamicCast(const Value &v)
00505 {
00506   if (v.isNull() || v.type() != NumberType)
00507     return Number((NumberImp*)0);
00508 
00509   return Number(static_cast<NumberImp*>(v.imp()));
00510 }
00511 
00512 double Number::value() const
00513 {
00514   assert(rep);
00515   return ((NumberImp*)rep)->value();
00516 }
00517 
00518 int Number::intValue() const
00519 {
00520   return int(value());
00521 }
00522 
00523 bool Number::isNaN() const
00524 {
00525   return KJS::isNaN(value());
00526 }
00527 
00528 bool Number::isInf() const
00529 {
00530   return KJS::isInf(value());
00531 }
00532 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:21:16 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001