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::operator=(const Value &v)
00205 {
00206   if (rep) {
00207     rep->deref();
00208     //fprintf(stderr, "Value::operator=(%p)(copying %p) old imp=%p ref=%d\n", this, &v, rep, rep->refcount);
00209   }
00210   rep = v.imp();
00211   if (rep)
00212   {
00213     rep->ref();
00214     //fprintf(stderr, "Value::operator=(%p)(copying %p) imp=%p ref=%d\n", this, &v, rep, rep->refcount);
00215   }
00216   return *this;
00217 }
00218 
00219 bool Value::isValid() const
00220 {
00221   return rep;
00222 }
00223 
00224 bool Value::isNull() const
00225 {
00226   return (rep == 0);
00227 }
00228 
00229 ValueImp *Value::imp() const
00230 {
00231   return rep;
00232 }
00233 
00234 Type Value::type() const
00235 {
00236   return rep->type();
00237 }
00238 
00239 bool Value::isA(Type t) const
00240 {
00241   return (type() == t);
00242 }
00243 
00244 Value Value::toPrimitive(ExecState *exec, Type preferredType) const
00245 {
00246   return rep->toPrimitive(exec,preferredType);
00247 }
00248 
00249 bool Value::toBoolean(ExecState *exec) const
00250 {
00251   return rep->toBoolean(exec);
00252 }
00253 
00254 double Value::toNumber(ExecState *exec) const
00255 {
00256   return rep->toNumber(exec);
00257 }
00258 
00259 int Value::toInteger(ExecState *exec) const
00260 {
00261   return rep->toInteger(exec);
00262 }
00263 
00264 int Value::toInt32(ExecState *exec) const
00265 {
00266   return rep->toInt32(exec);
00267 }
00268 
00269 unsigned int Value::toUInt32(ExecState *exec) const
00270 {
00271   return rep->toUInt32(exec);
00272 }
00273 
00274 unsigned short Value::toUInt16(ExecState *exec) const
00275 {
00276   return rep->toUInt16(exec);
00277 }
00278 
00279 UString Value::toString(ExecState *exec) const
00280 {
00281   return rep->toString(exec);
00282 }
00283 
00284 Object Value::toObject(ExecState *exec) const
00285 {
00286   return rep->toObject(exec);
00287 }
00288 
00289 // TODO: remove
00290 Value Value::getBase(ExecState *exec) const
00291 {
00292   return rep->getBase(exec);
00293 }
00294 
00295 // TODO: remove
00296 UString Value::getPropertyName(ExecState *exec) const
00297 {
00298   return rep->getPropertyName(exec);
00299 }
00300 
00301 // TODO: remove
00302 Value Value::getValue(ExecState *exec) const
00303 {
00304   return rep->getValue(exec);
00305 }
00306 
00307 // TODO: remove
00308 void Value::putValue(ExecState *exec, const Value w)
00309 {
00310   rep->putValue(exec,w);
00311 }
00312 
00313 // ------------------------------ Undefined ------------------------------------
00314 
00315 Undefined::Undefined() : Value(UndefinedImp::staticUndefined)
00316 {
00317 }
00318 
00319 Undefined::~Undefined() {
00320 }
00321 
00322 Undefined::Undefined(UndefinedImp *v) : Value(v)
00323 {
00324 }
00325 
00326 Undefined::Undefined(const Undefined &v) : Value(v)
00327 {
00328 }
00329 
00330 Undefined& Undefined::operator=(const Undefined &v)
00331 {
00332   Value::operator=(v);
00333   return *this;
00334 }
00335 
00336 Undefined Undefined::dynamicCast(const Value &v)
00337 {
00338   if (v.isNull() || v.type() != UndefinedType)
00339     return Undefined(0);
00340 
00341   return Undefined();
00342 }
00343 
00344 // ------------------------------ Null -----------------------------------------
00345 
00346 Null::Null() : Value(NullImp::staticNull)
00347 {
00348 }
00349 
00350 Null::~Null() {
00351 }
00352 
00353 
00354 Null::Null(NullImp *v) : Value(v)
00355 {
00356 }
00357 
00358 Null::Null(const Null &v) : Value(v)
00359 {
00360 }
00361 
00362 Null& Null::operator=(const Null &v)
00363 {
00364   Value::operator=(v);
00365   return *this;
00366 }
00367 
00368 Null Null::dynamicCast(const Value &v)
00369 {
00370   if (v.isNull() || v.type() != NullType)
00371     return Null(0);
00372 
00373   return Null();
00374 }
00375 
00376 // ------------------------------ Boolean --------------------------------------
00377 
00378 Boolean::Boolean(bool b)
00379   : Value(b ? BooleanImp::staticTrue : BooleanImp::staticFalse)
00380 {
00381 }
00382 
00383 Boolean::~Boolean() { }
00384 
00385 
00386 
00387 Boolean::Boolean(BooleanImp *v) : Value(v)
00388 {
00389 }
00390 
00391 Boolean::Boolean(const Boolean &v) : Value(v)
00392 {
00393 }
00394 
00395 Boolean& Boolean::operator=(const Boolean &v)
00396 {
00397   Value::operator=(v);
00398   return *this;
00399 }
00400 
00401 
00402 bool Boolean::value() const
00403 {
00404   assert(rep);
00405   return ((BooleanImp*)rep)->value();
00406 }
00407 
00408 Boolean Boolean::dynamicCast(const Value &v)
00409 {
00410   if (v.isNull() || v.type() != BooleanType)
00411     return static_cast<BooleanImp*>(0);
00412 
00413   return static_cast<BooleanImp*>(v.imp());
00414 }
00415 
00416 // ------------------------------ String ---------------------------------------
00417 
00418 String::String(const UString &s) : Value(new StringImp(UString(s)))
00419 {
00420 }
00421 
00422 String::~String() { }
00423 
00424 String::String(StringImp *v) : Value(v)
00425 {
00426 }
00427 
00428 String::String(const String &v) : Value(v)
00429 {
00430 }
00431 
00432 String& String::operator=(const String &v)
00433 {
00434   Value::operator=(v);
00435   return *this;
00436 }
00437 
00438 UString String::value() const
00439 {
00440   assert(rep);
00441   return ((StringImp*)rep)->value();
00442 }
00443 
00444 String String::dynamicCast(const Value &v)
00445 {
00446   if (v.isNull() || v.type() != StringType)
00447     return String(0);
00448 
00449   return String(static_cast<StringImp*>(v.imp()));
00450 }
00451 
00452 // ------------------------------ Number ---------------------------------------
00453 
00454 Number::Number(int i)
00455   : Value(new NumberImp(static_cast<double>(i))) { }
00456 
00457 Number::Number(unsigned int u)
00458   : Value(new NumberImp(static_cast<double>(u))) { }
00459 
00460 Number::Number(double d)
00461   : Value(new NumberImp(d)) { }
00462 
00463 Number::Number(long int l)
00464   : Value(new NumberImp(static_cast<double>(l))) { }
00465 
00466 Number::Number(long unsigned int l)
00467   : Value(new NumberImp(static_cast<double>(l))) { }
00468 
00469 Number::~Number() { }
00470 
00471 Number::Number(NumberImp *v) : Value(v)
00472 {
00473 }
00474 
00475 Number::Number(const Number &v) : Value(v)
00476 {
00477 }
00478 
00479 Number& Number::operator=(const Number &v)
00480 {
00481   Value::operator=(v);
00482   return *this;
00483 }
00484 
00485 Number Number::dynamicCast(const Value &v)
00486 {
00487   if (v.isNull() || v.type() != NumberType)
00488     return Number((NumberImp*)0);
00489 
00490   return Number(static_cast<NumberImp*>(v.imp()));
00491 }
00492 
00493 double Number::value() const
00494 {
00495   assert(rep);
00496   return ((NumberImp*)rep)->value();
00497 }
00498 
00499 int Number::intValue() const
00500 {
00501   return int(value());
00502 }
00503 
00504 bool Number::isNaN() const
00505 {
00506   return KJS::isNaN(value());
00507 }
00508 
00509 bool Number::isInf() const
00510 {
00511   return KJS::isInf(value());
00512 }
00513 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:08:38 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001