Extend the ReturnedValue mechanism to pointers to Managed objects
Add a Returned<T> that we can return instead of raw pointers to Managed objects. Start using the Returned<T> for a few methods. Also clean up all our classes to use the Q_MANAGED macro instead of manually defining their vtable. Change-Id: I0a2962e47f3de955cd2cd8474f8f3fcc9e36d084 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
parent
2a43ec129a
commit
49aead7f23
|
@ -50,32 +50,29 @@ namespace QV4 {
|
|||
|
||||
struct ArgumentsGetterFunction: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
uint index;
|
||||
|
||||
ArgumentsGetterFunction(ExecutionContext *scope, uint index)
|
||||
: FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
|
||||
|
||||
static ReturnedValue call(Managed *that, CallData *d);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct ArgumentsSetterFunction: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
uint index;
|
||||
|
||||
ArgumentsSetterFunction(ExecutionContext *scope, uint index)
|
||||
: FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
|
||||
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
|
||||
struct ArgumentsObject: Object {
|
||||
Q_MANAGED
|
||||
CallContext *context;
|
||||
QVector<Value> mappedArguments;
|
||||
ArgumentsObject(CallContext *context);
|
||||
|
@ -90,7 +87,6 @@ struct ArgumentsObject: Object {
|
|||
|
||||
static void markObjects(Managed *that);
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
static void destroy(Managed *);
|
||||
};
|
||||
|
||||
|
|
|
@ -51,13 +51,11 @@ namespace QV4 {
|
|||
|
||||
struct ArrayCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
ArrayCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct ArrayPrototype: ArrayObject
|
||||
|
|
|
@ -54,13 +54,13 @@ BooleanCtor::BooleanCtor(ExecutionContext *scope)
|
|||
ReturnedValue BooleanCtor::construct(Managed *m, CallData *callData)
|
||||
{
|
||||
bool n = callData->argc ? callData->args[0].toBoolean() : false;
|
||||
return Value::fromObject(m->engine()->newBooleanObject(Value::fromBoolean(n))).asReturnedValue();
|
||||
return Encode(m->engine()->newBooleanObject(Value::fromBoolean(n)));
|
||||
}
|
||||
|
||||
ReturnedValue BooleanCtor::call(Managed *, CallData *callData)
|
||||
{
|
||||
bool value = callData->argc ? callData->args[0].toBoolean() : 0;
|
||||
return Value::fromBoolean(value).asReturnedValue();
|
||||
return Encode(value);
|
||||
}
|
||||
|
||||
void BooleanPrototype::init(ExecutionContext *ctx, const Value &ctor)
|
||||
|
|
|
@ -51,13 +51,11 @@ namespace QV4 {
|
|||
|
||||
struct BooleanCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
BooleanCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct BooleanPrototype: BooleanObject
|
||||
|
|
|
@ -64,13 +64,11 @@ protected:
|
|||
|
||||
struct DateCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
DateCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct DatePrototype: DateObject
|
||||
|
|
|
@ -381,16 +381,16 @@ Object *ExecutionEngine::newStringObject(const Value &value)
|
|||
return object;
|
||||
}
|
||||
|
||||
Object *ExecutionEngine::newNumberObject(const Value &value)
|
||||
Returned<Object> *ExecutionEngine::newNumberObject(const Value &value)
|
||||
{
|
||||
NumberObject *object = new (memoryManager) NumberObject(this, value);
|
||||
return object;
|
||||
return object->asReturned<Object>();
|
||||
}
|
||||
|
||||
Object *ExecutionEngine::newBooleanObject(const Value &value)
|
||||
Returned<Object> *ExecutionEngine::newBooleanObject(const Value &value)
|
||||
{
|
||||
Object *object = new (memoryManager) BooleanObject(this, value);
|
||||
return object;
|
||||
return object->asReturned<Object>();
|
||||
}
|
||||
|
||||
ArrayObject *ExecutionEngine::newArrayObject(int count)
|
||||
|
|
|
@ -271,8 +271,8 @@ struct Q_QML_EXPORT ExecutionEngine
|
|||
String *newIdentifier(const QString &text);
|
||||
|
||||
Object *newStringObject(const Value &value);
|
||||
Object *newNumberObject(const Value &value);
|
||||
Object *newBooleanObject(const Value &value);
|
||||
Returned<Object> *newNumberObject(const Value &value);
|
||||
Returned<Object> *newBooleanObject(const Value &value);
|
||||
|
||||
ArrayObject *newArrayObject(int count = 0);
|
||||
ArrayObject *newArrayObject(const QStringList &list);
|
||||
|
|
|
@ -93,11 +93,9 @@ struct ReferenceErrorObject: ErrorObject {
|
|||
};
|
||||
|
||||
struct SyntaxErrorObject: ErrorObject {
|
||||
Q_MANAGED
|
||||
SyntaxErrorObject(ExecutionEngine *engine, const Value &msg);
|
||||
SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct TypeErrorObject: ErrorObject {
|
||||
|
@ -111,74 +109,60 @@ struct URIErrorObject: ErrorObject {
|
|||
|
||||
struct ErrorCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
ErrorCtor(ExecutionContext *scope);
|
||||
ErrorCtor(ExecutionContext *scope, String *name);
|
||||
|
||||
static ReturnedValue construct(Managed *, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct EvalErrorCtor: ErrorCtor
|
||||
{
|
||||
Q_MANAGED
|
||||
EvalErrorCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct RangeErrorCtor: ErrorCtor
|
||||
{
|
||||
Q_MANAGED
|
||||
RangeErrorCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct ReferenceErrorCtor: ErrorCtor
|
||||
{
|
||||
Q_MANAGED
|
||||
ReferenceErrorCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct SyntaxErrorCtor: ErrorCtor
|
||||
{
|
||||
Q_MANAGED
|
||||
SyntaxErrorCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct TypeErrorCtor: ErrorCtor
|
||||
{
|
||||
Q_MANAGED
|
||||
TypeErrorCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct URIErrorCtor: ErrorCtor
|
||||
{
|
||||
Q_MANAGED
|
||||
URIErrorCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ struct InternalClass;
|
|||
struct Lookup;
|
||||
|
||||
struct Q_QML_EXPORT FunctionObject: Object {
|
||||
Q_MANAGED
|
||||
// Used with Managed::subType
|
||||
enum FunctionType {
|
||||
RegularFunction = 0,
|
||||
|
@ -135,7 +136,6 @@ struct Q_QML_EXPORT FunctionObject: Object {
|
|||
protected:
|
||||
FunctionObject(InternalClass *ic);
|
||||
|
||||
static const ManagedVTable static_vtbl;
|
||||
static void markObjects(Managed *that);
|
||||
static bool hasInstance(Managed *that, const Value &value);
|
||||
static void destroy(Managed *that)
|
||||
|
@ -144,13 +144,11 @@ protected:
|
|||
|
||||
struct FunctionCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
FunctionCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *that, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct FunctionPrototype: FunctionObject
|
||||
|
@ -165,15 +163,13 @@ struct FunctionPrototype: FunctionObject
|
|||
};
|
||||
|
||||
struct BuiltinFunction: FunctionObject {
|
||||
Q_MANAGED
|
||||
ReturnedValue (*code)(SimpleCallContext *);
|
||||
|
||||
BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *));
|
||||
|
||||
static ReturnedValue construct(Managed *, CallData *);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct IndexedBuiltinFunction: FunctionObject
|
||||
|
@ -203,26 +199,23 @@ struct IndexedBuiltinFunction: FunctionObject
|
|||
|
||||
|
||||
struct ScriptFunction: FunctionObject {
|
||||
Q_MANAGED
|
||||
ScriptFunction(ExecutionContext *scope, Function *function);
|
||||
|
||||
static ReturnedValue construct(Managed *, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct SimpleScriptFunction: FunctionObject {
|
||||
Q_MANAGED
|
||||
SimpleScriptFunction(ExecutionContext *scope, Function *function);
|
||||
|
||||
static ReturnedValue construct(Managed *, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct BoundFunction: FunctionObject {
|
||||
Q_MANAGED
|
||||
FunctionObject *target;
|
||||
Value boundThis;
|
||||
QVector<Value> boundArgs;
|
||||
|
@ -234,7 +227,6 @@ struct BoundFunction: FunctionObject {
|
|||
static ReturnedValue construct(Managed *, CallData *d);
|
||||
static ReturnedValue call(Managed *that, CallData *dd);
|
||||
|
||||
static const ManagedVTable static_vtbl;
|
||||
static void destroy(Managed *);
|
||||
static void markObjects(Managed *that);
|
||||
static bool hasInstance(Managed *that, const Value &value);
|
||||
|
|
|
@ -50,15 +50,13 @@ namespace QV4 {
|
|||
|
||||
struct Q_QML_EXPORT EvalFunction : FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
EvalFunction(ExecutionContext *scope);
|
||||
|
||||
ReturnedValue evalCall(Value thisObject, Value *args, int argc, bool directCall);
|
||||
|
||||
using Managed::construct;
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct GlobalFunctions
|
||||
|
|
|
@ -436,7 +436,7 @@ void Lookup::setterGeneric(Lookup *l, const Value &object, const Value &value)
|
|||
{
|
||||
Object *o = object.asObject();
|
||||
if (!o) {
|
||||
o = __qmljs_convert_to_object(l->name->engine()->current, ValueRef::fromRawValue(&object));
|
||||
o = __qmljs_convert_to_object(l->name->engine()->current, ValueRef::fromRawValue(&object))->getPointer();
|
||||
o->put(l->name, value);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -61,10 +61,22 @@ inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
|
|||
template <typename T1, typename T2>
|
||||
inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
|
||||
|
||||
template <typename T>
|
||||
struct Returned : private T
|
||||
{
|
||||
static Returned<T> *create(T *t) { return static_cast<Returned<T> *>(t); }
|
||||
T *getPointer() { return this; }
|
||||
template<typename X>
|
||||
static T *getPointer(Returned<X> *x) { return x->getPointer(); }
|
||||
};
|
||||
|
||||
#define Q_MANAGED \
|
||||
public: \
|
||||
Q_MANAGED_CHECK \
|
||||
static const QV4::ManagedVTable static_vtbl;
|
||||
static const QV4::ManagedVTable static_vtbl; \
|
||||
template <typename T> \
|
||||
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
|
||||
|
||||
|
||||
struct GCDeletable
|
||||
{
|
||||
|
@ -162,6 +174,7 @@ const QV4::ManagedVTable classname::static_vtbl = \
|
|||
|
||||
struct Q_QML_EXPORT Managed
|
||||
{
|
||||
Q_MANAGED
|
||||
private:
|
||||
void *operator new(size_t);
|
||||
Managed(const Managed &other);
|
||||
|
@ -319,9 +332,6 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
|
||||
static const ManagedVTable static_vtbl;
|
||||
|
||||
const ManagedVTable *vtbl;
|
||||
public:
|
||||
InternalClass *internalClass;
|
||||
|
|
|
@ -59,7 +59,7 @@ NumberCtor::NumberCtor(ExecutionContext *scope)
|
|||
ReturnedValue NumberCtor::construct(Managed *m, CallData *callData)
|
||||
{
|
||||
double dbl = callData->argc ? callData->args[0].toNumber() : 0.;
|
||||
return Value::fromObject(m->engine()->newNumberObject(Value::fromDouble(dbl))).asReturnedValue();
|
||||
return Encode(m->engine()->newNumberObject(Value::fromDouble(dbl)));
|
||||
}
|
||||
|
||||
ReturnedValue NumberCtor::call(Managed *, CallData *callData)
|
||||
|
|
|
@ -51,13 +51,11 @@ namespace QV4 {
|
|||
|
||||
struct NumberCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
NumberCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *that, CallData *callData);
|
||||
static ReturnedValue call(Managed *, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct NumberPrototype: NumberObject
|
||||
|
|
|
@ -105,6 +105,7 @@ typedef Value (*PropertyEnumeratorFunction)(Object *object);
|
|||
typedef PropertyAttributes (*PropertyQueryFunction)(const Object *object, String *name);
|
||||
|
||||
struct Q_QML_EXPORT Object: Managed {
|
||||
Q_MANAGED
|
||||
uint memberDataAlloc;
|
||||
Property *memberData;
|
||||
|
||||
|
@ -182,6 +183,9 @@ struct Q_QML_EXPORT Object: Managed {
|
|||
static Object *cast(const Value &v) {
|
||||
return v.asObject();
|
||||
}
|
||||
static Value toValue(Object *o) {
|
||||
return Value::fromObject(o);
|
||||
}
|
||||
|
||||
// Array handling
|
||||
|
||||
|
@ -283,7 +287,8 @@ public:
|
|||
void ensureArrayAttributes();
|
||||
|
||||
inline bool protoHasArray() {
|
||||
Object *p = this;
|
||||
Scope scope(engine());
|
||||
Scoped<Object> p(scope, this);
|
||||
|
||||
while ((p = p->prototype()))
|
||||
if (p->arrayDataLen)
|
||||
|
@ -313,7 +318,6 @@ public:
|
|||
using Managed::setLookup;
|
||||
using Managed::advanceIterator;
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
static void destroy(Managed *that);
|
||||
static void markObjects(Managed *that);
|
||||
static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
|
||||
|
|
|
@ -51,13 +51,11 @@ namespace QV4 {
|
|||
|
||||
struct ObjectCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
ObjectCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *that, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct ObjectPrototype: Object
|
||||
|
|
|
@ -559,7 +559,7 @@ ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object)
|
|||
} else {
|
||||
// If this object is tainted, we have to check to see if it is in our
|
||||
// tainted object list
|
||||
Scoped<Object> alternateWrapper(scope, 0);
|
||||
Scoped<Object> alternateWrapper(scope, (Object *)0);
|
||||
if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object)
|
||||
alternateWrapper = Value::fromObject(engine->m_multiplyWrappedQObjects->value(object));
|
||||
|
||||
|
|
|
@ -103,13 +103,11 @@ protected:
|
|||
|
||||
struct RegExpCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
RegExpCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct RegExpPrototype: RegExpObject
|
||||
|
|
|
@ -598,7 +598,7 @@ Bool __qmljs_to_boolean(const ValueRef value)
|
|||
}
|
||||
|
||||
|
||||
Object *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value)
|
||||
Returned<Object> *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value)
|
||||
{
|
||||
assert(!value->isObject());
|
||||
switch (value->type()) {
|
||||
|
@ -608,7 +608,7 @@ Object *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value)
|
|||
case Value::Boolean_Type:
|
||||
return ctx->engine->newBooleanObject(*value);
|
||||
case Value::String_Type:
|
||||
return ctx->engine->newStringObject(*value);
|
||||
return ctx->engine->newStringObject(*value)->asReturned<Object>();
|
||||
break;
|
||||
case Value::Object_Type:
|
||||
Q_UNREACHABLE();
|
||||
|
@ -658,9 +658,10 @@ void __qmljs_set_property(ExecutionContext *ctx, const ValueRef object, String *
|
|||
|
||||
ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object, const ValueRef index)
|
||||
{
|
||||
Scope scope(ctx);
|
||||
uint idx = index->asArrayIndex();
|
||||
|
||||
Object *o = object->asObject();
|
||||
Scoped<Object> o(scope, object);
|
||||
if (!o) {
|
||||
if (idx < UINT_MAX) {
|
||||
if (String *str = object->asString()) {
|
||||
|
@ -766,18 +767,19 @@ void __qmljs_set_activation_property(ExecutionContext *ctx, String *name, const
|
|||
|
||||
ReturnedValue __qmljs_get_property(ExecutionContext *ctx, const ValueRef object, String *name)
|
||||
{
|
||||
Value res;
|
||||
Managed *m = object->asManaged();
|
||||
if (m)
|
||||
return m->get(name);
|
||||
Scope scope(ctx);
|
||||
|
||||
Scoped<Object> o(scope, object);
|
||||
if (o)
|
||||
return o->get(name);
|
||||
|
||||
if (object->isNullOrUndefined()) {
|
||||
QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQStringNoThrow());
|
||||
ctx->throwTypeError(message);
|
||||
}
|
||||
|
||||
m = __qmljs_convert_to_object(ctx, object);
|
||||
return m->get(name);
|
||||
o = __qmljs_convert_to_object(ctx, object);
|
||||
return o->get(name);
|
||||
}
|
||||
|
||||
ReturnedValue __qmljs_get_activation_property(ExecutionContext *ctx, String *name)
|
||||
|
@ -974,7 +976,7 @@ ReturnedValue __qmljs_call_activation_property(ExecutionContext *context, String
|
|||
ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, CallDataRef callData)
|
||||
{
|
||||
Scope scope(context);
|
||||
Managed *baseObject = callData->thisObject.asManaged();
|
||||
Scoped<Object> baseObject(scope, callData->thisObject);
|
||||
if (!baseObject) {
|
||||
if (callData->thisObject.isNullOrUndefined()) {
|
||||
QString message = QStringLiteral("Cannot call method '%1' of %2").arg(name->toQString()).arg(callData->thisObject.toQStringNoThrow());
|
||||
|
@ -982,7 +984,7 @@ ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, Cal
|
|||
}
|
||||
|
||||
baseObject = __qmljs_convert_to_object(context, ValueRef(&callData->thisObject));
|
||||
callData->thisObject = Value::fromObject(static_cast<Object *>(baseObject));
|
||||
callData->thisObject = baseObject.asValue();
|
||||
}
|
||||
|
||||
Scoped<FunctionObject> o(scope, baseObject->get(name));
|
||||
|
@ -1251,6 +1253,20 @@ QV4::ReturnedValue __qmljs_decrement(const QV4::ValueRef value)
|
|||
}
|
||||
}
|
||||
|
||||
QV4::ReturnedValue __qmljs_to_string(const QV4::ValueRef value, QV4::ExecutionContext *ctx)
|
||||
{
|
||||
if (value->isString())
|
||||
return value.asReturnedValue();
|
||||
return __qmljs_convert_to_string(ctx, value)->asReturnedValue();
|
||||
}
|
||||
|
||||
QV4::ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
|
||||
{
|
||||
if (value->isObject())
|
||||
return value.asReturnedValue();
|
||||
return Encode(__qmljs_convert_to_object(ctx, value));
|
||||
}
|
||||
|
||||
void __qmljs_value_to_double(double *result, const ValueRef value)
|
||||
{
|
||||
*result = value->toNumber();
|
||||
|
|
|
@ -172,7 +172,7 @@ QV4::ReturnedValue __qmljs_to_string(const ValueRef value, QV4::ExecutionContext
|
|||
Q_QML_EXPORT QV4::String *__qmljs_convert_to_string(QV4::ExecutionContext *ctx, const ValueRef value);
|
||||
void __qmljs_numberToString(QString *result, double num, int radix = 10);
|
||||
ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const ValueRef value);
|
||||
QV4::Object *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const ValueRef value);
|
||||
Returned<Object> *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const ValueRef value);
|
||||
|
||||
QV4::Bool __qmljs_equal_helper(const ValueRef x, const ValueRef y);
|
||||
Q_QML_EXPORT QV4::Bool __qmljs_strict_equal(const ValueRef x, const ValueRef y);
|
||||
|
@ -294,21 +294,6 @@ inline double __qmljs_to_number(const ValueRef value)
|
|||
return value->toNumber();
|
||||
}
|
||||
|
||||
inline QV4::ReturnedValue __qmljs_to_string(const QV4::ValueRef value, QV4::ExecutionContext *ctx)
|
||||
{
|
||||
if (value->isString())
|
||||
return value.asReturnedValue();
|
||||
return __qmljs_convert_to_string(ctx, value)->asReturnedValue();
|
||||
}
|
||||
|
||||
inline QV4::ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
|
||||
{
|
||||
if (value->isObject())
|
||||
return value.asReturnedValue();
|
||||
return Value::fromObject(__qmljs_convert_to_object(ctx, value)).asReturnedValue();
|
||||
}
|
||||
|
||||
|
||||
inline QV4::ReturnedValue __qmljs_uplus(const QV4::ValueRef value)
|
||||
{
|
||||
TRACE1(value);
|
||||
|
|
|
@ -138,6 +138,16 @@ struct ScopedValue
|
|||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ScopedValue(const Scope &scope, Returned<T> *t)
|
||||
{
|
||||
ptr = scope.engine->jsStackTop++;
|
||||
ptr->val = T::toValue(t->getPointer());
|
||||
#ifndef QT_NO_DEBUG
|
||||
++scope.size;
|
||||
#endif
|
||||
}
|
||||
|
||||
ScopedValue &operator=(const Value &v) {
|
||||
*ptr = v;
|
||||
return *this;
|
||||
|
@ -148,6 +158,12 @@ struct ScopedValue
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ScopedValue &operator=(const Returned<T> *t) {
|
||||
ptr->val = T::toValue(t->getPointer());
|
||||
return *this;
|
||||
}
|
||||
|
||||
ScopedValue &operator=(const ScopedValue &other) {
|
||||
*ptr = *other.ptr;
|
||||
return *this;
|
||||
|
@ -193,6 +209,27 @@ struct Scoped
|
|||
#endif
|
||||
}
|
||||
|
||||
Scoped(const Scope &scope, const ValueRef &v);
|
||||
|
||||
Scoped(const Scope &scope, T *t)
|
||||
{
|
||||
ptr = scope.engine->jsStackTop++;
|
||||
*ptr = T::toValue(t);
|
||||
#ifndef QT_NO_DEBUG
|
||||
++scope.size;
|
||||
#endif
|
||||
}
|
||||
template<typename X>
|
||||
Scoped(const Scope &scope, Returned<X> *x)
|
||||
{
|
||||
ptr = scope.engine->jsStackTop++;
|
||||
T *t = Returned<T>::getPointer(x);
|
||||
*ptr = T::toValue(t);
|
||||
#ifndef QT_NO_DEBUG
|
||||
++scope.size;
|
||||
#endif
|
||||
}
|
||||
|
||||
Scoped(const Scope &scope, const ReturnedValue &v)
|
||||
{
|
||||
ptr = scope.engine->jsStackTop++;
|
||||
|
@ -213,6 +250,8 @@ struct Scoped
|
|||
return *this;
|
||||
}
|
||||
|
||||
Scoped<T> &operator=(const ValueRef &v);
|
||||
|
||||
Scoped<T> &operator=(const ReturnedValue &v) {
|
||||
if (T::cast(QV4::Value::fromReturnedValue(v)))
|
||||
ptr->val = v;
|
||||
|
@ -226,17 +265,32 @@ struct Scoped
|
|||
return *this;
|
||||
}
|
||||
|
||||
Scoped<T> &operator=(T *t) {
|
||||
*ptr = T::toValue(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
Scoped<T> &operator=(Returned<X> *x) {
|
||||
*ptr = T::toValue(Returned<T>::getPointer(x));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
T *operator->() {
|
||||
return static_cast<T *>(ptr->managed());
|
||||
}
|
||||
|
||||
// const Value *operator->() const {
|
||||
// return T::cast(*ptr);
|
||||
// }
|
||||
const Value *operator->() const {
|
||||
return T::cast(*ptr);
|
||||
}
|
||||
|
||||
bool operator!() const {
|
||||
return !ptr->managed();
|
||||
}
|
||||
operator bool() const {
|
||||
return ptr->managed();
|
||||
}
|
||||
|
||||
T *getPointer() {
|
||||
return static_cast<T *>(ptr->managed());
|
||||
|
@ -325,6 +379,29 @@ private:
|
|||
Value *ptr;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Scoped<T>::Scoped(const Scope &scope, const ValueRef &v)
|
||||
{
|
||||
ptr = scope.engine->jsStackTop++;
|
||||
if (T::cast(*v.operator ->()))
|
||||
*ptr = *v.operator ->();
|
||||
else
|
||||
*ptr = QV4::Value::undefinedValue();
|
||||
#ifndef QT_NO_DEBUG
|
||||
++scope.size;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Scoped<T> &Scoped<T>::operator=(const ValueRef &v)
|
||||
{
|
||||
if (T::cast(*v.operator ->()))
|
||||
*ptr = *v.operator ->();
|
||||
else
|
||||
*ptr = QV4::Value::undefinedValue();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
struct CallDataRef {
|
||||
CallDataRef(const ScopedCallData &c)
|
||||
|
@ -384,6 +461,14 @@ struct Encode : private Value {
|
|||
dbl = i;
|
||||
}
|
||||
}
|
||||
Encode(ReturnedValue v) {
|
||||
val = v;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Encode(Returned<T> *t) {
|
||||
val = T::toValue(t->getPointer()).val;
|
||||
}
|
||||
|
||||
operator ReturnedValue() const {
|
||||
return val;
|
||||
|
|
|
@ -52,6 +52,7 @@ struct ExecutionEngine;
|
|||
struct Identifier;
|
||||
|
||||
struct Q_QML_EXPORT String : public Managed {
|
||||
Q_MANAGED
|
||||
enum StringType {
|
||||
StringType_Unknown,
|
||||
StringType_Regular,
|
||||
|
@ -122,6 +123,9 @@ struct Q_QML_EXPORT String : public Managed {
|
|||
static String *cast(const Value &v) {
|
||||
return v.asString();
|
||||
}
|
||||
static Value toValue(String *s) {
|
||||
return Value::fromString(s);
|
||||
}
|
||||
|
||||
ReturnedValue asReturnedValue() { return Value::fromString(this).asReturnedValue(); }
|
||||
|
||||
|
@ -141,8 +145,6 @@ protected:
|
|||
static bool deleteProperty(Managed *, String *);
|
||||
static bool deleteIndexedProperty(Managed *m, uint index);
|
||||
static bool isEqualTo(Managed *that, Managed *o);
|
||||
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -68,13 +68,11 @@ protected:
|
|||
|
||||
struct StringCtor: FunctionObject
|
||||
{
|
||||
Q_MANAGED
|
||||
StringCtor(ExecutionContext *scope);
|
||||
|
||||
static ReturnedValue construct(Managed *m, CallData *callData);
|
||||
static ReturnedValue call(Managed *that, CallData *callData);
|
||||
|
||||
protected:
|
||||
static const ManagedVTable static_vtbl;
|
||||
};
|
||||
|
||||
struct StringPrototype: StringObject
|
||||
|
|
|
@ -312,7 +312,7 @@ Object *Value::toObject(ExecutionContext *ctx) const
|
|||
{
|
||||
if (isObject())
|
||||
return objectValue();
|
||||
return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this));
|
||||
return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this))->getPointer();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -59,8 +59,6 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
namespace QV4 {
|
||||
|
||||
QV4::Object *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const QV4::Value &value);
|
||||
|
||||
inline Managed *Value::asManaged() const
|
||||
{
|
||||
if (isManaged())
|
||||
|
|
Loading…
Reference in New Issue