, context(context)
, fullyCreated(false)
{
- type = Type_ArgumentsObject;
flags &= ~SimpleArray;
ExecutionEngine *v4 = context->engine;
struct ArgumentsObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(ArgumentsObject)
CallContext *context;
bool fullyCreated;
QVector<SafeValue> mappedArguments;
const ManagedVTable ExecutionContext::static_vtbl =
{
+ ExecutionContext::IsExecutionContext,
+ ExecutionContext::IsString,
+ ExecutionContext::IsObject,
+ ExecutionContext::IsFunctionObject,
+ ExecutionContext::IsErrorObject,
+ 0,
+ ExecutionContext::MyType,
call,
construct,
markObjects,
struct Q_QML_EXPORT ExecutionContext : public Managed
{
Q_MANAGED
+ Q_MANAGED_TYPE(ExecutionContext)
+ enum {
+ IsExecutionContext = true
+ };
enum ContextType {
Type_GlobalContext = 0x1,
: Object(engine->dateClass)
{
setVTable(&static_vtbl);
- type = Type_DateObject;
value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN());
}
struct DateObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(DateObject)
SafeValue value;
DateObject(ExecutionEngine *engine, const ValueRef date): Object(engine->dateClass) {
- type = Type_DateObject;
value = date;
}
DateObject(ExecutionEngine *engine, const QDateTime &value);
protected:
DateObject(InternalClass *ic): Object(ic) {
- setVTable(&static_vtbl);
- type = Type_DateObject;
+ Q_ASSERT(internalClass->vtable == &static_vtbl);
value = Primitive::fromDouble(qSNaN());
}
};
initRootContext();
- StringPrototype *stringPrototype = new (memoryManager) StringPrototype(objectClass);
+ StringPrototype *stringPrototype = new (memoryManager) StringPrototype(InternalClass::create(this, &StringPrototype::static_vtbl, objectPrototype));
stringObjectClass = InternalClass::create(this, &String::static_vtbl, stringPrototype);
- NumberPrototype *numberPrototype = new (memoryManager) NumberPrototype(objectClass);
+ NumberPrototype *numberPrototype = new (memoryManager) NumberPrototype(InternalClass::create(this, &NumberPrototype::static_vtbl, objectPrototype));
numberClass = InternalClass::create(this, &NumberObject::static_vtbl, numberPrototype);
- BooleanPrototype *booleanPrototype = new (memoryManager) BooleanPrototype(objectClass);
+ BooleanPrototype *booleanPrototype = new (memoryManager) BooleanPrototype(InternalClass::create(this, &BooleanPrototype::static_vtbl, objectPrototype));
booleanClass = InternalClass::create(this, &BooleanObject::static_vtbl, booleanPrototype);
- DatePrototype *datePrototype = new (memoryManager) DatePrototype(objectClass);
+ DatePrototype *datePrototype = new (memoryManager) DatePrototype(InternalClass::create(this, &DatePrototype::static_vtbl, objectPrototype));
dateClass = InternalClass::create(this, &DateObject::static_vtbl, datePrototype);
FunctionPrototype *functionPrototype = new (memoryManager) FunctionPrototype(InternalClass::create(this, &FunctionPrototype::static_vtbl, objectPrototype));
protoClass = objectClass->addMember(id_constructor, Attr_NotEnumerable, &index);
Q_ASSERT(index == FunctionObject::Index_ProtoConstructor);
- RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(objectClass);
+ RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(InternalClass::create(this, &RegExpPrototype::static_vtbl, objectPrototype));
regExpClass = InternalClass::create(this, &RegExpObject::static_vtbl, regExpPrototype);
regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayIndex);
regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
- ErrorPrototype *errorPrototype = new (memoryManager) ErrorPrototype(objectClass);
+ ErrorPrototype *errorPrototype = new (memoryManager) ErrorPrototype(InternalClass::create(this, &ErrorObject::static_vtbl, objectPrototype));
errorClass = InternalClass::create(this, &ErrorObject::static_vtbl, errorPrototype);
EvalErrorPrototype *evalErrorPrototype = new (memoryManager) EvalErrorPrototype(errorClass);
evalErrorClass = InternalClass::create(this, &EvalErrorObject::static_vtbl, evalErrorPrototype);
globalObject->defineDefaultProperty(QStringLiteral("TypeError"), typeErrorCtor);
globalObject->defineDefaultProperty(QStringLiteral("URIError"), uRIErrorCtor);
ScopedObject o(scope);
- globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = new (memoryManager) MathObject(this)));
- globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = new (memoryManager) JsonObject(this)));
+ globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = new (memoryManager) MathObject(QV4::InternalClass::create(this, &MathObject::static_vtbl, objectPrototype))));
+ globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = new (memoryManager) JsonObject(QV4::InternalClass::create(this, &JsonObject::static_vtbl, objectPrototype))));
globalObject->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
globalObject->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
-
Scope scope(engine());
ScopedValue protectThis(scope, this);
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
subtype = t;
Scope scope(engine());
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
subtype = t;
Scope scope(engine());
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
subtype = t;
Scope scope(engine());
struct ErrorObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(ErrorObject)
+ enum {
+ IsErrorObject = true
+ };
enum ErrorType {
Error,
{
name = ic->engine->id_undefined;
- type = Type_FunctionObject;
needsActivation = false;
strictMode = false;
}
Scope s(internalClass->engine);
ScopedValue protectThis(s, this);
- type = Type_FunctionObject;
needsActivation = true;
strictMode = false;
#ifndef QT_NO_DEBUG
struct Q_QML_EXPORT FunctionObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(FunctionObject)
+ enum {
+ IsFunctionObject = true
+ };
// Used with Managed::subType
enum FunctionType {
RegularFunction = 0,
#endif
+DEFINE_MANAGED_VTABLE(JsonObject);
+
class JsonParser
{
public:
}
-JsonObject::JsonObject(ExecutionEngine *engine)
- : Object(engine)
+JsonObject::JsonObject(InternalClass *ic)
+ : Object(ic)
{
- type = Type_JSONObject;
-
- Scope scope(engine);
+ Scope scope(ic->engine);
ScopedObject protectThis(scope, this);
defineDefaultProperty(QStringLiteral("parse"), method_parse, 2);
namespace QV4 {
struct JsonObject : Object {
+ Q_MANAGED_TYPE(JsonObject)
+ Q_MANAGED
private:
typedef QSet<QV4::Object *> V4ObjectSet;
public:
- JsonObject(ExecutionEngine *engine);
+ JsonObject(InternalClass *ic);
static ReturnedValue method_parse(CallContext *ctx);
static ReturnedValue method_stringify(CallContext *ctx);
const ManagedVTable Managed::static_vtbl =
{
+ Managed::IsExecutionContext,
+ Managed::IsString,
+ Managed::IsObject,
+ Managed::IsFunctionObject,
+ Managed::IsErrorObject,
+ 0,
+ Managed::MyType,
call,
construct,
0 /*markObjects*/,
QString Managed::className() const
{
const char *s = 0;
- switch (Type(type)) {
+ switch (Type(internalClass->vtable->type)) {
case Type_Invalid:
case Type_String:
return QString();
case Type_ArgumentsObject:
s = "Arguments";
break;
- case Type_JSONObject:
+ case Type_JsonObject:
s = "JSON";
break;
case Type_MathObject:
s = "Math";
break;
+
+ case Type_ExecutionContext:
+ s = "__ExecutionContext";
+ break;
case Type_ForeachIteratorObject:
s = "__ForeachIterator";
break;
case Type_RegExp:
- s = "RegExp";
+ s = "__RegExp";
break;
+
case Type_QmlSequence:
s = "QmlSequence";
break;
template <typename T> \
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+#define Q_MANAGED_TYPE(type) \
+ public: \
+ enum { MyType = Type_##type };
struct GCDeletable
{
struct ManagedVTable
{
+ uint isExecutionContext : 1;
+ uint isString : 1;
+ uint isObject : 1;
+ uint isFunctionObject : 1;
+ uint isErrorObject : 1;
+ uint unused : 19;
+ uint type : 8;
ReturnedValue (*call)(Managed *, CallData *data);
ReturnedValue (*construct)(Managed *, CallData *data);
void (*markObjects)(Managed *, ExecutionEngine *e);
#define DEFINE_MANAGED_VTABLE(classname) \
const QV4::ManagedVTable classname::static_vtbl = \
{ \
+ classname::IsExecutionContext, \
+ classname::IsString, \
+ classname::IsObject, \
+ classname::IsFunctionObject, \
+ classname::IsErrorObject, \
+ 0, \
+ classname::MyType, \
call, \
construct, \
markObjects, \
#classname \
}
+#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
+const QV4::ManagedVTable classname::static_vtbl = \
+{ \
+ classname::IsExecutionContext, \
+ classname::IsString, \
+ classname::IsObject, \
+ classname::IsFunctionObject, \
+ classname::IsErrorObject, \
+ 0, \
+ classname::MyType, \
+ call, \
+ construct, \
+ markObjects, \
+ destroy, \
+ 0, \
+ get, \
+ getIndexed, \
+ put, \
+ putIndexed, \
+ query, \
+ queryIndexed, \
+ deleteProperty, \
+ deleteIndexedProperty, \
+ getLookup, \
+ setLookup, \
+ isEqualTo, \
+ advanceIterator, \
+ #name \
+}
+
#define DEFINE_MANAGED_VTABLE_WITH_DELETABLES(classname) \
const QV4::ManagedVTable classname::static_vtbl = \
{ \
+ classname::IsExecutionContext, \
+ classname::IsString, \
+ classname::IsObject, \
+ classname::IsFunctionObject, \
+ classname::IsErrorObject, \
+ 0, \
+ classname::MyType, \
call, \
construct, \
markObjects, \
struct Q_QML_EXPORT Managed
{
Q_MANAGED
+ enum {
+ IsExecutionContext = false,
+ IsString = false,
+ IsObject = false,
+ IsFunctionObject = false,
+ IsErrorObject = false
+ };
private:
void *operator new(size_t);
Managed(const Managed &other);
Type_RegExpObject,
Type_ErrorObject,
Type_ArgumentsObject,
- Type_JSONObject,
+ Type_JsonObject,
Type_MathObject,
+
+ Type_ExecutionContext,
Type_ForeachIteratorObject,
Type_RegExp,
Type_QmlSequence
};
+ Q_MANAGED_TYPE(Invalid)
ExecutionEngine *engine() const;
return internalClass->vtable == &T::static_vtbl ? static_cast<const T *>(this) : 0;
}
- String *asString() { return type == Type_String ? reinterpret_cast<String *>(this) : 0; }
- Object *asObject() { return type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
- ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
- FunctionObject *asFunctionObject() { return type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
- BooleanObject *asBooleanObject() { return type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
- NumberObject *asNumberObject() { return type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
- StringObject *asStringObject() { return type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
- DateObject *asDateObject() { return type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
- ErrorObject *asErrorObject() { return type == Type_ErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
- ArgumentsObject *asArgumentsObject() { return type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
+ String *asString() { return internalClass->vtable->type == Type_String ? reinterpret_cast<String *>(this) : 0; }
+ Object *asObject() { return internalClass->vtable->type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
+ ArrayObject *asArrayObject() { return internalClass->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
+ FunctionObject *asFunctionObject() { return internalClass->vtable->type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
+ BooleanObject *asBooleanObject() { return internalClass->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
+ NumberObject *asNumberObject() { return internalClass->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
+ StringObject *asStringObject() { return internalClass->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
+ DateObject *asDateObject() { return internalClass->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
+ ErrorObject *asErrorObject() { return internalClass->vtable->type == Type_ErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
+ ArgumentsObject *asArgumentsObject() { return internalClass->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
- bool isListType() const { return type == Type_QmlSequence; }
+ bool isListType() const { return internalClass->vtable->type == Type_QmlSequence; }
- bool isArrayObject() const { return type == Type_ArrayObject; }
- bool isStringObject() const { return type == Type_StringObject; }
+ bool isArrayObject() const { return internalClass->vtable->type == Type_ArrayObject; }
+ bool isStringObject() const { return internalClass->vtable->type == Type_StringObject; }
QString className() const;
static void setLookup(Managed *m, Lookup *l, const ValueRef v);
static bool isEqualTo(Managed *m, Managed *other);
- uint internalType() const {
- return type;
- }
-
ReturnedValue asReturnedValue() { return Value::fromManaged(this).asReturnedValue(); }
uchar strictMode : 1; // used by FunctionObject
uchar bindingKeyFlag : 1;
uchar hasAccessorProperty : 1;
- uchar type;
+ uchar _type;
mutable uchar subtype;
uchar flags;
};
using namespace QV4;
+DEFINE_MANAGED_VTABLE(MathObject);
+
static const double qt_PI = 2.0 * ::asin(1.0);
-MathObject::MathObject(ExecutionEngine *engine)
- : Object(engine)
+MathObject::MathObject(InternalClass *ic)
+ : Object(ic)
{
- type = Type_MathObject;
-
- Scope scope(engine);
+ Scope scope(ic->engine);
ScopedObject protectThis(scope, this);
defineReadonlyProperty(QStringLiteral("E"), Primitive::fromDouble(::exp(1.0)));
struct MathObject: Object
{
- MathObject(ExecutionEngine *engine);
+ Q_MANAGED
+ Q_MANAGED_TYPE(MathObject)
+ MathObject(InternalClass *ic);
static ReturnedValue method_abs(CallContext *context);
static ReturnedValue method_acos(CallContext *context);
: Managed(engine->objectClass)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
{
- type = Type_Object;
flags = SimpleArray;
}
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
{
Q_ASSERT(internalClass->vtable && internalClass->vtable != &Managed::static_vtbl);
- type = Type_Object;
flags = SimpleArray;
if (internalClass->size >= memberDataAlloc) {
{
Q_UNUSED(engine);
- type = Type_ArrayObject;
memberData[LengthPropertyIndex].value = Primitive::fromInt32(0);
}
struct Q_QML_EXPORT Object: Managed {
Q_MANAGED
+ Q_MANAGED_TYPE(Object)
+ enum {
+ IsObject = true
+ };
uint memberDataAlloc;
Property *memberData;
struct BooleanObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(BooleanObject)
SafeValue value;
BooleanObject(ExecutionEngine *engine, const ValueRef val)
: Object(engine->booleanClass) {
- type = Type_BooleanObject;
value = val;
}
protected:
BooleanObject(InternalClass *ic)
: Object(ic) {
- setVTable(&static_vtbl);
- type = Type_BooleanObject;
+ Q_ASSERT(internalClass->vtable == &static_vtbl);
value = Encode(false);
}
};
struct NumberObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(NumberObject)
SafeValue value;
NumberObject(ExecutionEngine *engine, const ValueRef val)
: Object(engine->numberClass) {
- type = Type_NumberObject;
value = val;
}
protected:
NumberObject(InternalClass *ic)
: Object(ic) {
- setVTable(&static_vtbl);
- type = Type_NumberObject;
+ Q_ASSERT(internalClass->vtable == &static_vtbl);
value = Encode((int)0);
}
};
struct ArrayObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(ArrayObject)
enum {
LengthPropertyIndex = 0
};
struct ForEachIteratorObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(ForeachIteratorObject)
ObjectIterator it;
ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
: Object(ctx->engine), it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
setVTable(&static_vtbl);
- type = Type_ForeachIteratorObject;
}
ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
void ObjectPrototype::init(ExecutionEngine *v4, ObjectRef ctor)
{
Scope scope(v4);
- ScopedObject o(scope);
+ ScopedObject o(scope, this);
- ctor->defineReadonlyProperty(v4->id_prototype, (o = this));
+ ctor->defineReadonlyProperty(v4->id_prototype, o);
ctor->defineReadonlyProperty(v4->id_length, Primitive::fromInt32(1));
ctor->defineDefaultProperty(QStringLiteral("getPrototypeOf"), method_getPrototypeOf, 1);
ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyDescriptor"), method_getOwnPropertyDescriptor, 2);
, m_ignoreCase(ignoreCase)
, m_multiLine(multiline)
{
- type = Type_RegExpObject;
-
if (!engine)
return;
const char* error = 0;
class RegExp : public Managed
{
Q_MANAGED
+ Q_MANAGED_TYPE(RegExp)
public:
static RegExp* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false);
~RegExp();
, value(RegExp::create(ic->engine, QString(), false, false))
, global(false)
{
+ Q_ASSERT(internalClass->vtable == &static_vtbl);
init(ic->engine);
}
void RegExpObject::init(ExecutionEngine *engine)
{
setVTable(&static_vtbl);
- type = Type_RegExpObject;
Scope scope(engine);
ScopedObject protectThis(scope, this);
struct RegExpObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(RegExpObject)
// needs to be compatible with the flags in qv4jsir_p.h
enum Flags {
RegExp_Global = 0x01,
class QQmlSequence : public QV4::Object
{
Q_MANAGED
+ Q_MANAGED_TYPE(QmlSequence)
public:
QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
: QV4::Object(InternalClass::create(engine, &static_vtbl, engine->sequencePrototype.asObject()))
, m_propertyIndex(-1)
, m_isReference(false)
{
- type = Type_QmlSequence;
flags &= ~SimpleArray;
QV4::Scope scope(engine);
QV4::ScopedObject protectThis(scope, this);
, m_propertyIndex(propertyIndex)
, m_isReference(true)
{
- type = Type_QmlSequence;
flags &= ~SimpleArray;
QV4::Scope scope(engine);
QV4::ScopedObject protectThis(scope, this);
const ManagedVTable String::static_vtbl =
{
+ String::IsExecutionContext,
+ String::IsString,
+ String::IsObject,
+ String::IsFunctionObject,
+ String::IsErrorObject,
+ 0,
+ String::MyType,
call,
construct,
markObjects,
if (t == o)
return true;
- if (o->type != Type_String)
+ if (o->internalClass->vtable->type != Type_String)
return false;
- Q_ASSERT(t->type == Type_String);
+ Q_ASSERT(t->internalClass->vtable->type == Type_String);
String *that = static_cast<String *>(t);
String *other = static_cast<String *>(o);
if (that->hashValue() != other->hashValue())
{
_text->ref.ref();
len = _text->size;
- type = Type_String;
subtype = StringType_Unknown;
}
, stringHash(UINT_MAX), largestSubLength(qMax(l->largestSubLength, r->largestSubLength))
, len(l->len + r->len)
{
- type = Type_String;
subtype = StringType_Unknown;
if (!l->largestSubLength && l->len > largestSubLength)
struct Q_QML_EXPORT String : public Managed {
Q_MANAGED
+ Q_MANAGED_TYPE(String)
+ enum {
+ IsString = true
+ };
+
enum StringType {
StringType_Unknown,
StringType_Regular,
String()
: Managed(0), _text(QStringData::sharedNull()), identifier(0)
, stringHash(UINT_MAX), largestSubLength(0), len(0)
- { type = Type_String; subtype = StringType_Unknown; }
+ { subtype = StringType_Unknown; }
String(ExecutionEngine *engine, const QString &text);
String(ExecutionEngine *engine, String *l, String *n);
~String() {
StringObject::StringObject(InternalClass *ic)
: Object(ic)
{
- setVTable(&static_vtbl);
- type = Type_StringObject;
+ Q_ASSERT(internalClass->vtable == &static_vtbl);
Scope scope(engine());
ScopedObject protectThis(scope, this);
: Object(engine->stringObjectClass)
{
setVTable(&static_vtbl);
- type = Type_StringObject;
Scope scope(engine);
ScopedObject protectThis(scope, this);
struct StringObject: Object {
Q_MANAGED
+ Q_MANAGED_TYPE(StringObject)
SafeValue value;
mutable Property tmpProperty;
{
if (!isManaged())
return false;
- return managed() && managed()->type == Managed::Type_String;
+ return managed() && managed()->internalClass->vtable->isString;
}
inline bool Value::isObject() const
{
if (!isManaged())
return false;
- return managed() && managed()->type != Managed::Type_String;
+ return managed() && managed()->internalClass->vtable->isObject;
}
inline bool Value::isPrimitive() const
: QV4::Object(engine)
{
setVTable(&static_vtbl);
- type = Type_Object;
}
QLocale locale;