You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
401 lines
12 KiB
401 lines
12 KiB
15 years ago
|
// -*- c-basic-offset: 2 -*-
|
||
|
/*
|
||
|
* This file is part of the KDE libraries
|
||
|
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
|
||
|
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
|
||
|
* Copyright (C) 2003 Apple Computer, Inc.
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Library General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public License
|
||
|
* along with this library; see the file COPYING.LIB. If not, write to
|
||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef _KJS_VALUE_H_
|
||
|
#define _KJS_VALUE_H_
|
||
|
|
||
|
#include <stdlib.h> // Needed for size_t
|
||
|
|
||
|
#include "ustring.h"
|
||
|
#include "simple_number.h"
|
||
|
|
||
|
// Primitive data types
|
||
|
|
||
|
namespace KJS {
|
||
|
|
||
|
class Value;
|
||
|
class ValueImp;
|
||
|
class ValueImpPrivate;
|
||
|
class Undefined;
|
||
|
class UndefinedImp;
|
||
|
class Null;
|
||
|
class NullImp;
|
||
|
class Boolean;
|
||
|
class BooleanImp;
|
||
|
class String;
|
||
|
class StringImp;
|
||
|
class Number;
|
||
|
class NumberImp;
|
||
|
class Object;
|
||
|
class ObjectImp;
|
||
|
class Reference;
|
||
|
class List;
|
||
|
class ListImp;
|
||
|
class Completion;
|
||
|
class ExecState;
|
||
|
|
||
|
/**
|
||
|
* Primitive types
|
||
|
*/
|
||
|
enum Type {
|
||
|
UnspecifiedType = 0,
|
||
|
UndefinedType = 1,
|
||
|
NullType = 2,
|
||
|
BooleanType = 3,
|
||
|
StringType = 4,
|
||
|
NumberType = 5,
|
||
|
ObjectType = 6
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* ValueImp is the base type for all primitives (Undefined, Null, Boolean,
|
||
|
* String, Number) and objects in ECMAScript.
|
||
|
*
|
||
|
* Note: you should never inherit from ValueImp as it is for primitive types
|
||
|
* only (all of which are provided internally by KJS). Instead, inherit from
|
||
|
* ObjectImp.
|
||
|
*/
|
||
|
class KJS_EXPORT ValueImp {
|
||
|
friend class Collector;
|
||
|
friend class Value;
|
||
|
friend class ContextImp;
|
||
|
public:
|
||
|
ValueImp();
|
||
|
virtual ~ValueImp();
|
||
|
|
||
|
ValueImp* ref() { if (!SimpleNumber::is(this)) refcount++; return this; }
|
||
|
bool deref() { if (SimpleNumber::is(this)) return false; else return (!--refcount); }
|
||
|
|
||
|
virtual void mark();
|
||
|
bool marked() const;
|
||
|
void* operator new(size_t);
|
||
|
void operator delete(void*);
|
||
|
|
||
|
/**
|
||
|
* @internal
|
||
|
*
|
||
|
* set by Object() so that the collector is allowed to delete us
|
||
|
*/
|
||
|
void setGcAllowed();
|
||
|
|
||
|
// Will crash if called on a simple number.
|
||
|
void setGcAllowedFast() { _flags |= VI_GCALLOWED; }
|
||
|
|
||
|
int toInteger(ExecState *exec) const;
|
||
|
int toInt32(ExecState *exec) const;
|
||
|
unsigned int toUInt32(ExecState *exec) const;
|
||
|
unsigned short toUInt16(ExecState *exec) const;
|
||
|
|
||
|
// Dispatch wrappers that handle the special small number case
|
||
|
|
||
|
Type dispatchType() const;
|
||
|
Value dispatchToPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const;
|
||
|
bool dispatchToBoolean(ExecState *exec) const;
|
||
|
double dispatchToNumber(ExecState *exec) const;
|
||
|
UString dispatchToString(ExecState *exec) const;
|
||
|
bool dispatchToUInt32(unsigned&) const;
|
||
|
Object dispatchToObject(ExecState *exec) const;
|
||
|
|
||
|
unsigned short int refcount;
|
||
|
|
||
|
bool isDestroyed() const { return _flags & VI_DESTRUCTED; }
|
||
|
|
||
|
private:
|
||
|
unsigned short int _flags;
|
||
|
|
||
|
virtual Type type() const = 0;
|
||
|
|
||
|
// The conversion operations
|
||
|
|
||
|
virtual Value toPrimitive(ExecState *exec, Type preferredType = UnspecifiedType) const = 0;
|
||
|
virtual bool toBoolean(ExecState *exec) const = 0;
|
||
|
virtual double toNumber(ExecState *exec) const = 0;
|
||
|
// TODO: no need for the following 4 int conversions to be virtual
|
||
|
virtual UString toString(ExecState *exec) const = 0;
|
||
|
virtual Object toObject(ExecState *exec) const = 0;
|
||
|
virtual bool toUInt32(unsigned&) const;
|
||
|
|
||
|
enum {
|
||
|
VI_MARKED = 1,
|
||
|
VI_GCALLOWED = 2,
|
||
|
VI_CREATED = 4,
|
||
|
VI_DESTRUCTED = 8 // nice word we have here :)
|
||
|
}; // VI means VALUEIMPL
|
||
|
|
||
|
ValueImpPrivate *_vd;
|
||
|
|
||
|
// Give a compile time error if we try to copy one of these.
|
||
|
ValueImp(const ValueImp&);
|
||
|
ValueImp& operator=(const ValueImp&);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Value objects are act as wrappers ("smart pointers") around ValueImp
|
||
|
* objects and their descendents. Instead of using ValueImps
|
||
|
* (and derivatives) during normal program execution, you should use a
|
||
|
* Value-derived class.
|
||
|
*
|
||
|
* Value maintains a pointer to a ValueImp object and uses a reference
|
||
|
* counting scheme to ensure that the ValueImp object is not deleted or
|
||
|
* garbage collected.
|
||
|
*
|
||
|
* Note: The conversion operations all return values of various types -
|
||
|
* if an error occurs during conversion, an error object will instead
|
||
|
* be returned (where possible), and the execution state's exception
|
||
|
* will be set appropriately.
|
||
|
*/
|
||
|
class KJS_EXPORT Value {
|
||
|
public:
|
||
|
Value() : rep(0) { }
|
||
|
explicit Value(ValueImp *v);
|
||
|
Value(const Value &v);
|
||
|
~Value();
|
||
|
|
||
|
Value& operator=(const Value &v);
|
||
|
/**
|
||
|
* Returns whether or not this is a valid value. An invalid value
|
||
|
* has a 0 implementation pointer and should not be used for
|
||
|
* any other operation than this check. Current use: as a
|
||
|
* distinct return value signalling failing dynamicCast() calls.
|
||
|
*/
|
||
|
bool isValid() const { return rep != 0; }
|
||
|
/**
|
||
|
* @deprecated
|
||
|
* Use !isValid() instead.
|
||
|
*/
|
||
|
bool isNull() const { return rep == 0; }
|
||
|
ValueImp *imp() const { return rep; }
|
||
|
|
||
|
/**
|
||
|
* Returns the type of value. This is one of UndefinedType, NullType,
|
||
|
* BooleanType, StringType, NumberType, or ObjectType.
|
||
|
*
|
||
|
* @return The type of value
|
||
|
*/
|
||
|
Type type() const { return rep->dispatchType(); }
|
||
|
|
||
|
/**
|
||
|
* Checks whether or not the value is of a particular tpye
|
||
|
*
|
||
|
* @param t The type to compare with
|
||
|
* @return true if the value is of the specified type, otherwise false
|
||
|
*/
|
||
|
bool isA(Type t) const { return rep->dispatchType() == t; }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToPrimitive type conversion operation on this value
|
||
|
* (ECMA 9.1)
|
||
|
*/
|
||
|
Value toPrimitive(ExecState *exec,
|
||
|
Type preferredType = UnspecifiedType) const
|
||
|
{ return rep->dispatchToPrimitive(exec, preferredType); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToBoolean type conversion operation on this value (ECMA 9.2)
|
||
|
*/
|
||
|
bool toBoolean(ExecState *exec) const { return rep->dispatchToBoolean(exec); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToNumber type conversion operation on this value (ECMA 9.3)
|
||
|
*/
|
||
|
double toNumber(ExecState *exec) const { return rep->dispatchToNumber(exec); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToInteger type conversion operation on this value (ECMA 9.4)
|
||
|
*/
|
||
|
int toInteger(ExecState *exec) const { return rep->toInteger(exec); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToInt32 type conversion operation on this value (ECMA 9.5)
|
||
|
*/
|
||
|
int toInt32(ExecState *exec) const { return rep->toInt32(exec); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToUInt32 type conversion operation on this value (ECMA 9.6)
|
||
|
*/
|
||
|
unsigned int toUInt32(ExecState *exec) const { return rep->toUInt32(exec); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToUInt16 type conversion operation on this value (ECMA 9.7)
|
||
|
*/
|
||
|
unsigned short toUInt16(ExecState *exec) const { return rep->toUInt16(exec); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToString type conversion operation on this value (ECMA 9.8)
|
||
|
*/
|
||
|
UString toString(ExecState *exec) const { return rep->dispatchToString(exec); }
|
||
|
|
||
|
/**
|
||
|
* Performs the ToObject type conversion operation on this value (ECMA 9.9)
|
||
|
*/
|
||
|
Object toObject(ExecState *exec) const;
|
||
|
|
||
|
/**
|
||
|
* Checks if we can do a lossless conversion to UInt32.
|
||
|
*/
|
||
|
bool toUInt32(unsigned& i) const { return rep->dispatchToUInt32(i); }
|
||
|
|
||
|
protected:
|
||
|
ValueImp *rep;
|
||
|
};
|
||
|
|
||
|
// Primitive types
|
||
|
|
||
|
/**
|
||
|
* Represents an primitive Undefined value. All instances of this class
|
||
|
* share the same implementation object, so == will always return true
|
||
|
* for any comparison between two Undefined objects.
|
||
|
*/
|
||
|
class KJS_EXPORT Undefined : public Value {
|
||
|
public:
|
||
|
Undefined();
|
||
|
|
||
|
/**
|
||
|
* Converts a Value into an Undefined. If the value's type is not
|
||
|
* UndefinedType, a null object will be returned (i.e. one with it's
|
||
|
* internal pointer set to 0). If you do not know for sure whether the
|
||
|
* value is of type UndefinedType, you should check the isValid()
|
||
|
* methods afterwards before calling any methods on the returned value.
|
||
|
*
|
||
|
* @return The value converted to an Undefined
|
||
|
*/
|
||
|
static Undefined dynamicCast(const Value &v);
|
||
|
private:
|
||
|
friend class UndefinedImp;
|
||
|
explicit Undefined(UndefinedImp *v);
|
||
|
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Represents an primitive Null value. All instances of this class
|
||
|
* share the same implementation object, so == will always return true
|
||
|
* for any comparison between two Null objects.
|
||
|
*/
|
||
|
class KJS_EXPORT Null : public Value {
|
||
|
public:
|
||
|
Null();
|
||
|
|
||
|
/**
|
||
|
* Converts a Value into an Null. If the value's type is not NullType,
|
||
|
* a null object will be returned (i.e. one with it's internal pointer set
|
||
|
* to 0). If you do not know for sure whether the value is of type
|
||
|
* NullType, you should check the isValid() methods afterwards before
|
||
|
* calling any methods on the returned value.
|
||
|
*
|
||
|
* @return The value converted to a Null
|
||
|
*/
|
||
|
static Null dynamicCast(const Value &v);
|
||
|
private:
|
||
|
friend class NullImp;
|
||
|
explicit Null(NullImp *v);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Represents an primitive Boolean value
|
||
|
*/
|
||
|
class KJS_EXPORT Boolean : public Value {
|
||
|
public:
|
||
|
Boolean(bool b = false);
|
||
|
|
||
|
/**
|
||
|
* Converts a Value into an Boolean. If the value's type is not BooleanType,
|
||
|
* a null object will be returned (i.e. one with it's internal pointer set
|
||
|
* to 0). If you do not know for sure whether the value is of type
|
||
|
* BooleanType, you should check the isValid() methods afterwards before
|
||
|
* calling any methods on the returned value.
|
||
|
*
|
||
|
* @return The value converted to a Boolean
|
||
|
*/
|
||
|
static Boolean dynamicCast(const Value &v);
|
||
|
|
||
|
bool value() const;
|
||
|
private:
|
||
|
friend class BooleanImp;
|
||
|
explicit Boolean(BooleanImp *v);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Represents an primitive String value
|
||
|
*/
|
||
|
class KJS_EXPORT String : public Value {
|
||
|
public:
|
||
|
String(const UString &s = "");
|
||
|
|
||
|
/**
|
||
|
* Converts a Value into an String. If the value's type is not StringType,
|
||
|
* a null object will be returned (i.e. one with it's internal pointer set
|
||
|
* to 0). If you do not know for sure whether the value is of type
|
||
|
* StringType, you should check the isValid() methods afterwards before
|
||
|
* calling any methods on the returned value.
|
||
|
*
|
||
|
* @return The value converted to a String
|
||
|
*/
|
||
|
static String dynamicCast(const Value &v);
|
||
|
|
||
|
UString value() const;
|
||
|
private:
|
||
|
friend class StringImp;
|
||
|
explicit String(StringImp *v);
|
||
|
};
|
||
|
|
||
|
extern const double NaN;
|
||
|
extern const double Inf;
|
||
|
|
||
|
/**
|
||
|
* Represents an primitive Number value
|
||
|
*/
|
||
|
class KJS_EXPORT Number : public Value {
|
||
|
friend class ValueImp;
|
||
|
public:
|
||
|
Number(int i);
|
||
|
Number(unsigned int u);
|
||
|
Number(double d = 0.0);
|
||
|
Number(long int l);
|
||
|
Number(long unsigned int l);
|
||
|
|
||
|
double value() const;
|
||
|
int intValue() const;
|
||
|
|
||
|
bool isNaN() const;
|
||
|
bool isInf() const;
|
||
|
|
||
|
/**
|
||
|
* Converts a Value into an Number. If the value's type is not NumberType,
|
||
|
* a null object will be returned (i.e. one with it's internal pointer set
|
||
|
* to 0). If you do not know for sure whether the value is of type
|
||
|
* NumberType, you should check the isNull() methods afterwards before
|
||
|
* calling any methods on the returned value.
|
||
|
*
|
||
|
* @return The value converted to a Number
|
||
|
*/
|
||
|
static Number dynamicCast(const Value &v);
|
||
|
private:
|
||
|
friend class NumberImp;
|
||
|
explicit Number(NumberImp *v);
|
||
|
};
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
#endif // _KJS_VALUE_H_
|