value.cpp Source File (kjs Library)

| # kjs Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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

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