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 }