Convert most remaining return values from Value to ReturnedValue

Change-Id: If8b0c3b91be50678693868c10fefc3678008834d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Lars Knoll 2013-09-12 22:37:41 +02:00 committed by The Qt Project
parent 399f88f6b7
commit a2d115fbaf
59 changed files with 553 additions and 498 deletions

View File

@ -204,7 +204,7 @@ static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, Execut
if (v.isNull()) { if (v.isNull()) {
row->put(v4->newIdentifier(record.fieldName(ii)), Value::nullValue()); row->put(v4->newIdentifier(record.fieldName(ii)), Value::nullValue());
} else { } else {
row->put(v4->newIdentifier(record.fieldName(ii)), v8->fromVariant(v)); row->put(v4->newIdentifier(record.fieldName(ii)), Value::fromReturnedValue(v8->fromVariant(v)));
} }
} }
if (hasProperty) if (hasProperty)
@ -257,7 +257,8 @@ static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx)
QSqlQuery query(db); QSqlQuery query(db);
bool err = false; bool err = false;
Value result = Value::undefinedValue(); Scope scope(QV8Engine::getV4(engine));
ScopedValue result(scope, Value::undefinedValue());
if (query.prepare(sql)) { if (query.prepare(sql)) {
if (ctx->argumentCount > 1) { if (ctx->argumentCount > 1) {
@ -268,17 +269,18 @@ static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx)
query.bindValue(ii, engine->toVariant(QV4::Value::fromReturnedValue(array->getIndexed(ii)), -1)); query.bindValue(ii, engine->toVariant(QV4::Value::fromReturnedValue(array->getIndexed(ii)), -1));
} else if (Object *object = values.asObject()) { } else if (Object *object = values.asObject()) {
ObjectIterator it(object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly); ObjectIterator it(object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
ScopedValue key(scope);
while (1) { while (1) {
Value value; Value value;
Value key = it.nextPropertyName(&value); key = it.nextPropertyName(&value);
if (key.isNull()) if (key->isNull())
break; break;
QVariant v = engine->toVariant(value, -1); QVariant v = engine->toVariant(value, -1);
if (key.isString()) { if (key->isString()) {
query.bindValue(key.stringValue()->toQString(), v); query.bindValue(key->stringValue()->toQString(), v);
} else { } else {
assert(key.isInteger()); assert(key->isInteger());
query.bindValue(key.integerValue(), v); query.bindValue(key->integerValue(), v);
} }
} }
} else { } else {

View File

@ -926,7 +926,7 @@ QQmlV4Handle QQuickXmlListModel::get(int index) const
Object *o = v4engine->newObject(); Object *o = v4engine->newObject();
for (int ii = 0; ii < d->roleObjects.count(); ++ii) { for (int ii = 0; ii < d->roleObjects.count(); ++ii) {
Property *p = o->insertMember(v4engine->newIdentifier(d->roleObjects[ii]->name()), PropertyAttributes()); Property *p = o->insertMember(v4engine->newIdentifier(d->roleObjects[ii]->name()), PropertyAttributes());
p->value = v8engine->fromVariant(d->data.value(ii).value(index)); p->value = Value::fromReturnedValue(v8engine->fromVariant(d->data.value(ii).value(index)));
} }
return QQmlV4Handle(Value::fromObject(o)); return QQmlV4Handle(Value::fromObject(o));

View File

@ -327,8 +327,10 @@ QJSValue QJSEngine::newQObject(QObject *object)
{ {
Q_D(QJSEngine); Q_D(QJSEngine);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(d); QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
QV4::Scope scope(v4);
QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership); QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership);
return new QJSValuePrivate(v4, QV4::QObjectWrapper::wrap(v4, object)); QV4::ScopedValue v(scope, QV4::QObjectWrapper::wrap(v4, object));
return new QJSValuePrivate(v4, v);
} }
/*! /*!
@ -353,7 +355,7 @@ QJSValue QJSEngine::globalObject() const
QJSValue QJSEngine::create(int type, const void *ptr) QJSValue QJSEngine::create(int type, const void *ptr)
{ {
Q_D(QJSEngine); Q_D(QJSEngine);
return new QJSValuePrivate(d->m_v4Engine, d->metaTypeToJS(type, ptr)); return new QJSValuePrivate(d->m_v4Engine, QV4::Value::fromReturnedValue(d->metaTypeToJS(type, ptr)));
} }
/*! /*!
@ -365,7 +367,7 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
QJSValuePrivate *vp = QJSValuePrivate::get(value); QJSValuePrivate *vp = QJSValuePrivate::get(value);
QV8Engine *engine = vp->engine ? vp->engine->v8Engine : 0; QV8Engine *engine = vp->engine ? vp->engine->v8Engine : 0;
if (engine) { if (engine) {
return engine->metaTypeFromJS(vp->getValue(engine->m_v4Engine), type, ptr); return engine->metaTypeFromJS(QV4::Value::fromReturnedValue(vp->getValue(engine->m_v4Engine)), type, ptr);
} else { } else {
switch (type) { switch (type) {
case QMetaType::Bool: case QMetaType::Bool:

View File

@ -57,13 +57,13 @@
#include <private/qv4exception_p.h> #include <private/qv4exception_p.h>
#include <private/qv4scopedvalue_p.h> #include <private/qv4scopedvalue_p.h>
QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e) QV4::ReturnedValue QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
{ {
if (!this->engine) if (!this->engine)
this->engine = e; this->engine = e;
else if (this->engine != e) { else if (this->engine != e) {
qWarning("JSValue can't be reassigned to another engine."); qWarning("JSValue can't be reassigned to another engine.");
return QV4::Value::emptyValue(); return QV4::Value::emptyValue().asReturnedValue();
} }
if (value.asString() == &string) { if (value.asString() == &string) {
value = QV4::Value::fromString(engine->newString(string.toQString())); value = QV4::Value::fromString(engine->newString(string.toQString()));
@ -74,7 +74,7 @@ QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
if (next) if (next)
next->prev = &this->next; next->prev = &this->next;
} }
return value; return value.asReturnedValue();
} }
/*! /*!
@ -514,7 +514,7 @@ QJSValue QJSValue::call(const QJSValueList &args)
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine"); qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue(); return QJSValue();
} }
callData->args[i] = args.at(i).d->getValue(engine); callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine));
} }
ScopedValue result(scope); ScopedValue result(scope);
@ -565,13 +565,13 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
} }
ScopedCallData callData(scope, args.size()); ScopedCallData callData(scope, args.size());
callData->thisObject = instance.d->getValue(engine); callData->thisObject = QV4::Value::fromReturnedValue(instance.d->getValue(engine));
for (int i = 0; i < args.size(); ++i) { for (int i = 0; i < args.size(); ++i) {
if (!args.at(i).d->checkEngine(engine)) { if (!args.at(i).d->checkEngine(engine)) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine"); qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue(); return QJSValue();
} }
callData->args[i] = args.at(i).d->getValue(engine); callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine));
} }
ScopedValue result(scope); ScopedValue result(scope);
@ -620,7 +620,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine"); qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
return QJSValue(); return QJSValue();
} }
callData->args[i] = args.at(i).d->getValue(engine); callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine));
} }
ScopedValue result(scope); ScopedValue result(scope);
@ -864,7 +864,12 @@ QJSValue QJSValue::property(quint32 arrayIndex) const
*/ */
void QJSValue::setProperty(const QString& name, const QJSValue& value) void QJSValue::setProperty(const QString& name, const QJSValue& value)
{ {
Object *o = d->value.asObject(); ExecutionEngine *engine = d->engine;
if (!engine)
return;
Scope scope(engine);
Scoped<Object> o(scope, d->value);
if (!o) if (!o)
return; return;
@ -873,7 +878,6 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
return; return;
} }
ExecutionEngine *engine = d->engine;
String *s = engine->newString(name); String *s = engine->newString(name);
uint idx = s->asArrayIndex(); uint idx = s->asArrayIndex();
if (idx < UINT_MAX) { if (idx < UINT_MAX) {
@ -884,7 +888,8 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
QV4::ExecutionContext *ctx = engine->current; QV4::ExecutionContext *ctx = engine->current;
s->makeIdentifier(); s->makeIdentifier();
try { try {
o->put(s, value.d->getValue(engine)); QV4::ScopedValue v(scope, value.d->getValue(engine));
o->put(s, v);
} catch (QV4::Exception &e) { } catch (QV4::Exception &e) {
e.accept(ctx); e.accept(ctx);
} }
@ -904,17 +909,22 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
*/ */
void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
{ {
Object *o = d->value.asObject(); ExecutionEngine *engine = d->engine;
if (!engine)
return;
Scope scope(engine);
Scoped<Object> o(scope, d->value);
if (!o) if (!o)
return; return;
ExecutionEngine *engine = d->engine;
QV4::ExecutionContext *ctx = engine->current; QV4::ExecutionContext *ctx = engine->current;
QV4::ScopedValue v(scope, value.d->getValue(engine));
try { try {
if (arrayIndex != UINT_MAX) if (arrayIndex != UINT_MAX)
o->putIndexed(arrayIndex, value.d->getValue(engine)); o->putIndexed(arrayIndex, v);
else else
o->put(engine->id_uintMax, value.d->getValue(engine)); o->put(engine->id_uintMax, v);
} catch (QV4::Exception &e) { } catch (QV4::Exception &e) {
e.accept(ctx); e.accept(ctx);
} }

View File

@ -88,7 +88,7 @@ public:
value = QV4::Value::fromString(&string); value = QV4::Value::fromString(&string);
} }
QV4::Value getValue(QV4::ExecutionEngine *e); QV4::ReturnedValue getValue(QV4::ExecutionEngine *e);
static QJSValuePrivate *get(const QJSValue &v) { return v.d; } static QJSValuePrivate *get(const QJSValue &v) { return v.d; }

View File

@ -600,7 +600,7 @@ ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
return Value::fromInt32(-1).asReturnedValue(); return Value::fromInt32(-1).asReturnedValue();
} }
return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance).asReturnedValue(); return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance);
} }
ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx) ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)

View File

@ -209,6 +209,9 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string
{ {
using namespace QV4; using namespace QV4;
using namespace std; using namespace std;
Scope scope(ctx);
cout << prefix << "tag: " << hex << v.tag << dec << endl << prefix << "\t-> "; cout << prefix << "tag: " << hex << v.tag << dec << endl << prefix << "\t-> ";
switch (v.type()) { switch (v.type()) {
case Value::Undefined_Type: cout << "Undefined" << endl; return; case Value::Undefined_Type: cout << "Undefined" << endl; return;
@ -271,10 +274,11 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string
cout << prefix << "properties:" << endl; cout << prefix << "properties:" << endl;
ForEachIteratorObject it(ctx, o); ForEachIteratorObject it(ctx, o);
for (Value name = it.nextPropertyName(); !name.isNull(); name = it.nextPropertyName()) { QV4::ScopedValue name(scope);
cout << prefix << "\t\"" << qPrintable(name.stringValue()->toQString()) << "\"" << endl; for (name = it.nextPropertyName(); !name->isNull(); name = it.nextPropertyName()) {
cout << prefix << "\t\"" << qPrintable(name->stringValue()->toQString()) << "\"" << endl;
PropertyAttributes attrs; PropertyAttributes attrs;
Property *d = o->__getOwnProperty__(name.stringValue(), &attrs); Property *d = o->__getOwnProperty__(name->stringValue(), &attrs);
Value pval = Value::fromReturnedValue(o->getValue(d, attrs)); Value pval = Value::fromReturnedValue(o->getValue(d, attrs));
cout << prefix << "\tvalue:" << endl; cout << prefix << "\tvalue:" << endl;
realDumpValue(pval, ctx, prefix + "\t"); realDumpValue(pval, ctx, prefix + "\t");

View File

@ -618,6 +618,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that); IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that);
ExecutionEngine *v4 = f->engine(); ExecutionEngine *v4 = f->engine();
ExecutionContext *context = v4->current; ExecutionContext *context = v4->current;
Scope scope(v4);
SimpleCallContext ctx; SimpleCallContext ctx;
ctx.initSimpleCallContext(f->scope->engine); ctx.initSimpleCallContext(f->scope->engine);
@ -628,7 +629,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
ctx.argumentCount = callData->argc; ctx.argumentCount = callData->argc;
v4->pushContext(&ctx); v4->pushContext(&ctx);
Value result; ScopedValue result(scope);
try { try {
result = f->code(&ctx, f->index); result = f->code(&ctx, f->index);
} catch (Exception &ex) { } catch (Exception &ex) {

View File

@ -180,10 +180,10 @@ struct IndexedBuiltinFunction: FunctionObject
{ {
Q_MANAGED Q_MANAGED
Value (*code)(SimpleCallContext *ctx, uint index); ReturnedValue (*code)(SimpleCallContext *ctx, uint index);
uint index; uint index;
IndexedBuiltinFunction(ExecutionContext *scope, uint index, Value (*code)(SimpleCallContext *ctx, uint index)) IndexedBuiltinFunction(ExecutionContext *scope, uint index, ReturnedValue (*code)(SimpleCallContext *ctx, uint index))
: FunctionObject(scope, /*name*/0) : FunctionObject(scope, /*name*/0)
, code(code) , code(code)
, index(index) , index(index)

View File

@ -82,7 +82,7 @@ QV4Include::~QV4Include()
delete m_reply; m_reply = 0; delete m_reply; m_reply = 0;
} }
QV4::Value QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status) QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status)
{ {
// XXX It seems inefficient to create this object from scratch each time. // XXX It seems inefficient to create this object from scratch each time.
@ -94,7 +94,7 @@ QV4::Value QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status)
o->put(v4->newString("status"), QV4::Value::fromInt32(status)); o->put(v4->newString("status"), QV4::Value::fromInt32(status));
return QV4::Value::fromObject(o); return QV4::Value::fromObject(o).asReturnedValue();
} }
void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status) void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
@ -115,9 +115,9 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
} }
} }
QV4::Value QV4Include::result() QV4::ReturnedValue QV4Include::result()
{ {
return m_resultObject.value(); return m_resultObject.value().asReturnedValue();
} }
#define INCLUDE_MAXIMUM_REDIRECT_RECURSION 15 #define INCLUDE_MAXIMUM_REDIRECT_RECURSION 15

View File

@ -88,9 +88,9 @@ private:
const QV4::Value &qmlglobal, const QV4::Value &callback); const QV4::Value &qmlglobal, const QV4::Value &callback);
~QV4Include(); ~QV4Include();
QV4::Value result(); QV4::ReturnedValue result();
static QV4::Value resultValue(QV4::ExecutionEngine *v4, Status status = Loading); static QV4::ReturnedValue resultValue(QV4::ExecutionEngine *v4, Status status = Loading);
static void callback(const QV4::Value &callback, const QV4::Value &status); static void callback(const QV4::Value &callback, const QV4::Value &status);
QV4::ExecutionEngine *v4; QV4::ExecutionEngine *v4;

View File

@ -783,13 +783,14 @@ QString Stringify::JO(Object *o)
QStringList partial; QStringList partial;
if (propertyList.isEmpty()) { if (propertyList.isEmpty()) {
ObjectIterator it(o, ObjectIterator::EnumerableOnly); ObjectIterator it(o, ObjectIterator::EnumerableOnly);
ScopedValue name(scope);
while (1) { while (1) {
Value v; Value v;
Value name = it.nextPropertyNameAsString(&v); name = it.nextPropertyNameAsString(&v);
if (name.isNull()) if (name->isNull())
break; break;
QString key = name.toQStringNoThrow(); QString key = name->toQStringNoThrow();
QString member = makeMember(key, v); QString member = makeMember(key, v);
if (!member.isEmpty()) if (!member.isEmpty())
partial += member; partial += member;
@ -936,22 +937,22 @@ ReturnedValue JsonObject::method_stringify(SimpleCallContext *ctx)
QV4::Value JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value) ReturnedValue JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value)
{ {
if (value.isString()) if (value.isString())
return Value::fromString(engine->current, value.toString()); return Value::fromString(engine->current, value.toString()).asReturnedValue();
else if (value.isDouble()) else if (value.isDouble())
return Value::fromDouble(value.toDouble()); return Encode(value.toDouble());
else if (value.isBool()) else if (value.isBool())
return Value::fromBoolean(value.toBool()); return Encode(value.toBool());
else if (value.isArray()) else if (value.isArray())
return fromJsonArray(engine, value.toArray()); return fromJsonArray(engine, value.toArray());
else if (value.isObject()) else if (value.isObject())
return fromJsonObject(engine, value.toObject()); return fromJsonObject(engine, value.toObject());
else if (value.isNull()) else if (value.isNull())
return Value::nullValue(); return Encode::null();
else else
return Value::undefinedValue(); return Encode::undefined();
} }
QJsonValue JsonObject::toJsonValue(const QV4::Value &value, QJsonValue JsonObject::toJsonValue(const QV4::Value &value,
@ -973,12 +974,13 @@ QJsonValue JsonObject::toJsonValue(const QV4::Value &value,
return QJsonValue(QJsonValue::Undefined); return QJsonValue(QJsonValue::Undefined);
} }
QV4::Value JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object) QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object)
{ {
Object *o = engine->newObject(); Scope scope(engine);
Scoped<Object> o(scope, Value::fromObject(engine->newObject()));
for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it) for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it)
o->put(engine->newString(it.key()), fromJsonValue(engine, it.value())); o->put(engine->newString(it.key()), Value::fromReturnedValue(fromJsonValue(engine, it.value())));
return Value::fromObject(o); return o.asReturnedValue();
} }
QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects) QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects)
@ -987,6 +989,8 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects
if (!o || o->asFunctionObject()) if (!o || o->asFunctionObject())
return result; return result;
Scope scope(o->engine());
if (visitedObjects.contains(o)) { if (visitedObjects.contains(o)) {
// Avoid recursion. // Avoid recursion.
// For compatibility with QVariant{List,Map} conversion, we return an // For compatibility with QVariant{List,Map} conversion, we return an
@ -997,13 +1001,14 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects
visitedObjects.insert(o); visitedObjects.insert(o);
ObjectIterator it(o, ObjectIterator::EnumerableOnly); ObjectIterator it(o, ObjectIterator::EnumerableOnly);
ScopedValue name(scope);
while (1) { while (1) {
Value v; Value v;
Value name = it.nextPropertyNameAsString(&v); name = it.nextPropertyNameAsString(&v);
if (name.isNull()) if (name->isNull())
break; break;
QString key = name.toQStringNoThrow(); QString key = name->toQStringNoThrow();
if (!v.asFunctionObject()) if (!v.asFunctionObject())
result.insert(key, toJsonValue(v, visitedObjects)); result.insert(key, toJsonValue(v, visitedObjects));
} }
@ -1013,16 +1018,16 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects
return result; return result;
} }
QV4::Value JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array) QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array)
{ {
int size = array.size(); int size = array.size();
ArrayObject *a = engine->newArrayObject(); ArrayObject *a = engine->newArrayObject();
a->arrayReserve(size); a->arrayReserve(size);
a->arrayDataLen = size; a->arrayDataLen = size;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
a->arrayData[i].value = fromJsonValue(engine, array.at(i)); a->arrayData[i].value = Value::fromReturnedValue(fromJsonValue(engine, array.at(i)));
a->setArrayLengthUnchecked(size); a->setArrayLengthUnchecked(size);
return Value::fromObject(a); return Value::fromObject(a).asReturnedValue();
} }
QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects) QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects)

View File

@ -59,9 +59,9 @@ public:
static ReturnedValue method_parse(SimpleCallContext *ctx); static ReturnedValue method_parse(SimpleCallContext *ctx);
static ReturnedValue method_stringify(SimpleCallContext *ctx); static ReturnedValue method_stringify(SimpleCallContext *ctx);
static QV4::Value fromJsonValue(ExecutionEngine *engine, const QJsonValue &value); static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value);
static QV4::Value fromJsonObject(ExecutionEngine *engine, const QJsonObject &object); static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object);
static QV4::Value fromJsonArray(ExecutionEngine *engine, const QJsonArray &array); static ReturnedValue fromJsonArray(ExecutionEngine *engine, const QJsonArray &array);
static inline QJsonValue toJsonValue(const QV4::Value &value) static inline QJsonValue toJsonValue(const QV4::Value &value)
{ V4ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); } { V4ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); }

View File

@ -1127,7 +1127,7 @@ void Object::copyArrayData(Object *other)
} }
Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionContext *ctx, Object *o) ReturnedValue Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionContext *ctx, Object *o)
{ {
Scope scope(engine()); Scope scope(engine());
ScopedValue value(scope); ScopedValue value(scope);
@ -1138,13 +1138,13 @@ Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionCont
bool exists; bool exists;
value = o->getIndexed(i, &exists); value = o->getIndexed(i, &exists);
if (exists && __qmljs_strict_equal(value, ValueRef(&v))) if (exists && __qmljs_strict_equal(value, ValueRef(&v)))
return Value::fromDouble(i); return Encode(i);
} }
} else if (sparseArray) { } else if (sparseArray) {
for (SparseArrayNode *n = sparseArray->lowerBound(fromIndex); n != sparseArray->end() && n->key() < endIndex; n = n->nextNode()) { for (SparseArrayNode *n = sparseArray->lowerBound(fromIndex); n != sparseArray->end() && n->key() < endIndex; n = n->nextNode()) {
value = o->getValue(arrayData + n->value, arrayAttributes ? arrayAttributes[n->value] : Attr_Data); value = o->getValue(arrayData + n->value, arrayAttributes ? arrayAttributes[n->value] : Attr_Data);
if (__qmljs_strict_equal(value, ValueRef(&v))) if (__qmljs_strict_equal(value, ValueRef(&v)))
return Value::fromDouble(n->key()); return Encode(n->key());
} }
} else { } else {
if ((int) endIndex > arrayDataLen) if ((int) endIndex > arrayDataLen)
@ -1156,12 +1156,12 @@ Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionCont
if (!arrayAttributes || !arrayAttributes[pd - arrayData].isGeneric()) { if (!arrayAttributes || !arrayAttributes[pd - arrayData].isGeneric()) {
value = o->getValue(pd, arrayAttributes ? arrayAttributes[pd - arrayData] : Attr_Data); value = o->getValue(pd, arrayAttributes ? arrayAttributes[pd - arrayData] : Attr_Data);
if (__qmljs_strict_equal(value, ValueRef(&v))) if (__qmljs_strict_equal(value, ValueRef(&v)))
return Value::fromDouble(pd - arrayData); return Encode((uint)(pd - arrayData));
} }
++pd; ++pd;
} }
} }
return Value::fromInt32(-1); return Encode(-1);
} }
void Object::arrayConcat(const ArrayObject *other) void Object::arrayConcat(const ArrayObject *other)

View File

@ -277,7 +277,7 @@ public:
void arrayConcat(const ArrayObject *other); void arrayConcat(const ArrayObject *other);
void arraySort(ExecutionContext *context, Object *thisObject, const Value &comparefn, uint arrayDataLen); void arraySort(ExecutionContext *context, Object *thisObject, const Value &comparefn, uint arrayDataLen);
Value arrayIndexOf(Value v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o); ReturnedValue arrayIndexOf(Value v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o);
void arrayReserve(uint n); void arrayReserve(uint n);
void ensureArrayAttributes(); void ensureArrayAttributes();
@ -350,7 +350,7 @@ struct ForEachIteratorObject: Object {
type = Type_ForeachIteratorObject; type = Type_ForeachIteratorObject;
} }
Value nextPropertyName() { return it.nextPropertyNameAsString(); } ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
protected: protected:
static void markObjects(Managed *that); static void markObjects(Managed *that);

View File

@ -92,38 +92,38 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
return 0; return 0;
} }
Value ObjectIterator::nextPropertyName(Value *value) ReturnedValue ObjectIterator::nextPropertyName(Value *value)
{ {
PropertyAttributes attrs; PropertyAttributes attrs;
uint index; uint index;
String *name; String *name;
Property *p = next(&name, &index, &attrs); Property *p = next(&name, &index, &attrs);
if (!p) if (!p)
return Value::nullValue(); return Encode::null();
if (value) if (value)
*value = Value::fromReturnedValue(object->getValue(p, attrs)); *value = Value::fromReturnedValue(object->getValue(p, attrs));
if (name) if (name)
return Value::fromString(name); return Value::fromString(name).asReturnedValue();
assert(index < UINT_MAX); assert(index < UINT_MAX);
return Value::fromDouble(index); return Encode(index);
} }
Value ObjectIterator::nextPropertyNameAsString(Value *value) ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value)
{ {
PropertyAttributes attrs; PropertyAttributes attrs;
uint index; uint index;
String *name; String *name;
Property *p = next(&name, &index, &attrs); Property *p = next(&name, &index, &attrs);
if (!p) if (!p)
return Value::nullValue(); return Encode::null();
if (value) if (value)
*value = Value::fromReturnedValue(object->getValue(p, attrs)); *value = Value::fromReturnedValue(object->getValue(p, attrs));
if (name) if (name)
return Value::fromString(name); return Value::fromString(name).asReturnedValue();
assert(index < UINT_MAX); assert(index < UINT_MAX);
return Value::fromString(object->engine()->newString(QString::number(index))); return Value::fromString(object->engine()->newString(QString::number(index))).asReturnedValue();
} }

View File

@ -76,8 +76,8 @@ struct Q_QML_EXPORT ObjectIterator
ObjectIterator(Object *o, uint flags); ObjectIterator(Object *o, uint flags);
Property *next(String **name, uint *index, PropertyAttributes *attributes = 0); Property *next(String **name, uint *index, PropertyAttributes *attributes = 0);
Value nextPropertyName(Value *value = 0); ReturnedValue nextPropertyName(Value *value = 0);
Value nextPropertyNameAsString(Value *value = 0); ReturnedValue nextPropertyNameAsString(Value *value = 0);
}; };
} }

View File

@ -352,14 +352,16 @@ ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx)
if (!ctx->argument(0).isObject()) if (!ctx->argument(0).isObject())
ctx->throwTypeError(); ctx->throwTypeError();
Scope scope(ctx);
Object *o = ctx->argument(0).objectValue(); Object *o = ctx->argument(0).objectValue();
ArrayObject *a = ctx->engine->newArrayObject(); ArrayObject *a = ctx->engine->newArrayObject();
ObjectIterator it(o, ObjectIterator::EnumerableOnly); ObjectIterator it(o, ObjectIterator::EnumerableOnly);
ScopedValue name(scope);
while (1) { while (1) {
Value name = it.nextPropertyNameAsString(); name = it.nextPropertyNameAsString();
if (name.isNull()) if (name->isNull())
break; break;
a->push_back(name); a->push_back(name);
} }
@ -605,15 +607,17 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con
ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Value &o) ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Value &o)
{ {
Scope scope(v4);
ArrayObject *array = v4->newArrayObject(); ArrayObject *array = v4->newArrayObject();
Object *O = o.asObject(); Object *O = o.asObject();
if (!O) if (!O)
return array; return array;
ObjectIterator it(O, ObjectIterator::NoFlags); ObjectIterator it(O, ObjectIterator::NoFlags);
ScopedValue name(scope);
while (1) { while (1) {
Value name = it.nextPropertyNameAsString(); name = it.nextPropertyNameAsString();
if (name.isNull()) if (name->isNull())
break; break;
array->push_back(name); array->push_back(name);
} }

View File

@ -138,30 +138,16 @@ struct ReadAccessor {
} }
}; };
static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, int v)
{ return QV4::Value::fromInt32(v); }
static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, uint v)
{ return QV4::Value::fromUInt32(v); }
static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, bool v)
{ return QV4::Value::fromBoolean(v); }
static inline QV4::Value valueToHandle(QV4::ExecutionEngine *e, const QString &v)
{ return QV4::Value::fromString(e, v); }
static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, float v)
{ return QV4::Value::fromDouble(v); }
static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, double v)
{ return QV4::Value::fromDouble(v); }
static inline QV4::Value valueToHandle(QV4::ExecutionEngine *e, QObject *v)
{ return QV4::QObjectWrapper::wrap(e, v); }
// Load value properties // Load value properties
template<void (*ReadFunction)(QObject *, const QQmlPropertyData &, template<void (*ReadFunction)(QObject *, const QQmlPropertyData &,
void *, QQmlNotifier **)> void *, QQmlNotifier **)>
static QV4::Value LoadProperty(QV8Engine *engine, QObject *object, static QV4::ReturnedValue LoadProperty(QV8Engine *engine, QObject *object,
const QQmlPropertyData &property, const QQmlPropertyData &property,
QQmlNotifier **notifier) QQmlNotifier **notifier)
{ {
Q_ASSERT(!property.isFunction()); Q_ASSERT(!property.isFunction());
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
if (property.isQObject()) { if (property.isQObject()) {
QObject *rv = 0; QObject *rv = 0;
@ -172,35 +158,35 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object,
} else if (property.propType == QMetaType::QReal) { } else if (property.propType == QMetaType::QReal) {
qreal v = 0; qreal v = 0;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
return valueToHandle(v4, v); return QV4::Encode(v);
} else if (property.propType == QMetaType::Int || property.isEnum()) { } else if (property.propType == QMetaType::Int || property.isEnum()) {
int v = 0; int v = 0;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
return valueToHandle(v4, v); return QV4::Encode(v);
} else if (property.propType == QMetaType::Bool) { } else if (property.propType == QMetaType::Bool) {
bool v = false; bool v = false;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
return valueToHandle(v4, v); return QV4::Encode(v);
} else if (property.propType == QMetaType::QString) { } else if (property.propType == QMetaType::QString) {
QString v; QString v;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
return valueToHandle(v4, v); return Value::fromString(v4, v).asReturnedValue();
} else if (property.propType == QMetaType::UInt) { } else if (property.propType == QMetaType::UInt) {
uint v = 0; uint v = 0;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
return valueToHandle(v4, v); return QV4::Encode(v);
} else if (property.propType == QMetaType::Float) { } else if (property.propType == QMetaType::Float) {
float v = 0; float v = 0;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
return valueToHandle(v4, v); return QV4::Encode(v);
} else if (property.propType == QMetaType::Double) { } else if (property.propType == QMetaType::Double) {
double v = 0; double v = 0;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
return valueToHandle(v4, v); return QV4::Encode(v);
} else if (property.isV4Handle()) { } else if (property.isV4Handle()) {
QQmlV4Handle handle; QQmlV4Handle handle;
ReadFunction(object, property, &handle, notifier); ReadFunction(object, property, &handle, notifier);
return handle.toValue(); return handle.toValue().asReturnedValue();
} else if (property.propType == qMetaTypeId<QJSValue>()) { } else if (property.propType == qMetaTypeId<QJSValue>()) {
QJSValue v; QJSValue v;
ReadFunction(object, property, &v, notifier); ReadFunction(object, property, &v, notifier);
@ -225,16 +211,16 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object,
// see if it's a sequence type // see if it's a sequence type
bool succeeded = false; bool succeeded = false;
QV4::Value retn = QV4::SequencePrototype::newSequence(v4, property.propType, object, property.coreIndex, &succeeded); QV4::ScopedValue retn(scope, QV4::SequencePrototype::newSequence(v4, property.propType, object, property.coreIndex, &succeeded));
if (succeeded) if (succeeded)
return retn; return retn.asReturnedValue();
} }
if (property.propType == QMetaType::UnknownType) { if (property.propType == QMetaType::UnknownType) {
QMetaProperty p = object->metaObject()->property(property.coreIndex); QMetaProperty p = object->metaObject()->property(property.coreIndex);
qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property " qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
"'%s::%s'", p.typeName(), object->metaObject()->className(), p.name()); "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name());
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} else { } else {
QVariant v(property.propType, (void *)0); QVariant v(property.propType, (void *)0);
ReadFunction(object, property, v.data(), notifier); ReadFunction(object, property, v.data(), notifier);
@ -271,20 +257,23 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont
return result; return result;
} }
Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, bool includeImports) ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode,
bool *hasProperty, bool includeImports)
{ {
if (QQmlData::wasDeleted(m_object)) { if (QQmlData::wasDeleted(m_object)) {
if (hasProperty) if (hasProperty)
*hasProperty = false; *hasProperty = false;
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} }
QV4:Scope scope(ctx);
if (name->isEqualTo(m_destroy) || name->isEqualTo(m_toString)) { if (name->isEqualTo(m_destroy) || name->isEqualTo(m_toString)) {
int index = name->isEqualTo(m_destroy) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod; int index = name->isEqualTo(m_destroy) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod;
QV4::Value method = QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, index); QV4::ScopedValue method(scope, QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, index));
if (hasProperty) if (hasProperty)
*hasProperty = true; *hasProperty = true;
return method; return method.asReturnedValue();
} }
QQmlPropertyData local; QQmlPropertyData local;
@ -301,7 +290,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
if (r.isValid()) { if (r.isValid()) {
if (r.scriptIndex != -1) { if (r.scriptIndex != -1) {
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} else if (r.type) { } else if (r.type) {
return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, r.type, QmlTypeWrapper::ExcludeEnums); return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, r.type, QmlTypeWrapper::ExcludeEnums);
} else if (r.importNamespace) { } else if (r.importNamespace) {
@ -311,7 +300,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
} }
} }
} }
return QV4::Value::fromReturnedValue(QV4::Object::get(this, name, hasProperty)); return QV4::Object::get(this, name, hasProperty);
} }
QQmlData::flushPendingBinding(m_object, result->coreIndex); QQmlData::flushPendingBinding(m_object, result->coreIndex);
@ -321,7 +310,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) { if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) {
if (hasProperty) if (hasProperty)
*hasProperty = false; *hasProperty = false;
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} }
} }
@ -334,7 +323,8 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
Q_ASSERT(vmemo); Q_ASSERT(vmemo);
return vmemo->vmeMethod(result->coreIndex); return vmemo->vmeMethod(result->coreIndex);
} else if (result->isV4Function()) { } else if (result->isV4Function()) {
return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex, QV4::Value::fromObject(ctx->engine->qmlContextObject())); return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex,
QV4::Value::fromObject(ctx->engine->qmlContextObject())).asReturnedValue();
} else if (result->isSignalHandler()) { } else if (result->isSignalHandler()) {
QV4::QmlSignalHandler *handler = new (ctx->engine->memoryManager) QV4::QmlSignalHandler(ctx->engine, m_object, result->coreIndex); QV4::QmlSignalHandler *handler = new (ctx->engine->memoryManager) QV4::QmlSignalHandler(ctx->engine, m_object, result->coreIndex);
@ -343,9 +333,9 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
handler->put(connect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(connect))); handler->put(connect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(connect)));
handler->put(disconnect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(disconnect))); handler->put(disconnect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(disconnect)));
return QV4::Value::fromObject(handler); return QV4::Value::fromObject(handler).asReturnedValue();
} else { } else {
return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex); return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex).asReturnedValue();
} }
} }
@ -358,15 +348,16 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
if (ep && ep->propertyCapture && result->accessors->notifier) if (ep && ep->propertyCapture && result->accessors->notifier)
nptr = &n; nptr = &n;
QV4::Value rv = LoadProperty<ReadAccessor::Accessor>(ctx->engine->v8Engine, m_object, *result, nptr); QV4::ScopedValue rv(scope, LoadProperty<ReadAccessor::Accessor>(ctx->engine->v8Engine, m_object, *result, nptr));
if (result->accessors->notifier) { if (result->accessors->notifier) {
if (n) ep->captureProperty(n); if (n)
ep->captureProperty(n);
} else { } else {
ep->captureProperty(m_object, result->coreIndex, result->notifyIndex); ep->captureProperty(m_object, result->coreIndex, result->notifyIndex);
} }
return rv; return rv.asReturnedValue();
} }
if (ep && !result->isConstant()) if (ep && !result->isConstant())
@ -383,25 +374,26 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
} }
} }
Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty) ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty)
{ {
QV4::Scope scope(ctx);
if (QQmlData::wasDeleted(object)) { if (QQmlData::wasDeleted(object)) {
if (hasProperty) if (hasProperty)
*hasProperty = false; *hasProperty = false;
return QV4::Value::nullValue(); return QV4::Encode::null();
} }
if (!QQmlData::get(object, true)) { if (!QQmlData::get(object, true)) {
if (hasProperty) if (hasProperty)
*hasProperty = false; *hasProperty = false;
return QV4::Value::nullValue(); return QV4::Encode::null();
} }
QObjectWrapper *wrapper = wrap(ctx->engine, object).as<QV4::QObjectWrapper>(); QV4::Scoped<QObjectWrapper> wrapper(scope, wrap(ctx->engine, object));
if (!wrapper) { if (!wrapper) {
if (hasProperty) if (hasProperty)
*hasProperty = false; *hasProperty = false;
return QV4::Value::nullValue(); return QV4::Encode::null();
} }
return wrapper->getQmlProperty(ctx, qmlContext, name, revisionMode, hasProperty); return wrapper->getQmlProperty(ctx, qmlContext, name, revisionMode, hasProperty);
} }
@ -540,57 +532,59 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC
return true; return true;
} }
Value QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object)
{ {
if (QQmlData::wasDeleted(object)) if (QQmlData::wasDeleted(object))
return QV4::Value::nullValue(); return QV4::Encode::null();
QQmlData *ddata = QQmlData::get(object, true); QQmlData *ddata = QQmlData::get(object, true);
if (!ddata) if (!ddata)
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
Scope scope(engine);
if (ddata->jsEngineId == engine->m_engineId && !ddata->jsWrapper.isEmpty()) { if (ddata->jsEngineId == engine->m_engineId && !ddata->jsWrapper.isEmpty()) {
// We own the JS object // We own the JS object
return ddata->jsWrapper.value(); return ddata->jsWrapper.value().asReturnedValue();
} else if (ddata->jsWrapper.isEmpty() && } else if (ddata->jsWrapper.isEmpty() &&
(ddata->jsEngineId == engine->m_engineId || // We own the QObject (ddata->jsEngineId == engine->m_engineId || // We own the QObject
ddata->jsEngineId == 0 || // No one owns the QObject ddata->jsEngineId == 0 || // No one owns the QObject
!ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted !ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted
QV4::Value rv = create(engine, ddata, object); QV4::ScopedValue rv(scope, create(engine, ddata, object));
ddata->jsWrapper = rv; ddata->jsWrapper = rv;
ddata->jsEngineId = engine->m_engineId; ddata->jsEngineId = engine->m_engineId;
return rv; return rv.asReturnedValue();
} else { } else {
// If this object is tainted, we have to check to see if it is in our // If this object is tainted, we have to check to see if it is in our
// tainted object list // tainted object list
Object *alternateWrapper = 0; Scoped<Object> alternateWrapper(scope, 0);
if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object) if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object)
alternateWrapper = engine->m_multiplyWrappedQObjects->value(object); alternateWrapper = Value::fromObject(engine->m_multiplyWrappedQObjects->value(object));
// If our tainted handle doesn't exist or has been collected, and there isn't // If our tainted handle doesn't exist or has been collected, and there isn't
// a handle in the ddata, we can assume ownership of the ddata->v8object // a handle in the ddata, we can assume ownership of the ddata->v8object
if (ddata->jsWrapper.isEmpty() && !alternateWrapper) { if (ddata->jsWrapper.isEmpty() && !alternateWrapper) {
QV4::Value result = create(engine, ddata, object); QV4::ScopedValue result(scope, create(engine, ddata, object));
ddata->jsWrapper = result; ddata->jsWrapper = result;
ddata->jsEngineId = engine->m_engineId; ddata->jsEngineId = engine->m_engineId;
return result; return result.asReturnedValue();
} }
if (!alternateWrapper) { if (!alternateWrapper) {
alternateWrapper = create(engine, ddata, object).asObject(); alternateWrapper = create(engine, ddata, object);
if (!engine->m_multiplyWrappedQObjects) if (!engine->m_multiplyWrappedQObjects)
engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap; engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap;
engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper); engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper.getPointer());
ddata->hasTaintedV8Object = true; ddata->hasTaintedV8Object = true;
} }
return QV4::Value::fromObject(alternateWrapper); return alternateWrapper.asReturnedValue();
} }
} }
QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObject *object) ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObject *object)
{ {
QQmlEngine *qmlEngine = engine->v8Engine->engine(); QQmlEngine *qmlEngine = engine->v8Engine->engine();
if (!ddata->propertyCache && qmlEngine) { if (!ddata->propertyCache && qmlEngine) {
@ -598,7 +592,7 @@ QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObj
if (ddata->propertyCache) ddata->propertyCache->addref(); if (ddata->propertyCache) ddata->propertyCache->addref();
} }
return Value::fromObject(new (engine->memoryManager) QV4::QObjectWrapper(engine, object)); return Value::fromObject(new (engine->memoryManager) QV4::QObjectWrapper(engine, object)).asReturnedValue();
} }
QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty) QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty)
@ -606,7 +600,7 @@ QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProper
QObjectWrapper *that = static_cast<QObjectWrapper*>(m); QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
ExecutionEngine *v4 = m->engine(); ExecutionEngine *v4 = m->engine();
QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4); QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4);
return that->getQmlProperty(v4->current, qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true).asReturnedValue(); return that->getQmlProperty(v4->current, qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true);
} }
void QObjectWrapper::put(Managed *m, String *name, const Value &value) void QObjectWrapper::put(Managed *m, String *name, const Value &value)
@ -707,9 +701,9 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
for (int ii = 0; ii < argCount; ++ii) { for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1]; int type = argsTypes[ii + 1];
if (type == qMetaTypeId<QVariant>()) { if (type == qMetaTypeId<QVariant>()) {
callData->args[ii] = v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1])); callData->args[ii] = QV4::Value::fromReturnedValue(v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1])));
} else { } else {
callData->args[ii] = v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1])); callData->args[ii] = QV4::Value::fromReturnedValue(v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1])));
} }
} }
@ -968,7 +962,7 @@ struct CallArgument {
inline void initAsType(int type); inline void initAsType(int type);
inline void fromValue(int type, QV8Engine *, const QV4::Value&); inline void fromValue(int type, QV8Engine *, const QV4::Value&);
inline QV4::Value toValue(QV8Engine *); inline ReturnedValue toValue(QV8Engine *);
private: private:
CallArgument(const CallArgument &); CallArgument(const CallArgument &);
@ -1052,7 +1046,7 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data()); QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data());
return args[0].toValue(engine).asReturnedValue(); return args[0].toValue(engine);
} else if (returnType != QMetaType::Void) { } else if (returnType != QMetaType::Void) {
@ -1063,7 +1057,7 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args); QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args);
return arg.toValue(engine).asReturnedValue(); return arg.toValue(engine);
} else { } else {
@ -1581,23 +1575,25 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::Value &
} }
} }
QV4::Value CallArgument::toValue(QV8Engine *engine) QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
{ {
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
if (type == qMetaTypeId<QJSValue>()) { if (type == qMetaTypeId<QJSValue>()) {
return QJSValuePrivate::get(*qjsValuePtr)->getValue(v4); return QJSValuePrivate::get(*qjsValuePtr)->getValue(v4);
} else if (type == QMetaType::Int) { } else if (type == QMetaType::Int) {
return QV4::Value::fromInt32(int(intValue)); return QV4::Encode(int(intValue));
} else if (type == QMetaType::UInt) { } else if (type == QMetaType::UInt) {
return QV4::Value::fromUInt32(intValue); return QV4::Encode((uint)intValue);
} else if (type == QMetaType::Bool) { } else if (type == QMetaType::Bool) {
return QV4::Value::fromBoolean(boolValue); return QV4::Encode(boolValue);
} else if (type == QMetaType::Double) { } else if (type == QMetaType::Double) {
return QV4::Value::fromDouble(doubleValue); return QV4::Encode(doubleValue);
} else if (type == QMetaType::Float) { } else if (type == QMetaType::Float) {
return QV4::Value::fromDouble(floatValue); return QV4::Encode(floatValue);
} else if (type == QMetaType::QString) { } else if (type == QMetaType::QString) {
return engine->toString(*qstringPtr); return engine->toString(*qstringPtr).asReturnedValue();
} else if (type == QMetaType::QObjectStar) { } else if (type == QMetaType::QObjectStar) {
QObject *object = qobjectPtr; QObject *object = qobjectPtr;
if (object) if (object)
@ -1611,11 +1607,11 @@ QV4::Value CallArgument::toValue(QV8Engine *engine)
array->arrayReserve(list.count()); array->arrayReserve(list.count());
array->arrayDataLen = list.count(); array->arrayDataLen = list.count();
for (int ii = 0; ii < list.count(); ++ii) for (int ii = 0; ii < list.count(); ++ii)
array->arrayData[ii].value = QV4::QObjectWrapper::wrap(v4, list.at(ii)); array->arrayData[ii].value = Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, list.at(ii)));
array->setArrayLengthUnchecked(list.count()); array->setArrayLengthUnchecked(list.count());
return QV4::Value::fromObject(array); return QV4::Value::fromObject(array).asReturnedValue();
} else if (type == qMetaTypeId<QQmlV4Handle>()) { } else if (type == qMetaTypeId<QQmlV4Handle>()) {
return handlePtr->toValue(); return handlePtr->toValue().asReturnedValue();
} else if (type == QMetaType::QJsonArray) { } else if (type == QMetaType::QJsonArray) {
return QV4::JsonObject::fromJsonArray(v4, *jsonArrayPtr); return QV4::JsonObject::fromJsonArray(v4, *jsonArrayPtr);
} else if (type == QMetaType::QJsonObject) { } else if (type == QMetaType::QJsonObject) {
@ -1624,14 +1620,14 @@ QV4::Value CallArgument::toValue(QV8Engine *engine)
return QV4::JsonObject::fromJsonValue(v4, *jsonValuePtr); return QV4::JsonObject::fromJsonValue(v4, *jsonValuePtr);
} else if (type == -1 || type == qMetaTypeId<QVariant>()) { } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
QVariant value = *qvariantPtr; QVariant value = *qvariantPtr;
QV4::Value rv = engine->fromVariant(value); QV4::ScopedValue rv(scope, engine->fromVariant(value));
if (QV4::QObjectWrapper *qobjectWrapper = rv.as<QV4::QObjectWrapper>()) { if (QV4::QObjectWrapper *qobjectWrapper = rv->as<QV4::QObjectWrapper>()) {
if (QObject *object = qobjectWrapper->object()) if (QObject *object = qobjectWrapper->object())
QQmlData::get(object, true)->setImplicitDestructible(); QQmlData::get(object, true)->setImplicitDestructible();
} }
return rv; return rv.asReturnedValue();
} else { } else {
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} }
} }

View File

@ -85,17 +85,17 @@ struct Q_QML_EXPORT QObjectWrapper : public QV4::Object
QObject *object() const { return m_object.data(); } QObject *object() const { return m_object.data(); }
Value getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false); ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false);
static Value getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0); static ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0);
static bool setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value); static bool setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value);
static Value wrap(ExecutionEngine *engine, QObject *object); static ReturnedValue wrap(ExecutionEngine *engine, QObject *object);
using Object::get; using Object::get;
private: private:
static Value create(ExecutionEngine *engine, QQmlData *ddata, QObject *object); static ReturnedValue create(ExecutionEngine *engine, QQmlData *ddata, QObject *object);
QObjectWrapper(ExecutionEngine *engine, QObject *object); QObjectWrapper(ExecutionEngine *engine, QObject *object);

View File

@ -755,7 +755,7 @@ ReturnedValue __qmljs_foreach_next_property_name(const ValueRef foreach_iterator
ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator->objectValue()); ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator->objectValue());
Q_ASSERT(it->as<ForEachIteratorObject>()); Q_ASSERT(it->as<ForEachIteratorObject>());
return it->nextPropertyName().asReturnedValue(); return it->nextPropertyName();
} }

View File

@ -263,12 +263,12 @@ Function *Script::function()
return vmFunction; return vmFunction;
} }
Value Script::qmlBinding() ReturnedValue Script::qmlBinding()
{ {
if (!parsed) if (!parsed)
parse(); parse();
QV4::ExecutionEngine *v4 = scope->engine; QV4::ExecutionEngine *v4 = scope->engine;
return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject())); return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject())).asReturnedValue();
} }
QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject) QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject)

View File

@ -75,7 +75,7 @@ struct Q_QML_EXPORT Script {
void parse(); void parse();
ReturnedValue run(); ReturnedValue run();
Value qmlBinding(); ReturnedValue qmlBinding();
Function *function(); Function *function();

View File

@ -571,36 +571,38 @@ bool SequencePrototype::isSequenceType(int sequenceTypeId)
#define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \ #define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \ if (sequenceType == qMetaTypeId<SequenceType>()) { \
QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex); \ QV4::Scoped<QV4::Object> obj(scope, QV4::Value::fromObject(new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex))); \
return QV4::Value::fromObject(obj); \ return obj.asReturnedValue(); \
} else } else
QV4::Value SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int sequenceType, QObject *object, int propertyIndex, bool *succeeded) ReturnedValue SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int sequenceType, QObject *object, int propertyIndex, bool *succeeded)
{ {
QV4::Scope scope(engine);
// This function is called when the property is a QObject Q_PROPERTY of // This function is called when the property is a QObject Q_PROPERTY of
// the given sequence type. Internally we store a typed-sequence // the given sequence type. Internally we store a typed-sequence
// (as well as object ptr + property index for updated-read and write-back) // (as well as object ptr + property index for updated-read and write-back)
// and so access/mutate avoids variant conversion. // and so access/mutate avoids variant conversion.
*succeeded = true; *succeeded = true;
FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return QV4::Value::undefinedValue(); } FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return QV4::Encode::undefined(); }
} }
#undef NEW_REFERENCE_SEQUENCE #undef NEW_REFERENCE_SEQUENCE
#define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \ #define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \ if (sequenceType == qMetaTypeId<SequenceType>()) { \
QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value<SequenceType >()); \ QV4::Scoped<QV4::Object> obj(scope, QV4::Value::fromObject(new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value<SequenceType >()))); \
return QV4::Value::fromObject(obj); \ return obj.asReturnedValue(); \
} else } else
QV4::Value SequencePrototype::fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded) ReturnedValue SequencePrototype::fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded)
{ {
QV4::Scope scope(engine);
// This function is called when assigning a sequence value to a normal JS var // This function is called when assigning a sequence value to a normal JS var
// in a JS block. Internally, we store a sequence of the specified type. // in a JS block. Internally, we store a sequence of the specified type.
// Access and mutation is extremely fast since it will not need to modify any // Access and mutation is extremely fast since it will not need to modify any
// QObject property. // QObject property.
int sequenceType = v.userType(); int sequenceType = v.userType();
*succeeded = true; *succeeded = true;
FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return QV4::Value::undefinedValue(); } FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return QV4::Encode::undefined(); }
} }
#undef NEW_COPY_SEQUENCE #undef NEW_COPY_SEQUENCE

View File

@ -69,7 +69,7 @@ struct SequencePrototype : public QV4::Object
void init(QV4::ExecutionEngine *engine); void init(QV4::ExecutionEngine *engine);
static QV4::ReturnedValue method_valueOf(QV4::SimpleCallContext *ctx) static ReturnedValue method_valueOf(QV4::SimpleCallContext *ctx)
{ {
return QV4::Value::fromString(ctx->thisObject.toString(ctx)).asReturnedValue(); return QV4::Value::fromString(ctx->thisObject.toString(ctx)).asReturnedValue();
} }
@ -77,8 +77,8 @@ struct SequencePrototype : public QV4::Object
static ReturnedValue method_sort(QV4::SimpleCallContext *ctx); static ReturnedValue method_sort(QV4::SimpleCallContext *ctx);
static bool isSequenceType(int sequenceTypeId); static bool isSequenceType(int sequenceTypeId);
static QV4::Value newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded); static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
static QV4::Value fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded); static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded);
static int metaTypeForSequence(QV4::Object *object); static int metaTypeForSequence(QV4::Object *object);
static QVariant toVariant(QV4::Object *object); static QVariant toVariant(QV4::Object *object);
static QVariant toVariant(const QV4::Value &array, int typeHint, bool *succeeded); static QVariant toVariant(const QV4::Value &array, int typeHint, bool *succeeded);

View File

@ -287,28 +287,29 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi
} }
} }
QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine) ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
{ {
quint32 header = popUint32(data); quint32 header = popUint32(data);
Type type = headertype(header); Type type = headertype(header);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
Scope scope(v4);
switch (type) { switch (type) {
case WorkerUndefined: case WorkerUndefined:
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
case WorkerNull: case WorkerNull:
return QV4::Value::nullValue(); return QV4::Encode::null();
case WorkerTrue: case WorkerTrue:
return QV4::Value::fromBoolean(true); return QV4::Encode(true);
case WorkerFalse: case WorkerFalse:
return QV4::Value::fromBoolean(false); return QV4::Encode(false);
case WorkerString: case WorkerString:
{ {
quint32 size = headersize(header); quint32 size = headersize(header);
QString qstr((QChar *)data, size); QString qstr((QChar *)data, size);
data += ALIGN(size * sizeof(uint16_t)); data += ALIGN(size * sizeof(uint16_t));
return QV4::Value::fromString(v4->newString(qstr)); return QV4::Value::fromString(v4->newString(qstr)).asReturnedValue();
} }
case WorkerFunction: case WorkerFunction:
Q_ASSERT(!"Unreachable"); Q_ASSERT(!"Unreachable");
@ -317,70 +318,79 @@ QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine)
{ {
quint32 size = headersize(header); quint32 size = headersize(header);
QV4::ArrayObject *a = v4->newArrayObject(); QV4::ArrayObject *a = v4->newArrayObject();
ScopedValue v(scope);
for (quint32 ii = 0; ii < size; ++ii) { for (quint32 ii = 0; ii < size; ++ii) {
a->putIndexed(ii, deserialize(data, engine)); v = deserialize(data, engine);
a->putIndexed(ii, v);
} }
return QV4::Value::fromObject(a); return QV4::Value::fromObject(a).asReturnedValue();
} }
case WorkerObject: case WorkerObject:
{ {
quint32 size = headersize(header); quint32 size = headersize(header);
QV4::Object *o = v4->newObject(); QV4::Object *o = v4->newObject();
ScopedValue name(scope);
ScopedValue value(scope);
for (quint32 ii = 0; ii < size; ++ii) { for (quint32 ii = 0; ii < size; ++ii) {
QV4::Value name = deserialize(data, engine); name = deserialize(data, engine);
QV4::Value value = deserialize(data, engine); value = deserialize(data, engine);
o->put(name.asString(), value); o->put(name->asString(), value);
} }
return QV4::Value::fromObject(o); return QV4::Value::fromObject(o).asReturnedValue();
} }
case WorkerInt32: case WorkerInt32:
return QV4::Value::fromInt32((qint32)popUint32(data)); return QV4::Encode((qint32)popUint32(data));
case WorkerUint32: case WorkerUint32:
return QV4::Value::fromUInt32(popUint32(data)); return QV4::Encode(popUint32(data));
case WorkerNumber: case WorkerNumber:
return QV4::Value::fromDouble(popDouble(data)); return QV4::Encode(popDouble(data));
case WorkerDate: case WorkerDate:
return QV4::Value::fromObject(v4->newDateObject(QV4::Value::fromDouble(popDouble(data)))); return QV4::Value::fromObject(v4->newDateObject(QV4::Value::fromDouble(popDouble(data)))).asReturnedValue();
case WorkerRegexp: case WorkerRegexp:
{ {
quint32 flags = headersize(header); quint32 flags = headersize(header);
quint32 length = popUint32(data); quint32 length = popUint32(data);
QString pattern = QString((QChar *)data, length - 1); QString pattern = QString((QChar *)data, length - 1);
data += ALIGN(length * sizeof(uint16_t)); data += ALIGN(length * sizeof(uint16_t));
return QV4::Value::fromObject(v4->newRegExpObject(pattern, flags)); return QV4::Value::fromObject(v4->newRegExpObject(pattern, flags)).asReturnedValue();
} }
case WorkerListModel: case WorkerListModel:
{ {
void *ptr = popPtr(data); void *ptr = popPtr(data);
QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr; QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr;
QV4::Value rv = QV4::QObjectWrapper::wrap(v4, agent); QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, agent));
// ### Find a better solution then the ugly property // ### Find a better solution then the ugly property
QQmlListModelWorkerAgent::VariantRef ref(agent); QQmlListModelWorkerAgent::VariantRef ref(agent);
QVariant var = qVariantFromValue(ref); QVariant var = qVariantFromValue(ref);
rv.asObject()->defineReadonlyProperty(v4->newString("__qml:hidden:ref"), engine->fromVariant(var)); QV4::ScopedValue v(scope, engine->fromVariant((var)));
rv->asObject()->defineReadonlyProperty(v4->newString("__qml:hidden:ref"), v);
agent->release(); agent->release();
agent->setV8Engine(engine); agent->setV8Engine(engine);
return rv; return rv.asReturnedValue();
} }
case WorkerSequence: case WorkerSequence:
{ {
ScopedValue value(scope);
bool succeeded = false; bool succeeded = false;
quint32 length = headersize(header); quint32 length = headersize(header);
quint32 seqLength = length - 1; quint32 seqLength = length - 1;
int sequenceType = deserialize(data, engine).integerValue(); value = deserialize(data, engine);
int sequenceType = value->integerValue();
QV4::ArrayObject *array = v4->newArrayObject(); QV4::ArrayObject *array = v4->newArrayObject();
array->arrayReserve(seqLength); array->arrayReserve(seqLength);
array->arrayDataLen = seqLength; array->arrayDataLen = seqLength;
for (quint32 ii = 0; ii < seqLength; ++ii) for (quint32 ii = 0; ii < seqLength; ++ii) {
array->arrayData[ii].value = deserialize(data, engine); value = deserialize(data, engine);
array->arrayData[ii].value = value;
}
array->setArrayLengthUnchecked(seqLength); array->setArrayLengthUnchecked(seqLength);
QVariant seqVariant = QV4::SequencePrototype::toVariant(QV4::Value::fromObject(array), sequenceType, &succeeded); QVariant seqVariant = QV4::SequencePrototype::toVariant(QV4::Value::fromObject(array), sequenceType, &succeeded);
return QV4::SequencePrototype::fromVariant(v4, seqVariant, &succeeded); return QV4::SequencePrototype::fromVariant(v4, seqVariant, &succeeded);
} }
} }
Q_ASSERT(!"Unreachable"); Q_ASSERT(!"Unreachable");
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} }
QByteArray Serialize::serialize(const QV4::Value &value, QV8Engine *engine) QByteArray Serialize::serialize(const QV4::Value &value, QV8Engine *engine)
@ -390,7 +400,7 @@ QByteArray Serialize::serialize(const QV4::Value &value, QV8Engine *engine)
return rv; return rv;
} }
QV4::Value Serialize::deserialize(const QByteArray &data, QV8Engine *engine) ReturnedValue Serialize::deserialize(const QByteArray &data, QV8Engine *engine)
{ {
const char *stream = data.constData(); const char *stream = data.constData();
return deserialize(stream, engine); return deserialize(stream, engine);

View File

@ -66,11 +66,11 @@ class Serialize {
public: public:
static QByteArray serialize(const Value &, QV8Engine *); static QByteArray serialize(const Value &, QV8Engine *);
static Value deserialize(const QByteArray &, QV8Engine *); static ReturnedValue deserialize(const QByteArray &, QV8Engine *);
private: private:
static void serialize(QByteArray &, const Value &, QV8Engine *); static void serialize(QByteArray &, const Value &, QV8Engine *);
static Value deserialize(const char *&, QV8Engine *); static ReturnedValue deserialize(const char *&, QV8Engine *);
}; };
} }

View File

@ -244,12 +244,13 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
} else { } else {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
QV4::Scope scope(ep->v4engine());
ep->referenceScarceResources(); ep->referenceScarceResources();
bool isUndefined = false; bool isUndefined = false;
QV4::Value result = QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined));
QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined);
trace.event("writing binding result"); trace.event("writing binding result");
@ -285,12 +286,12 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
QVariant QQmlBinding::evaluate() QVariant QQmlBinding::evaluate()
{ {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
QV4::Scope scope(ep->v4engine());
ep->referenceScarceResources(); ep->referenceScarceResources();
bool isUndefined = false; bool isUndefined = false;
QV4::Value result = QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined));
QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined);
ep->dereferenceScarceResources(); ep->dereferenceScarceResources();

View File

@ -194,7 +194,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
// for several cases (such as QVariant type and QObject-derived types) // for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]); //args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == QMetaType::QVariant) { if (type == QMetaType::QVariant) {
args[ii] = engine->fromVariant(*((QVariant *)a[ii + 1])); args[ii] = QV4::Value::fromReturnedValue(engine->fromVariant(*((QVariant *)a[ii + 1])));
} else if (type == QMetaType::Int) { } else if (type == QMetaType::Int) {
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise //### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
args[ii] = QV4::Value::fromInt32(*reinterpret_cast<const int*>(a[ii + 1])); args[ii] = QV4::Value::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
@ -204,9 +204,9 @@ void QQmlBoundSignalExpression::evaluate(void **a)
if (!*reinterpret_cast<void* const *>(a[ii + 1])) if (!*reinterpret_cast<void* const *>(a[ii + 1]))
args[ii] = QV4::Value::nullValue(); args[ii] = QV4::Value::nullValue();
else else
args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1])); args[ii] = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1])));
} else { } else {
args[ii] = engine->fromVariant(QVariant(type, a[ii + 1])); args[ii] = QV4::Value::fromReturnedValue(engine->fromVariant(QVariant(type, a[ii + 1])));
} }
} }

View File

@ -1221,8 +1221,8 @@ void QQmlComponent::createObject(QQmlV4Function *args)
QQmlComponent_setQmlParent(rv, parent); QQmlComponent_setQmlParent(rv, parent);
QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, rv); QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, rv));
Q_ASSERT(object.asObject()); Q_ASSERT(object->isObject());
if (!valuemap.isEmpty()) { if (!valuemap.isEmpty()) {
QQmlComponentExtension *e = componentExtension(v8engine); QQmlComponentExtension *e = componentExtension(v8engine);
@ -1369,8 +1369,8 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu
QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
QV4::Scope scope(v4engine); QV4::Scope scope(v4engine);
QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, toCreate); QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate));
Q_ASSERT(object.asObject()); Q_ASSERT(object->asObject());
if (!valuemap.isEmpty()) { if (!valuemap.isEmpty()) {
QQmlComponentExtension *e = componentExtension(v8engine); QQmlComponentExtension *e = componentExtension(v8engine);
@ -1412,7 +1412,7 @@ QV4::ReturnedValue QmlIncubatorObject::method_get_object(QV4::SimpleCallContext
if (!o) if (!o)
ctx->throwTypeError(); ctx->throwTypeError();
return QV4::QObjectWrapper::wrap(ctx->engine, o->object()).asReturnedValue(); return QV4::QObjectWrapper::wrap(ctx->engine, o->object());
} }
QV4::ReturnedValue QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ctx) QV4::ReturnedValue QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ctx)
@ -1478,7 +1478,7 @@ void QmlIncubatorObject::setInitialState(QObject *o)
QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject())); QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()));
QV4::ScopedCallData callData(scope, 2); QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4->globalObject); callData->thisObject = QV4::Value::fromObject(v4->globalObject);
callData->args[0] = QV4::QObjectWrapper::wrap(v4, o); callData->args[0] = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, o));
callData->args[1] = valuemap; callData->args[1] = valuemap;
f->call(callData); f->call(callData);
} }

View File

@ -73,15 +73,15 @@ QmlContextWrapper::~QmlContextWrapper()
context->destroy(); context->destroy();
} }
QV4::Value QmlContextWrapper::qmlScope(QV8Engine *v8, QQmlContextData *ctxt, QObject *scope) ReturnedValue QmlContextWrapper::qmlScope(QV8Engine *v8, QQmlContextData *ctxt, QObject *scope)
{ {
ExecutionEngine *v4 = QV8Engine::getV4(v8); ExecutionEngine *v4 = QV8Engine::getV4(v8);
QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, ctxt, scope); QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, ctxt, scope);
return Value::fromObject(w); return Value::fromObject(w).asReturnedValue();
} }
QV4::Value QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url) ReturnedValue QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url)
{ {
ExecutionEngine *v4 = QV8Engine::getV4(v8); ExecutionEngine *v4 = QV8Engine::getV4(v8);
@ -92,7 +92,7 @@ QV4::Value QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url)
QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, context, 0); QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, context, 0);
w->isNullWrapper = true; w->isNullWrapper = true;
return Value::fromObject(w); return Value::fromObject(w).asReturnedValue();
} }
QQmlContextData *QmlContextWrapper::callingContext(ExecutionEngine *v4) QQmlContextData *QmlContextWrapper::callingContext(ExecutionEngine *v4)
@ -192,9 +192,9 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty
else else
return QV4::Value::undefinedValue().asReturnedValue(); return QV4::Value::undefinedValue().asReturnedValue();
} else if (r.type) { } else if (r.type) {
return QmlTypeWrapper::create(engine, scopeObject, r.type).asReturnedValue(); return QmlTypeWrapper::create(engine, scopeObject, r.type);
} else if (r.importNamespace) { } else if (r.importNamespace) {
return QmlTypeWrapper::create(engine, scopeObject, context->imports, r.importNamespace).asReturnedValue(); return QmlTypeWrapper::create(engine, scopeObject, context->imports, r.importNamespace);
} }
Q_ASSERT(!"Unreachable"); Q_ASSERT(!"Unreachable");
} }
@ -216,7 +216,7 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty
ep->captureProperty(&context->idValues[propertyIdx].bindings); ep->captureProperty(&context->idValues[propertyIdx].bindings);
if (hasProperty) if (hasProperty)
*hasProperty = true; *hasProperty = true;
return QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]).asReturnedValue(); return QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]);
} else { } else {
QQmlContextPrivate *cp = context->asQQmlContextPrivate(); QQmlContextPrivate *cp = context->asQQmlContextPrivate();
@ -231,9 +231,9 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty
QQmlListProperty<QObject> prop(context->asQQmlContext(), (void*) qintptr(propertyIdx), QQmlListProperty<QObject> prop(context->asQQmlContext(), (void*) qintptr(propertyIdx),
QQmlContextPrivate::context_count, QQmlContextPrivate::context_count,
QQmlContextPrivate::context_at); QQmlContextPrivate::context_at);
return QmlListWrapper::create(engine, prop, qMetaTypeId<QQmlListProperty<QObject> >()).asReturnedValue(); return QmlListWrapper::create(engine, prop, qMetaTypeId<QQmlListProperty<QObject> >());
} else { } else {
return engine->fromVariant(cp->propertyValues.at(propertyIdx)).asReturnedValue(); return engine->fromVariant(cp->propertyValues.at(propertyIdx));
} }
} }
} }
@ -242,7 +242,8 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty
// Search scope object // Search scope object
if (scopeObject) { if (scopeObject) {
bool hasProp = false; bool hasProp = false;
QV4::Value result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, scopeObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp); QV4::ScopedValue result(scope, QV4::QObjectWrapper::getQmlProperty(v4->current, context, scopeObject,
name, QV4::QObjectWrapper::CheckRevision, &hasProp));
if (hasProp) { if (hasProp) {
if (hasProperty) if (hasProperty)
*hasProperty = true; *hasProperty = true;

View File

@ -70,8 +70,8 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext = false); QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext = false);
~QmlContextWrapper(); ~QmlContextWrapper();
static QV4::Value qmlScope(QV8Engine *e, QQmlContextData *ctxt, QObject *scope); static ReturnedValue qmlScope(QV8Engine *e, QQmlContextData *ctxt, QObject *scope);
static QV4::Value urlScope(QV8Engine *e, const QUrl &); static ReturnedValue urlScope(QV8Engine *e, const QUrl &);
static QQmlContextData *callingContext(ExecutionEngine *v4); static QQmlContextData *callingContext(ExecutionEngine *v4);
static void takeContextOwnership(const QV4::Value &qmlglobal); static void takeContextOwnership(const QV4::Value &qmlglobal);

View File

@ -260,7 +260,7 @@ void QQmlExpression::setExpression(const QString &expression)
} }
// Must be called with a valid handle scope // Must be called with a valid handle scope
QV4::Value QQmlExpressionPrivate::v4value(bool *isUndefined) QV4::ReturnedValue QQmlExpressionPrivate::v4value(bool *isUndefined)
{ {
if (!expressionFunctionValid) { if (!expressionFunctionValid) {
function = qmlBinding(context(), scopeObject(), expression, url, line, &qmlscope); function = qmlBinding(context(), scopeObject(), expression, url, line, &qmlscope);
@ -285,7 +285,8 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined)
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
{ {
QV4::Value result = v4value(isUndefined); QV4::Scope scope(QV8Engine::getV4(ep->v8engine()));
QV4::ScopedValue result(scope, v4value(isUndefined));
rv = ep->v8engine()->toVariant(result, -1); rv = ep->v8engine()->toVariant(result, -1);
} }

View File

@ -81,7 +81,7 @@ public:
QVariant value(bool *isUndefined = 0); QVariant value(bool *isUndefined = 0);
QV4::Value v4value(bool *isUndefined = 0); QV4::ReturnedValue v4value(bool *isUndefined = 0);
static inline QQmlExpressionPrivate *get(QQmlExpression *expr); static inline QQmlExpressionPrivate *get(QQmlExpression *expr);
static inline QQmlExpression *get(QQmlExpressionPrivate *expr); static inline QQmlExpression *get(QQmlExpressionPrivate *expr);

View File

@ -122,15 +122,13 @@ void QQmlJavaScriptExpression::resetNotifyOnValueChanged()
clearGuards(); clearGuards();
} }
QV4::Value QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
const QV4::Value &function, bool *isUndefined) const QV4::Value &function, bool *isUndefined)
{ {
return evaluate(context, function, 0, 0, isUndefined); return evaluate(context, function, 0, 0, isUndefined);
} }
QV4::Value QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
const QV4::Value &function, const QV4::Value &function,
int argc, QV4::Value *args, int argc, QV4::Value *args,
bool *isUndefined) bool *isUndefined)
@ -140,7 +138,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
if (function.isEmpty() || function.isUndefined()) { if (function.isEmpty() || function.isUndefined()) {
if (isUndefined) if (isUndefined)
*isUndefined = true; *isUndefined = true;
return QV4::Value::emptyValue(); return QV4::Value::emptyValue().asReturnedValue();
} }
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
@ -167,15 +165,14 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
QV4::ScopedValue result(scope, QV4::Value::undefinedValue()); QV4::ScopedValue result(scope, QV4::Value::undefinedValue());
QV4::ExecutionContext *ctx = v4->current; QV4::ExecutionContext *ctx = v4->current;
try { try {
QV4::Value This = ep->v8engine()->global(); QV4::ScopedCallData callData(scope, argc);
callData->thisObject = ep->v8engine()->global();
if (scopeObject() && requiresThisObject()) { if (scopeObject() && requiresThisObject()) {
QV4::Value value = QV4::QObjectWrapper::wrap(ctx->engine, scopeObject()); QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(ctx->engine, scopeObject()));
if (value.isObject()) if (value->isObject())
This = value; callData->thisObject = value;
} }
QV4::ScopedCallData callData(scope, argc);
callData->thisObject = This;
memcpy(callData->args, args, argc*sizeof(QV4::Value)); memcpy(callData->args, args, argc*sizeof(QV4::Value));
result = function.asFunctionObject()->call(callData); result = function.asFunctionObject()->call(callData);
@ -211,7 +208,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
ep->propertyCapture = lastPropertyCapture; ep->propertyCapture = lastPropertyCapture;
return result; return result.asReturnedValue();
} }
void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n) void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n)
@ -360,7 +357,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObje
return result.asReturnedValue(); return result.asReturnedValue();
} }
QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *scope, QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *qmlScope,
const QString &code, const QString &filename, quint16 line, const QString &code, const QString &filename, quint16 line,
QV4::PersistentValue *qmlscope) QV4::PersistentValue *qmlscope)
{ {
@ -369,10 +366,11 @@ QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt,
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine()); QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
QV4::ExecutionContext *ctx = v4->current; QV4::ExecutionContext *ctx = v4->current;
QV4::Scope scope(v4);
QV4::Value scopeObject = QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scope); QV4::ScopedValue qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, qmlScope));
QV4::Script script(v4, scopeObject.asObject(), code, filename, line); QV4::Script script(v4, qmlScopeObject->asObject(), code, filename, line);
QV4::Value result; QV4::ScopedValue result(scope);
try { try {
script.parse(); script.parse();
result = script.qmlBinding(); result = script.qmlBinding();
@ -386,13 +384,13 @@ QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt,
error.setLine(line); error.setLine(line);
if (error.url().isEmpty()) if (error.url().isEmpty())
error.setUrl(QUrl::fromLocalFile(filename)); error.setUrl(QUrl::fromLocalFile(filename));
error.setObject(scope); error.setObject(qmlScope);
ep->warning(error); ep->warning(error);
return QV4::PersistentValue(); return QV4::PersistentValue();
} }
if (qmlscope) if (qmlscope)
*qmlscope = scopeObject; *qmlscope = qmlScopeObject;
return result; return result.asReturnedValue();
} }

View File

@ -110,9 +110,9 @@ public:
QQmlJavaScriptExpression(VTable *vtable); QQmlJavaScriptExpression(VTable *vtable);
QV4::Value evaluate(QQmlContextData *, const QV4::Value &function, QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function,
bool *isUndefined); bool *isUndefined);
QV4::Value evaluate(QQmlContextData *, const QV4::Value &function, QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function,
int argc, QV4::Value *args, int argc, QV4::Value *args,
bool *isUndefined); bool *isUndefined);

View File

@ -63,10 +63,10 @@ QmlListWrapper::~QmlListWrapper()
{ {
} }
Value QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int propType) ReturnedValue QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int propType)
{ {
if (!object || propId == -1) if (!object || propId == -1)
return Value::nullValue(); return Encode::null();
ExecutionEngine *v4 = QV8Engine::getV4(v8); ExecutionEngine *v4 = QV8Engine::getV4(v8);
@ -75,10 +75,10 @@ Value QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int pro
r->propertyType = propType; r->propertyType = propType;
void *args[] = { &r->property, 0 }; void *args[] = { &r->property, 0 };
QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args); QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args);
return Value::fromObject(r); return Value::fromObject(r).asReturnedValue();
} }
Value QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType) ReturnedValue QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType)
{ {
ExecutionEngine *v4 = QV8Engine::getV4(v8); ExecutionEngine *v4 = QV8Engine::getV4(v8);
@ -86,7 +86,7 @@ Value QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty<QObject> &pro
r->object = prop.object; r->object = prop.object;
r->property = prop; r->property = prop;
r->propertyType = propType; r->propertyType = propType;
return Value::fromObject(r); return Value::fromObject(r).asReturnedValue();
} }
QVariant QmlListWrapper::toVariant() const QVariant QmlListWrapper::toVariant() const
@ -126,7 +126,7 @@ ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProper
quint32 count = w->property.count ? w->property.count(&w->property) : 0; quint32 count = w->property.count ? w->property.count(&w->property) : 0;
if (index < count && w->property.at) if (index < count && w->property.at)
return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index)).asReturnedValue(); return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index));
return Value::undefinedValue().asReturnedValue(); return Value::undefinedValue().asReturnedValue();
} }
@ -156,7 +156,7 @@ Property *QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, String
*attrs = QV4::Attr_Data; *attrs = QV4::Attr_Data;
*index = it->arrayIndex; *index = it->arrayIndex;
++it->arrayIndex; ++it->arrayIndex;
it->tmpDynamicProperty.value = QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index)); it->tmpDynamicProperty.value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index)));
return &it->tmpDynamicProperty; return &it->tmpDynamicProperty;
} }
return QV4::Object::advanceIterator(m, it, name, index, attrs); return QV4::Object::advanceIterator(m, it, name, index, attrs);

View File

@ -76,8 +76,8 @@ protected:
public: public:
static Value create(QV8Engine *v8, QObject *object, int propId, int propType); static ReturnedValue create(QV8Engine *v8, QObject *object, int propId, int propType);
static Value create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType); static ReturnedValue create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType);
QVariant toVariant() const; QVariant toVariant() const;

View File

@ -807,7 +807,7 @@ QQmlLocale::~QQmlLocale()
{ {
} }
QV4::Value QQmlLocale::locale(QV8Engine *v8engine, const QString &locale) QV4::ReturnedValue QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
{ {
QV8LocaleDataDeletable *d = localeV8Data(v8engine); QV8LocaleDataDeletable *d = localeV8Data(v8engine);
QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine); QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine);
@ -815,7 +815,7 @@ QV4::Value QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
if (!locale.isEmpty()) if (!locale.isEmpty())
wrapper->locale = QLocale(locale); wrapper->locale = QLocale(locale);
wrapper->setPrototype(d->prototype.value().asObject()); wrapper->setPrototype(d->prototype.value().asObject());
return QV4::Value::fromObject(wrapper); return QV4::Value::fromObject(wrapper).asReturnedValue();
} }
void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine) void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)

View File

@ -118,7 +118,7 @@ public:
Saturday = Qt::Saturday Saturday = Qt::Saturday
}; };
static QV4::Value locale(QV8Engine *v8engine, const QString &lang); static QV4::ReturnedValue locale(QV8Engine *v8engine, const QString &lang);
static void registerStringLocaleCompare(QV4::ExecutionEngine *engine); static void registerStringLocaleCompare(QV4::ExecutionEngine *engine);

View File

@ -87,19 +87,19 @@ QVariant QmlTypeWrapper::toVariant() const
// Returns a type wrapper for type t on o. This allows access of enums, and attached properties. // Returns a type wrapper for type t on o. This allows access of enums, and attached properties.
Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMode mode) ReturnedValue QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMode mode)
{ {
Q_ASSERT(t); Q_ASSERT(t);
ExecutionEngine *v4 = QV8Engine::getV4(v8); ExecutionEngine *v4 = QV8Engine::getV4(v8);
QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8); QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8);
w->mode = mode; w->object = o; w->type = t; w->mode = mode; w->object = o; w->type = t;
return Value::fromObject(w); return Value::fromObject(w).asReturnedValue();
} }
// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a // Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a
// namespace. // namespace.
Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, TypeNameMode mode) ReturnedValue QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, TypeNameMode mode)
{ {
Q_ASSERT(t); Q_ASSERT(t);
Q_ASSERT(importNamespace); Q_ASSERT(importNamespace);
@ -108,17 +108,20 @@ Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, co
QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8); QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8);
w->mode = mode; w->object = o; w->typeNamespace = t; w->importNamespace = importNamespace; w->mode = mode; w->object = o; w->typeNamespace = t; w->importNamespace = importNamespace;
t->addref(); t->addref();
return Value::fromObject(w); return Value::fromObject(w).asReturnedValue();
} }
ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
{ {
QmlTypeWrapper *w = m->as<QmlTypeWrapper>();
QV4::ExecutionEngine *v4 = m->engine(); QV4::ExecutionEngine *v4 = m->engine();
QV4::Scope scope(v4);
QmlTypeWrapper *w = m->as<QmlTypeWrapper>();
if (!w) if (!w)
v4->current->throwTypeError(); v4->current->throwTypeError();
if (hasProperty) if (hasProperty)
*hasProperty = true; *hasProperty = true;
@ -155,12 +158,12 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
} }
// check for property. // check for property.
return QV4::QObjectWrapper::getQmlProperty(v4->current, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty).asReturnedValue(); return QV4::QObjectWrapper::getQmlProperty(v4->current, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty);
} else if (!siinfo->scriptApi(e).isUndefined()) { } else if (!siinfo->scriptApi(e).isUndefined()) {
QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine); QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine);
// NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
QV4::Object *o = QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine).asObject(); QV4::Scoped<Object> o(scope, QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine));
if (o) if (!!o)
return o->get(name); return o->get(name);
} }
@ -179,7 +182,7 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
} else if (w->object) { } else if (w->object) {
QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
if (ao) if (ao)
return QV4::QObjectWrapper::getQmlProperty(v4->current, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty).asReturnedValue(); return QV4::QObjectWrapper::getQmlProperty(v4->current, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty);
// Fall through to base implementation // Fall through to base implementation
} }
@ -196,16 +199,16 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
if (r.isValid()) { if (r.isValid()) {
QQmlContextData *context = v8engine->callingContext(); QQmlContextData *context = v8engine->callingContext();
if (r.type) { if (r.type) {
return create(w->v8, object, r.type, w->mode).asReturnedValue(); return create(w->v8, object, r.type, w->mode);
} else if (r.scriptIndex != -1) { } else if (r.scriptIndex != -1) {
int index = r.scriptIndex; int index = r.scriptIndex;
if (index < context->importedScripts.count()) if (index < context->importedScripts.count())
return context->importedScripts.at(index).value().asReturnedValue(); return context->importedScripts.at(index).value().asReturnedValue();
} else if (r.importNamespace) { } else if (r.importNamespace) {
return create(w->v8, object, context->imports, r.importNamespace).asReturnedValue(); return create(w->v8, object, context->imports, r.importNamespace);
} }
return QV4::Value::undefinedValue().asReturnedValue(); return QV4::Encode::undefined();
} }

View File

@ -78,8 +78,8 @@ public:
QVariant toVariant() const; QVariant toVariant() const;
static QV4::Value create(QV8Engine *, QObject *, QQmlType *, TypeNameMode = IncludeEnums); static ReturnedValue create(QV8Engine *, QObject *, QQmlType *, TypeNameMode = IncludeEnums);
static QV4::Value create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums); static ReturnedValue create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums);
static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static ReturnedValue get(Managed *m, String *name, bool *hasProperty);

View File

@ -139,7 +139,7 @@ void QmlValueTypeWrapper::initProto(ExecutionEngine *v4)
v4->qmlExtensions()->valueTypeWrapperPrototype = o; v4->qmlExtensions()->valueTypeWrapperPrototype = o;
} }
Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type) ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type)
{ {
ExecutionEngine *v4 = QV8Engine::getV4(v8); ExecutionEngine *v4 = QV8Engine::getV4(v8);
initProto(v4); initProto(v4);
@ -147,10 +147,10 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property,
QmlValueTypeReference *r = new (v4->memoryManager) QmlValueTypeReference(v8); QmlValueTypeReference *r = new (v4->memoryManager) QmlValueTypeReference(v8);
r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype); r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->type = type; r->object = object; r->property = property; r->type = type; r->object = object; r->property = property;
return Value::fromObject(r); return Value::fromObject(r).asReturnedValue();
} }
Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type) ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type)
{ {
ExecutionEngine *v4 = QV8Engine::getV4(v8); ExecutionEngine *v4 = QV8Engine::getV4(v8);
initProto(v4); initProto(v4);
@ -158,7 +158,7 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValu
QmlValueTypeCopy *r = new (v4->memoryManager) QmlValueTypeCopy(v8); QmlValueTypeCopy *r = new (v4->memoryManager) QmlValueTypeCopy(v8);
r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype); r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->type = type; r->value = value; r->type = type; r->value = value;
return Value::fromObject(r); return Value::fromObject(r).asReturnedValue();
} }
QVariant QmlValueTypeWrapper::toVariant() const QVariant QmlValueTypeWrapper::toVariant() const
@ -301,7 +301,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
if (result->isFunction()) { if (result->isFunction()) {
// calling a Q_INVOKABLE function of a value type // calling a Q_INVOKABLE function of a value type
QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4); QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4);
return QV4::QObjectWrapper::getQmlProperty(v4->current, qmlContext, r->type, name, QV4::QObjectWrapper::IgnoreRevision).asReturnedValue(); return QV4::QObjectWrapper::getQmlProperty(v4->current, qmlContext, r->type, name, QV4::QObjectWrapper::IgnoreRevision);
} }
#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ #define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \
@ -321,7 +321,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper
QVariant v(result->propType, (void *)0); QVariant v(result->propType, (void *)0);
void *args[] = { v.data(), 0 }; void *args[] = { v.data(), 0 };
r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args);
return r->v8->fromVariant(v).asReturnedValue(); return r->v8->fromVariant(v);
#undef VALUE_TYPE_ACCESSOR #undef VALUE_TYPE_ACCESSOR
} }

View File

@ -76,8 +76,8 @@ protected:
public: public:
static Value create(QV8Engine *v8, QObject *, int, QQmlValueType *); static ReturnedValue create(QV8Engine *v8, QObject *, int, QQmlValueType *);
static Value create(QV8Engine *v8, const QVariant &, QQmlValueType *); static ReturnedValue create(QV8Engine *v8, const QVariant &, QQmlValueType *);
QVariant toVariant() const; QVariant toVariant() const;
bool isEqual(const QVariant& value); bool isEqual(const QVariant& value);

View File

@ -372,7 +372,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
// Store a created object in a property. These all pop from the objects stack. // Store a created object in a property. These all pop from the objects stack.
QML_STORE_VALUE(StoreObject, QObject *, objects.pop()); QML_STORE_VALUE(StoreObject, QObject *, objects.pop());
QML_STORE_VALUE(StoreVariantObject, QVariant, QVariant::fromValue(objects.pop())); QML_STORE_VALUE(StoreVariantObject, QVariant, QVariant::fromValue(objects.pop()));
QML_STORE_VAR(StoreVarObject, QV4::QObjectWrapper::wrap(ep->v4engine(), objects.pop())); QML_STORE_VAR(StoreVarObject, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(ep->v4engine(), objects.pop())));
// Store a literal value in a corresponding property // Store a literal value in a corresponding property
QML_STORE_VALUE(StoreFloat, float, instr.value); QML_STORE_VALUE(StoreFloat, float, instr.value);
@ -420,7 +420,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
// Store a literal value in a var property. // Store a literal value in a var property.
// We deliberately do not use string converters here // We deliberately do not use string converters here
QML_STORE_VAR(StoreVar, ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value))); QML_STORE_VAR(StoreVar, QV4::Value::fromReturnedValue(ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value))));
QML_STORE_VAR(StoreVarInteger, QV4::Value::fromInt32(instr.value)); QML_STORE_VAR(StoreVarInteger, QV4::Value::fromInt32(instr.value));
QML_STORE_VAR(StoreVarDouble, QV4::Value::fromDouble(instr.value)); QML_STORE_VAR(StoreVarDouble, QV4::Value::fromDouble(instr.value));
QML_STORE_VAR(StoreVarBool, QV4::Value::fromBoolean(instr.value)); QML_STORE_VAR(StoreVarBool, QV4::Value::fromBoolean(instr.value));
@ -1113,6 +1113,8 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s
Q_ASSERT(parentCtxt && parentCtxt->engine); Q_ASSERT(parentCtxt && parentCtxt->engine);
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine);
QV8Engine *v8engine = ep->v8engine(); QV8Engine *v8engine = ep->v8engine();
QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine);
QV4::Scope scope(v4);
if (script->hasError()) { if (script->hasError()) {
ep->warning(script->error()); ep->warning(script->error());
@ -1178,7 +1180,7 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s
return QV4::PersistentValue(); return QV4::PersistentValue();
} }
QV4::Value qmlglobal = QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0); QV4::ScopedValue qmlglobal(scope, QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0));
QV4::QmlContextWrapper::takeContextOwnership(qmlglobal); QV4::QmlContextWrapper::takeContextOwnership(qmlglobal);
QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current; QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current;

View File

@ -911,8 +911,10 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(ctxt->engine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(ctxt->engine);
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
QV4::Scope scope(ep->v4engine());
QV4::FunctionObject *function = method(id).asFunctionObject();
QV4::Scoped<QV4::FunctionObject> function(scope, method(id));
if (!function) { if (!function) {
// The function was not compiled. There are some exceptional cases which the // The function was not compiled. There are some exceptional cases which the
// expression rewriter does not rewrite properly (e.g., \r-terminated lines // expression rewriter does not rewrite properly (e.g., \r-terminated lines
@ -927,12 +929,11 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
QQmlVMEMetaData::MethodData *data = metaData->methodData() + id; QQmlVMEMetaData::MethodData *data = metaData->methodData() + id;
QV4::Scope scope(function->engine());
QV4::ScopedCallData callData(scope, data->parameterCount); QV4::ScopedCallData callData(scope, data->parameterCount);
callData->thisObject = ep->v8engine()->global(); callData->thisObject = ep->v8engine()->global();
for (int ii = 0; ii < data->parameterCount; ++ii) for (int ii = 0; ii < data->parameterCount; ++ii)
callData->args[ii] = ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]); callData->args[ii] = QV4::Value::fromReturnedValue(ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]));
QV4::ScopedValue result(scope); QV4::ScopedValue result(scope);
QV4::ExecutionContext *ctx = function->engine()->current; QV4::ExecutionContext *ctx = function->engine()->current;
@ -961,11 +962,11 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
return object->qt_metacall(c, _id, a); return object->qt_metacall(c, _id, a);
} }
QV4::Value QQmlVMEMetaObject::method(int index) QV4::ReturnedValue QQmlVMEMetaObject::method(int index)
{ {
if (!ctxt || !ctxt->isValid()) { if (!ctxt || !ctxt->isValid()) {
qWarning("QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context"); qWarning("QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context");
return QV4::Value::emptyValue(); return QV4::Value::emptyValue().asReturnedValue();
} }
if (!v8methods) if (!v8methods)
@ -984,16 +985,16 @@ QV4::Value QQmlVMEMetaObject::method(int index)
ctxt->urlString, data->lineNumber); ctxt->urlString, data->lineNumber);
} }
return v8methods[index]; return v8methods[index].value().asReturnedValue();
} }
QV4::Value QQmlVMEMetaObject::readVarProperty(int id) QV4::ReturnedValue QQmlVMEMetaObject::readVarProperty(int id)
{ {
Q_ASSERT(id >= firstVarPropertyIndex); Q_ASSERT(id >= firstVarPropertyIndex);
if (ensureVarPropertiesAllocated()) if (ensureVarPropertiesAllocated())
return QV4::Value::fromReturnedValue(varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex)); return varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex);
return QV4::Value::emptyValue(); return QV4::Value::emptyValue().asReturnedValue();
} }
QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id)
@ -1070,8 +1071,8 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
// And, if the new value is a scarce resource, we need to ensure that it does not get // And, if the new value is a scarce resource, we need to ensure that it does not get
// automatically released by the engine until no other references to it exist. // automatically released by the engine until no other references to it exist.
QV4::Value newv = QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value); QV4::ScopedValue newv(scope, QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value));
if (QV4::VariantObject *v = newv.as<QV4::VariantObject>()) if (QV4::VariantObject *v = newv->as<QV4::VariantObject>())
v->addVmePropertyReference(); v->addVmePropertyReference();
// Write the value and emit change signal as appropriate. // Write the value and emit change signal as appropriate.
@ -1150,7 +1151,7 @@ quint16 QQmlVMEMetaObject::vmeMethodLineNumber(int index)
return data->lineNumber; return data->lineNumber;
} }
QV4::Value QQmlVMEMetaObject::vmeMethod(int index) QV4::ReturnedValue QQmlVMEMetaObject::vmeMethod(int index)
{ {
if (index < methodOffset()) { if (index < methodOffset()) {
Q_ASSERT(parentVMEMetaObject()); Q_ASSERT(parentVMEMetaObject());
@ -1178,7 +1179,7 @@ void QQmlVMEMetaObject::setVmeMethod(int index, QV4::PersistentValue function)
v8methods[methodIndex] = function; v8methods[methodIndex] = function;
} }
QV4::Value QQmlVMEMetaObject::vmeProperty(int index) QV4::ReturnedValue QQmlVMEMetaObject::vmeProperty(int index)
{ {
if (index < propOffset()) { if (index < propOffset()) {
Q_ASSERT(parentVMEMetaObject()); Q_ASSERT(parentVMEMetaObject());

View File

@ -164,10 +164,10 @@ public:
bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const;
void registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor); void registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor);
QV4::Value vmeMethod(int index); QV4::ReturnedValue vmeMethod(int index);
quint16 vmeMethodLineNumber(int index); quint16 vmeMethodLineNumber(int index);
void setVmeMethod(int index, QV4::PersistentValue function); void setVmeMethod(int index, QV4::PersistentValue function);
QV4::Value vmeProperty(int index); QV4::ReturnedValue vmeProperty(int index);
void setVMEProperty(int index, const QV4::Value &v); void setVMEProperty(int index, const QV4::Value &v);
void connectAliasSignal(int index, bool indexInSignalRange); void connectAliasSignal(int index, bool indexInSignalRange);
@ -217,9 +217,9 @@ public:
QQmlPropertyValueInterceptor *interceptors; QQmlPropertyValueInterceptor *interceptors;
QV4::PersistentValue *v8methods; QV4::PersistentValue *v8methods;
QV4::Value method(int); QV4::ReturnedValue method(int);
QV4::Value readVarProperty(int); QV4::ReturnedValue readVarProperty(int);
void writeVarProperty(int, const QV4::Value &); void writeVarProperty(int, const QV4::Value &);
QVariant readPropertyAsVariant(int); QVariant readPropertyAsVariant(int);
void writeProperty(int, const QVariant &); void writeProperty(int, const QVariant &);

View File

@ -100,9 +100,11 @@ static inline QQmlXMLHttpRequestData *xhrdata(QV8Engine *engine)
static Value constructMeObject(const Value &thisObj, QV8Engine *e) static Value constructMeObject(const Value &thisObj, QV8Engine *e)
{ {
ExecutionEngine *v4 = QV8Engine::getV4(e); ExecutionEngine *v4 = QV8Engine::getV4(e);
Scope scope(v4);
Object *meObj = v4->newObject(); Object *meObj = v4->newObject();
meObj->put(v4->newString(QStringLiteral("ThisObject")), thisObj); meObj->put(v4->newString(QStringLiteral("ThisObject")), thisObj);
meObj->put(v4->newString(QStringLiteral("ActivationObject")), QmlContextWrapper::qmlScope(e, e->callingContext(), 0)); ScopedValue v(scope, QmlContextWrapper::qmlScope(e, e->callingContext(), 0));
meObj->put(v4->newString(QStringLiteral("ActivationObject")), v);
return Value::fromObject(meObj); return Value::fromObject(meObj);
} }

View File

@ -202,7 +202,7 @@ ReturnedValue QtObject::method_rgba(QV4::SimpleCallContext *ctx)
if (a < 0.0) a=0.0; if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0; if (a > 1.0) a=1.0;
return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)).asReturnedValue(); return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
} }
/*! /*!
@ -231,7 +231,7 @@ ReturnedValue QtObject::method_hsla(QV4::SimpleCallContext *ctx)
if (a < 0.0) a=0.0; if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0; if (a > 1.0) a=1.0;
return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)).asReturnedValue(); return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
} }
/*! /*!
@ -292,7 +292,7 @@ ReturnedValue QtObject::method_rect(QV4::SimpleCallContext *ctx)
double w = ctx->arguments[2].toNumber(); double w = ctx->arguments[2].toNumber();
double h = ctx->arguments[3].toNumber(); double h = ctx->arguments[3].toNumber();
return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))).asReturnedValue(); return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
} }
/*! /*!
@ -307,7 +307,7 @@ ReturnedValue QtObject::method_point(QV4::SimpleCallContext *ctx)
double x = ctx->arguments[0].toNumber(); double x = ctx->arguments[0].toNumber();
double y = ctx->arguments[1].toNumber(); double y = ctx->arguments[1].toNumber();
return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QPointF(x, y))).asReturnedValue(); return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
} }
/*! /*!
@ -322,7 +322,7 @@ ReturnedValue QtObject::method_size(QV4::SimpleCallContext *ctx)
double w = ctx->arguments[0].toNumber(); double w = ctx->arguments[0].toNumber();
double h = ctx->arguments[1].toNumber(); double h = ctx->arguments[1].toNumber();
return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QSizeF(w, h))).asReturnedValue(); return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
} }
/*! /*!
@ -343,7 +343,7 @@ ReturnedValue QtObject::method_font(QV4::SimpleCallContext *ctx)
QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok); QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok);
if (!ok) if (!ok)
V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified"); V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
return v8engine->fromVariant(v).asReturnedValue(); return v8engine->fromVariant(v);
} }
@ -363,7 +363,7 @@ ReturnedValue QtObject::method_vector2d(QV4::SimpleCallContext *ctx)
const void *params[] = { xy }; const void *params[] = { xy };
QV8Engine *v8engine = ctx->engine->v8Engine; QV8Engine *v8engine = ctx->engine->v8Engine;
return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params)).asReturnedValue(); return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
} }
/*! /*!
@ -382,7 +382,7 @@ ReturnedValue QtObject::method_vector3d(QV4::SimpleCallContext *ctx)
const void *params[] = { xyz }; const void *params[] = { xyz };
QV8Engine *v8engine = ctx->engine->v8Engine; QV8Engine *v8engine = ctx->engine->v8Engine;
return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)).asReturnedValue(); return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
} }
/*! /*!
@ -402,7 +402,7 @@ ReturnedValue QtObject::method_vector4d(QV4::SimpleCallContext *ctx)
const void *params[] = { xyzw }; const void *params[] = { xyzw };
QV8Engine *v8engine = ctx->engine->v8Engine; QV8Engine *v8engine = ctx->engine->v8Engine;
return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)).asReturnedValue(); return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
} }
/*! /*!
@ -422,7 +422,7 @@ ReturnedValue QtObject::method_quaternion(QV4::SimpleCallContext *ctx)
const void *params[] = { sxyz }; const void *params[] = { sxyz };
QV8Engine *v8engine = ctx->engine->v8Engine; QV8Engine *v8engine = ctx->engine->v8Engine;
return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params)).asReturnedValue(); return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
} }
/*! /*!
@ -441,7 +441,7 @@ ReturnedValue QtObject::method_matrix4x4(QV4::SimpleCallContext *ctx)
QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok); QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok);
if (!ok) if (!ok)
V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array"); V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
return v8engine->fromVariant(v).asReturnedValue(); return v8engine->fromVariant(v);
} }
if (ctx->argumentCount != 16) if (ctx->argumentCount != 16)
@ -466,7 +466,7 @@ ReturnedValue QtObject::method_matrix4x4(QV4::SimpleCallContext *ctx)
vals[15] = ctx->arguments[15].toNumber(); vals[15] = ctx->arguments[15].toNumber();
const void *params[] = { vals }; const void *params[] = { vals };
return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params)).asReturnedValue(); return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
} }
/*! /*!
@ -504,7 +504,7 @@ ReturnedValue QtObject::method_lighter(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 2) if (ctx->argumentCount == 2)
factor = ctx->arguments[1].toNumber(); factor = ctx->arguments[1].toNumber();
return v8engine->fromVariant(QQml_colorProvider()->lighter(v, factor)).asReturnedValue(); return v8engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
} }
/*! /*!
@ -543,7 +543,7 @@ ReturnedValue QtObject::method_darker(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 2) if (ctx->argumentCount == 2)
factor = ctx->arguments[1].toNumber(); factor = ctx->arguments[1].toNumber();
return v8engine->fromVariant(QQml_colorProvider()->darker(v, factor)).asReturnedValue(); return v8engine->fromVariant(QQml_colorProvider()->darker(v, factor));
} }
/*! /*!
@ -601,7 +601,7 @@ ReturnedValue QtObject::method_tint(QV4::SimpleCallContext *ctx)
return QV4::Encode::null(); return QV4::Encode::null();
} }
return v8engine->fromVariant(QQml_colorProvider()->tint(v1, v2)).asReturnedValue(); return v8engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
} }
/*! /*!
@ -645,7 +645,7 @@ ReturnedValue QtObject::method_formatDate(QV4::SimpleCallContext *ctx)
formattedDate = date.toString(enumFormat); formattedDate = date.toString(enumFormat);
} }
return v8engine->fromVariant(QVariant::fromValue(formattedDate)).asReturnedValue(); return v8engine->fromVariant(QVariant::fromValue(formattedDate));
} }
/*! /*!
@ -694,7 +694,7 @@ ReturnedValue QtObject::method_formatTime(QV4::SimpleCallContext *ctx)
formattedTime = time.toString(enumFormat); formattedTime = time.toString(enumFormat);
} }
return v8engine->fromVariant(QVariant::fromValue(formattedTime)).asReturnedValue(); return v8engine->fromVariant(QVariant::fromValue(formattedTime));
} }
/*! /*!
@ -812,7 +812,7 @@ ReturnedValue QtObject::method_formatDateTime(QV4::SimpleCallContext *ctx)
formattedDt = dt.toString(enumFormat); formattedDt = dt.toString(enumFormat);
} }
return v8engine->fromVariant(QVariant::fromValue(formattedDt)).asReturnedValue(); return v8engine->fromVariant(QVariant::fromValue(formattedDt));
} }
/*! /*!
@ -827,7 +827,7 @@ ReturnedValue QtObject::method_openUrlExternally(QV4::SimpleCallContext *ctx)
QV8Engine *v8engine = ctx->engine->v8Engine; QV8Engine *v8engine = ctx->engine->v8Engine;
QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow()); QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow());
return v8engine->fromVariant(QQml_guiProvider()->openUrlExternally(url)).asReturnedValue(); return v8engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
} }
/*! /*!
@ -863,7 +863,7 @@ ReturnedValue QtObject::method_fontFamilies(SimpleCallContext *ctx)
V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments"); V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
QV8Engine *v8engine = ctx->engine->v8Engine; QV8Engine *v8engine = ctx->engine->v8Engine;
return v8engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())).asReturnedValue(); return v8engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
} }
/*! /*!
@ -1039,7 +1039,7 @@ ReturnedValue QtObject::method_createQmlObject(SimpleCallContext *ctx)
Q_ASSERT(obj); Q_ASSERT(obj);
return QV4::QObjectWrapper::wrap(ctx->engine, obj).asReturnedValue(); return QV4::QObjectWrapper::wrap(ctx->engine, obj);
} }
/*! /*!
@ -1133,7 +1133,7 @@ ReturnedValue QtObject::method_createComponent(SimpleCallContext *ctx)
QQmlData::get(c, true)->explicitIndestructibleSet = false; QQmlData::get(c, true)->explicitIndestructibleSet = false;
QQmlData::get(c)->indestructible = false; QQmlData::get(c)->indestructible = false;
return QV4::QObjectWrapper::wrap(ctx->engine, c).asReturnedValue(); return QV4::QObjectWrapper::wrap(ctx->engine, c);
} }
/*! /*!
@ -1168,7 +1168,7 @@ ReturnedValue QtObject::method_locale(SimpleCallContext *ctx)
if (ctx->argumentCount == 1) if (ctx->argumentCount == 1)
code = ctx->arguments[0].toQStringNoThrow(); code = ctx->arguments[0].toQStringNoThrow();
return QQmlLocale::locale(v8engine, code).asReturnedValue(); return QQmlLocale::locale(v8engine, code);
} }
namespace { namespace {
@ -1276,7 +1276,7 @@ ReturnedValue QtObject::method_get_platform(SimpleCallContext *ctx)
// Only allocate a platform object once // Only allocate a platform object once
qt->m_platform = new QQmlPlatform(ctx->engine->v8Engine->publicEngine()); qt->m_platform = new QQmlPlatform(ctx->engine->v8Engine->publicEngine());
return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_platform).asReturnedValue(); return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_platform);
} }
ReturnedValue QtObject::method_get_application(SimpleCallContext *ctx) ReturnedValue QtObject::method_get_application(SimpleCallContext *ctx)
@ -1293,7 +1293,7 @@ ReturnedValue QtObject::method_get_application(SimpleCallContext *ctx)
// Only allocate an application object once // Only allocate an application object once
qt->m_application = QQml_guiProvider()->application(ctx->engine->v8Engine->publicEngine()); qt->m_application = QQml_guiProvider()->application(ctx->engine->v8Engine->publicEngine());
return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_application).asReturnedValue(); return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_application);
} }
#ifndef QT_NO_IM #ifndef QT_NO_IM
@ -1301,7 +1301,7 @@ ReturnedValue QtObject::method_get_inputMethod(SimpleCallContext *ctx)
{ {
QObject *o = QQml_guiProvider()->inputMethod(); QObject *o = QQml_guiProvider()->inputMethod();
QQmlEngine::setObjectOwnership(o, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(o, QQmlEngine::CppOwnership);
return QV4::QObjectWrapper::wrap(ctx->engine, o).asReturnedValue(); return QV4::QObjectWrapper::wrap(ctx->engine, o);
} }
#endif #endif

View File

@ -181,7 +181,7 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint)
return toBasicVariant(value); return toBasicVariant(value);
} }
static QV4::Value arrayFromStringList(QV8Engine *engine, const QStringList &list) static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringList &list)
{ {
QV4::ExecutionEngine *e = QV8Engine::getV4(engine); QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
QV4::ArrayObject *a = e->newArrayObject(); QV4::ArrayObject *a = e->newArrayObject();
@ -191,10 +191,10 @@ static QV4::Value arrayFromStringList(QV8Engine *engine, const QStringList &list
for (int ii = 0; ii < len; ++ii) for (int ii = 0; ii < len; ++ii)
a->arrayData[ii].value = QV4::Value::fromString(e->newString(list.at(ii))); a->arrayData[ii].value = QV4::Value::fromString(e->newString(list.at(ii)));
a->setArrayLengthUnchecked(len); a->setArrayLengthUnchecked(len);
return QV4::Value::fromObject(a); return QV4::Value::fromObject(a).asReturnedValue();
} }
static QV4::Value arrayFromVariantList(QV8Engine *engine, const QVariantList &list) static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariantList &list)
{ {
QV4::ExecutionEngine *e = QV8Engine::getV4(engine); QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
QV4::ArrayObject *a = e->newArrayObject(); QV4::ArrayObject *a = e->newArrayObject();
@ -202,23 +202,23 @@ static QV4::Value arrayFromVariantList(QV8Engine *engine, const QVariantList &li
a->arrayReserve(len); a->arrayReserve(len);
a->arrayDataLen = len; a->arrayDataLen = len;
for (int ii = 0; ii < len; ++ii) for (int ii = 0; ii < len; ++ii)
a->arrayData[ii].value = engine->fromVariant(list.at(ii)); a->arrayData[ii].value = QV4::Value::fromReturnedValue(engine->fromVariant(list.at(ii)));
a->setArrayLengthUnchecked(len); a->setArrayLengthUnchecked(len);
return QV4::Value::fromObject(a); return QV4::Value::fromObject(a).asReturnedValue();
} }
static QV4::Value objectFromVariantMap(QV8Engine *engine, const QVariantMap &map) static QV4::ReturnedValue objectFromVariantMap(QV8Engine *engine, const QVariantMap &map)
{ {
QV4::ExecutionEngine *e = QV8Engine::getV4(engine); QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
QV4::Object *o = e->newObject(); QV4::Object *o = e->newObject();
for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter) for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter)
o->put(e->newString(iter.key()), engine->fromVariant(iter.value())); o->put(e->newString(iter.key()), QV4::Value::fromReturnedValue(engine->fromVariant(iter.value())));
return QV4::Value::fromObject(o); return QV4::Value::fromObject(o).asReturnedValue();
} }
Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
QV4::Value QV8Engine::fromVariant(const QVariant &variant) QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
{ {
int type = variant.userType(); int type = variant.userType();
const void *ptr = variant.constData(); const void *ptr = variant.constData();
@ -227,49 +227,50 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
switch (QMetaType::Type(type)) { switch (QMetaType::Type(type)) {
case QMetaType::UnknownType: case QMetaType::UnknownType:
case QMetaType::Void: case QMetaType::Void:
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
case QMetaType::Bool: case QMetaType::Bool:
return QV4::Value::fromBoolean(*reinterpret_cast<const bool*>(ptr)); return QV4::Encode(*reinterpret_cast<const bool*>(ptr));
case QMetaType::Int: case QMetaType::Int:
return QV4::Value::fromInt32(*reinterpret_cast<const int*>(ptr)); return QV4::Encode(*reinterpret_cast<const int*>(ptr));
case QMetaType::UInt: case QMetaType::UInt:
return QV4::Value::fromUInt32(*reinterpret_cast<const uint*>(ptr)); return QV4::Encode(*reinterpret_cast<const uint*>(ptr));
case QMetaType::LongLong: case QMetaType::LongLong:
return QV4::Value::fromDouble(*reinterpret_cast<const qlonglong*>(ptr)); return QV4::Encode((double)*reinterpret_cast<const qlonglong*>(ptr));
case QMetaType::ULongLong: case QMetaType::ULongLong:
return QV4::Value::fromDouble(*reinterpret_cast<const qulonglong*>(ptr)); return QV4::Encode((double)*reinterpret_cast<const qulonglong*>(ptr));
case QMetaType::Double: case QMetaType::Double:
return QV4::Value::fromDouble(*reinterpret_cast<const double*>(ptr)); return QV4::Encode(*reinterpret_cast<const double*>(ptr));
case QMetaType::QString: case QMetaType::QString:
return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(ptr)); return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(ptr)).asReturnedValue();
case QMetaType::Float: case QMetaType::Float:
return QV4::Value::fromDouble(*reinterpret_cast<const float*>(ptr)); return QV4::Encode(*reinterpret_cast<const float*>(ptr));
case QMetaType::Short: case QMetaType::Short:
return QV4::Value::fromInt32(*reinterpret_cast<const short*>(ptr)); return QV4::Encode((int)*reinterpret_cast<const short*>(ptr));
case QMetaType::UShort: case QMetaType::UShort:
return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned short*>(ptr)); return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(ptr));
case QMetaType::Char: case QMetaType::Char:
return QV4::Value::fromInt32(*reinterpret_cast<const char*>(ptr)); return QV4::Encode((int)*reinterpret_cast<const char*>(ptr));
case QMetaType::UChar: case QMetaType::UChar:
return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned char*>(ptr)); return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(ptr));
case QMetaType::QChar: case QMetaType::QChar:
return QV4::Value::fromInt32((*reinterpret_cast<const QChar*>(ptr)).unicode()); return QV4::Encode((int)(*reinterpret_cast<const QChar*>(ptr)).unicode());
case QMetaType::QDateTime: case QMetaType::QDateTime:
return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(ptr))); return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(ptr))).asReturnedValue();
case QMetaType::QDate: case QMetaType::QDate:
return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr)))); return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr)))).asReturnedValue();
case QMetaType::QTime: case QMetaType::QTime:
return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr)))); return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr)))).asReturnedValue();
case QMetaType::QRegExp: case QMetaType::QRegExp:
return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr))); return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr))).asReturnedValue();
case QMetaType::QObjectStar: case QMetaType::QObjectStar:
return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr)); return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr));
case QMetaType::QStringList: case QMetaType::QStringList:
{ {
bool succeeded = false; bool succeeded = false;
QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded); QV4::Scope scope(m_v4Engine);
QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded));
if (succeeded) if (succeeded)
return retn; return retn.asReturnedValue();
return arrayFromStringList(this, *reinterpret_cast<const QStringList *>(ptr)); return arrayFromStringList(this, *reinterpret_cast<const QStringList *>(ptr));
} }
case QMetaType::QVariantList: case QMetaType::QVariantList:
@ -290,13 +291,14 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type)) if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
return QV4::QmlValueTypeWrapper::create(this, variant, vt); return QV4::QmlValueTypeWrapper::create(this, variant, vt);
} else { } else {
QV4::Scope scope(m_v4Engine);
if (type == qMetaTypeId<QQmlListReference>()) { if (type == qMetaTypeId<QQmlListReference>()) {
typedef QQmlListReferencePrivate QDLRP; typedef QQmlListReferencePrivate QDLRP;
QDLRP *p = QDLRP::get((QQmlListReference*)ptr); QDLRP *p = QDLRP::get((QQmlListReference*)ptr);
if (p->object) { if (p->object) {
return QV4::QmlListWrapper::create(this, p->property, p->propertyType); return QV4::QmlListWrapper::create(this, p->property, p->propertyType);
} else { } else {
return QV4::Value::nullValue(); return QV4::Encode::null();
} }
} else if (type == qMetaTypeId<QJSValue>()) { } else if (type == qMetaTypeId<QJSValue>()) {
const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr); const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr);
@ -310,9 +312,9 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
a->arrayReserve(list.count()); a->arrayReserve(list.count());
a->arrayDataLen = list.count(); a->arrayDataLen = list.count();
for (int ii = 0; ii < list.count(); ++ii) for (int ii = 0; ii < list.count(); ++ii)
a->arrayData[ii].value = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii)); a->arrayData[ii].value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii)));
a->setArrayLengthUnchecked(list.count()); a->setArrayLengthUnchecked(list.count());
return QV4::Value::fromObject(a); return QV4::Value::fromObject(a).asReturnedValue();
} else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) { } else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr)); return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr));
} }
@ -323,9 +325,9 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
return QV4::QObjectWrapper::wrap(m_v4Engine, obj); return QV4::QObjectWrapper::wrap(m_v4Engine, obj);
bool succeeded = false; bool succeeded = false;
QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded); QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded));
if (succeeded) if (succeeded)
return retn; return retn.asReturnedValue();
if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type)) if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
return QV4::QmlValueTypeWrapper::create(this, variant, vt); return QV4::QmlValueTypeWrapper::create(this, variant, vt);
@ -335,7 +337,7 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
// + QObjectList // + QObjectList
// + QList<int> // + QList<int>
return QV4::Value::fromObject(m_v4Engine->newVariantObject(variant)); return QV4::Value::fromObject(m_v4Engine->newVariantObject(variant)).asReturnedValue();
} }
QNetworkAccessManager *QV8Engine::networkAccessManager() QNetworkAccessManager *QV8Engine::networkAccessManager()
@ -513,15 +515,15 @@ QV4::Value QV8Engine::global()
// The result is a new Array object with length equal to the length // The result is a new Array object with length equal to the length
// of the QVariantList, and the elements being the QVariantList's // of the QVariantList, and the elements being the QVariantList's
// elements converted to JS, recursively. // elements converted to JS, recursively.
QV4::Value QV8Engine::variantListToJS(const QVariantList &lst) QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst)
{ {
QV4::ArrayObject *a = m_v4Engine->newArrayObject(); QV4::ArrayObject *a = m_v4Engine->newArrayObject();
a->arrayReserve(lst.size()); a->arrayReserve(lst.size());
a->arrayDataLen = lst.size(); a->arrayDataLen = lst.size();
for (int i = 0; i < lst.size(); i++) for (int i = 0; i < lst.size(); i++)
a->arrayData[i].value = variantToJS(lst.at(i)); a->arrayData[i].value = QV4::Value::fromReturnedValue(variantToJS(lst.at(i)));
a->setArrayLengthUnchecked(lst.size()); a->setArrayLengthUnchecked(lst.size());
return QV4::Value::fromObject(a); return QV4::Value::fromObject(a).asReturnedValue();
} }
// Converts a JS Array object to a QVariantList. // Converts a JS Array object to a QVariantList.
@ -559,15 +561,15 @@ QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a,
// The result is a new Object object with property names being // The result is a new Object object with property names being
// the keys of the QVariantMap, and values being the values of // the keys of the QVariantMap, and values being the values of
// the QVariantMap converted to JS, recursively. // the QVariantMap converted to JS, recursively.
QV4::Value QV8Engine::variantMapToJS(const QVariantMap &vmap) QV4::ReturnedValue QV8Engine::variantMapToJS(const QVariantMap &vmap)
{ {
QV4::Object *o = m_v4Engine->newObject(); QV4::Object *o = m_v4Engine->newObject();
QVariantMap::const_iterator it; QVariantMap::const_iterator it;
for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) { for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
QV4::Property *p = o->insertMember(m_v4Engine->newIdentifier(it.key()), QV4::Attr_Data); QV4::Property *p = o->insertMember(m_v4Engine->newIdentifier(it.key()), QV4::Attr_Data);
p->value = variantToJS(it.value()); p->value = QV4::Value::fromReturnedValue(variantToJS(it.value()));
} }
return QV4::Value::fromObject(o); return QV4::Value::fromObject(o).asReturnedValue();
} }
// Converts a JS Object to a QVariantMap. // Converts a JS Object to a QVariantMap.
@ -588,17 +590,19 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o,
// empty object (and no error is thrown). // empty object (and no error is thrown).
return result; return result;
} }
QV4::Scope scope(o->engine());
visitedObjects.insert(o); visitedObjects.insert(o);
QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly); QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly);
QV4::ScopedValue name(scope);
while (1) { while (1) {
QV4::Value v; QV4::Value v;
QV4::Value name = it.nextPropertyNameAsString(&v); name = it.nextPropertyNameAsString(&v);
if (name.isNull()) if (name->isNull())
break; break;
QString key = name.toQStringNoThrow(); QString key = name->toQStringNoThrow();
result.insert(key, variantFromJS(v, visitedObjects)); result.insert(key, variantFromJS(v, visitedObjects));
} }
@ -608,96 +612,85 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o,
// Converts the meta-type defined by the given type and data to JS. // Converts the meta-type defined by the given type and data to JS.
// Returns the value if conversion succeeded, an empty handle otherwise. // Returns the value if conversion succeeded, an empty handle otherwise.
QV4::Value QV8Engine::metaTypeToJS(int type, const void *data) QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data)
{ {
Q_ASSERT(data != 0); Q_ASSERT(data != 0);
QV4::Value result;
// check if it's one of the types we know // check if it's one of the types we know
switch (QMetaType::Type(type)) { switch (QMetaType::Type(type)) {
case QMetaType::UnknownType: case QMetaType::UnknownType:
case QMetaType::Void: case QMetaType::Void:
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
case QMetaType::Bool: case QMetaType::Bool:
return QV4::Value::fromBoolean(*reinterpret_cast<const bool*>(data)); return QV4::Encode(*reinterpret_cast<const bool*>(data));
case QMetaType::Int: case QMetaType::Int:
return QV4::Value::fromInt32(*reinterpret_cast<const int*>(data)); return QV4::Encode(*reinterpret_cast<const int*>(data));
case QMetaType::UInt: case QMetaType::UInt:
return QV4::Value::fromUInt32(*reinterpret_cast<const uint*>(data)); return QV4::Encode(*reinterpret_cast<const uint*>(data));
case QMetaType::LongLong: case QMetaType::LongLong:
return QV4::Value::fromDouble(double(*reinterpret_cast<const qlonglong*>(data))); return QV4::Encode(double(*reinterpret_cast<const qlonglong*>(data)));
case QMetaType::ULongLong: case QMetaType::ULongLong:
#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804 #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.") #pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast<const qulonglong*>(data))); return QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast<const qulonglong*>(data))); return QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
#else #else
return QV4::Value::fromDouble(double(*reinterpret_cast<const qulonglong*>(data))); return QV4::Encode(double(*reinterpret_cast<const qulonglong*>(data)));
#endif #endif
case QMetaType::Double: case QMetaType::Double:
return QV4::Value::fromDouble(*reinterpret_cast<const double*>(data)); return QV4::Encode(*reinterpret_cast<const double*>(data));
case QMetaType::QString: case QMetaType::QString:
return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(data)); return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(data)).asReturnedValue();
case QMetaType::Float: case QMetaType::Float:
return QV4::Value::fromDouble(*reinterpret_cast<const float*>(data)); return QV4::Encode(*reinterpret_cast<const float*>(data));
case QMetaType::Short: case QMetaType::Short:
return QV4::Value::fromInt32(*reinterpret_cast<const short*>(data)); return QV4::Encode((int)*reinterpret_cast<const short*>(data));
case QMetaType::UShort: case QMetaType::UShort:
return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned short*>(data)); return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(data));
case QMetaType::Char: case QMetaType::Char:
return QV4::Value::fromInt32(*reinterpret_cast<const char*>(data)); return QV4::Encode((int)*reinterpret_cast<const char*>(data));
case QMetaType::UChar: case QMetaType::UChar:
return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned char*>(data)); return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(data));
case QMetaType::QChar: case QMetaType::QChar:
return QV4::Value::fromUInt32((*reinterpret_cast<const QChar*>(data)).unicode()); return QV4::Encode((int)(*reinterpret_cast<const QChar*>(data)).unicode());
case QMetaType::QStringList: case QMetaType::QStringList:
result = QV4::Value::fromObject(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(data))); return QV4::Value::fromObject(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(data))).asReturnedValue();
break;
case QMetaType::QVariantList: case QMetaType::QVariantList:
result = variantListToJS(*reinterpret_cast<const QVariantList *>(data)); return variantListToJS(*reinterpret_cast<const QVariantList *>(data));
break;
case QMetaType::QVariantMap: case QMetaType::QVariantMap:
result = variantMapToJS(*reinterpret_cast<const QVariantMap *>(data)); return variantMapToJS(*reinterpret_cast<const QVariantMap *>(data));
break;
case QMetaType::QDateTime: case QMetaType::QDateTime:
result = QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(data))); return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(data))).asReturnedValue();
break;
case QMetaType::QDate: case QMetaType::QDate:
result = QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(data)))); return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(data)))).asReturnedValue();
break;
case QMetaType::QRegExp: case QMetaType::QRegExp:
result = QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(data))); return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(data))).asReturnedValue();
break;
case QMetaType::QObjectStar: case QMetaType::QObjectStar:
result = QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(data)); return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(data));
break;
case QMetaType::QVariant: case QMetaType::QVariant:
result = variantToJS(*reinterpret_cast<const QVariant*>(data)); return variantToJS(*reinterpret_cast<const QVariant*>(data));
break;
case QMetaType::QJsonValue: case QMetaType::QJsonValue:
result = QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast<const QJsonValue *>(data)); return QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast<const QJsonValue *>(data));
break;
case QMetaType::QJsonObject: case QMetaType::QJsonObject:
result = QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast<const QJsonObject *>(data)); return QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast<const QJsonObject *>(data));
break;
case QMetaType::QJsonArray: case QMetaType::QJsonArray:
result = QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast<const QJsonArray *>(data)); return QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast<const QJsonArray *>(data));
break;
default: default:
if (type == qMetaTypeId<QJSValue>()) { if (type == qMetaTypeId<QJSValue>()) {
return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->getValue(m_v4Engine); return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->getValue(m_v4Engine);
} else { } else {
QByteArray typeName = QMetaType::typeName(type); QByteArray typeName = QMetaType::typeName(type);
if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) { if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) {
return QV4::Value::nullValue(); return QV4::Encode::null();
} else { } else {
// Fall back to wrapping in a QVariant. // Fall back to wrapping in a QVariant.
result = QV4::Value::fromObject(m_v4Engine->newVariantObject(QVariant(type, data))); return QV4::Value::fromObject(m_v4Engine->newVariantObject(QVariant(type, data))).asReturnedValue();
} }
} }
} }
return result; Q_UNREACHABLE();
return 0;
} }
// Converts a JS value to a meta-type. // Converts a JS value to a meta-type.
@ -874,7 +867,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) {
} }
// Converts a QVariant to JS. // Converts a QVariant to JS.
QV4::Value QV8Engine::variantToJS(const QVariant &value) QV4::ReturnedValue QV8Engine::variantToJS(const QVariant &value)
{ {
return metaTypeToJS(value.userType(), value.constData()); return metaTypeToJS(value.userType(), value.constData());
} }

View File

@ -121,6 +121,7 @@ namespace QV4 {
// valid during the call. If the return value isn't set within myMethod(), the will return // valid during the call. If the return value isn't set within myMethod(), the will return
// undefined. // undefined.
class QV8Engine; class QV8Engine;
// ### GC
class QQmlV4Function class QQmlV4Function
{ {
public: public:
@ -129,6 +130,7 @@ public:
QQmlContextData *context() { return ctx; } QQmlContextData *context() { return ctx; }
QV4::Value qmlGlobal() { return global; } QV4::Value qmlGlobal() { return global; }
void setReturnValue(const QV4::Value &rv) { *retVal = rv; } void setReturnValue(const QV4::Value &rv) { *retVal = rv; }
void setReturnValue(QV4::ReturnedValue rv) { *retVal = QV4::Value::fromReturnedValue(rv); }
QV8Engine *engine() const { return e; } QV8Engine *engine() const { return e; }
private: private:
friend struct QV4::QObjectMethod; friend struct QV4::QObjectMethod;
@ -149,6 +151,7 @@ private:
QV8Engine *e; QV8Engine *e;
}; };
// ### GC
class Q_QML_PRIVATE_EXPORT QQmlV4Handle class Q_QML_PRIVATE_EXPORT QQmlV4Handle
{ {
public: public:
@ -210,7 +213,7 @@ public:
void freezeObject(const QV4::Value &value); void freezeObject(const QV4::Value &value);
QVariant toVariant(const QV4::Value &value, int typeHint); QVariant toVariant(const QV4::Value &value, int typeHint);
QV4::Value fromVariant(const QVariant &); QV4::ReturnedValue fromVariant(const QVariant &);
// Return a JS string for the given QString \a string // Return a JS string for the given QString \a string
QV4::Value toString(const QString &string); QV4::Value toString(const QString &string);
@ -232,19 +235,19 @@ public:
inline Deletable *extensionData(int) const; inline Deletable *extensionData(int) const;
void setExtensionData(int, Deletable *); void setExtensionData(int, Deletable *);
QV4::Value variantListToJS(const QVariantList &lst); QV4::ReturnedValue variantListToJS(const QVariantList &lst);
inline QVariantList variantListFromJS(QV4::ArrayObject *array) inline QVariantList variantListFromJS(QV4::ArrayObject *array)
{ V8ObjectSet visitedObjects; return variantListFromJS(array, visitedObjects); } { V8ObjectSet visitedObjects; return variantListFromJS(array, visitedObjects); }
QV4::Value variantMapToJS(const QVariantMap &vmap); QV4::ReturnedValue variantMapToJS(const QVariantMap &vmap);
inline QVariantMap variantMapFromJS(QV4::Object *object) inline QVariantMap variantMapFromJS(QV4::Object *object)
{ V8ObjectSet visitedObjects; return variantMapFromJS(object, visitedObjects); } { V8ObjectSet visitedObjects; return variantMapFromJS(object, visitedObjects); }
QV4::Value variantToJS(const QVariant &value); QV4::ReturnedValue variantToJS(const QVariant &value);
inline QVariant variantFromJS(const QV4::Value &value) inline QVariant variantFromJS(const QV4::Value &value)
{ V8ObjectSet visitedObjects; return variantFromJS(value, visitedObjects); } { V8ObjectSet visitedObjects; return variantFromJS(value, visitedObjects); }
QV4::Value metaTypeToJS(int type, const void *data); QV4::ReturnedValue metaTypeToJS(int type, const void *data);
bool metaTypeFromJS(const QV4::Value &value, int type, void *data); bool metaTypeFromJS(const QV4::Value &value, int type, void *data);
bool convertToNativeQObject(const QV4::Value &value, bool convertToNativeQObject(const QV4::Value &value,

View File

@ -63,10 +63,10 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
{ {
Q_MANAGED Q_MANAGED
QV4::Value (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg); QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg);
uint flag; uint flag;
DelegateModelGroupFunction(QV4::ExecutionContext *scope, uint flag, QV4::Value (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg)) DelegateModelGroupFunction(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg))
: FunctionObject(scope, /*name*/0) : FunctionObject(scope, /*name*/0)
, code(code) , code(code)
, flag(flag) , flag(flag)
@ -89,7 +89,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
that->engine()->current->throwTypeError(QStringLiteral("Not a valid VisualData object")); that->engine()->current->throwTypeError(QStringLiteral("Not a valid VisualData object"));
QV4::Value v = callData->argc ? callData->args[0] : QV4::Value::undefinedValue(); QV4::Value v = callData->argc ? callData->args[0] : QV4::Value::undefinedValue();
return f->code(o->item, f->flag, v).asReturnedValue(); return f->code(o->item, f->flag, v);
} }
}; };
@ -1550,13 +1550,16 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
if (!o) if (!o)
return false; return false;
QV4::Scope scope(o->engine());
QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly|QV4::ObjectIterator::WithProtoChain); QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly|QV4::ObjectIterator::WithProtoChain);
QV4::ScopedValue propertyName(scope);
while (1) { while (1) {
QV4::Value value; QV4::Value value;
QV4::Value propertyName = it.nextPropertyNameAsString(&value); propertyName = it.nextPropertyNameAsString(&value);
if (propertyName.isNull()) if (propertyName->isNull())
break; break;
cacheItem->setValue(propertyName.toQStringNoThrow(), m_cacheMetaType->v8Engine->toVariant(value, QVariant::Invalid)); cacheItem->setValue(propertyName->toQStringNoThrow(), m_cacheMetaType->v8Engine->toVariant(value, QVariant::Invalid));
} }
cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag; cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag;
@ -1698,7 +1701,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_model(QV4::SimpleCallContext *ctx)
if (!o->item->metaType->model) if (!o->item->metaType->model)
return QV4::Encode::undefined(); return QV4::Encode::undefined();
return o->item->get().asReturnedValue(); return o->item->get();
} }
QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx) QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx)
@ -1713,7 +1716,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx
groups.append(o->item->metaType->groupNames.at(i - 1)); groups.append(o->item->metaType->groupNames.at(i - 1));
} }
return ctx->engine->v8Engine->fromVariant(groups).asReturnedValue(); return ctx->engine->v8Engine->fromVariant(groups);
} }
QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx) QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx)
@ -1735,22 +1738,22 @@ QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx
return QV4::Encode::undefined(); return QV4::Encode::undefined();
} }
QV4::Value QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &) QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
{ {
return QV4::Value::fromBoolean(thisItem->groups & (1 << flag)); return QV4::Encode(bool(thisItem->groups & (1 << flag)));
} }
QV4::Value QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, uint flag, const QV4::Value &arg) QV4::ReturnedValue QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, uint flag, const QV4::Value &arg)
{ {
if (!cacheItem->metaType->model) if (!cacheItem->metaType->model)
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model); QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model);
bool member = arg.toBoolean(); bool member = arg.toBoolean();
uint groupFlag = (1 << flag); uint groupFlag = (1 << flag);
if (member == ((cacheItem->groups & groupFlag) != 0)) if (member == ((cacheItem->groups & groupFlag) != 0))
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
const int cacheIndex = model->m_cache.indexOf(cacheItem); const int cacheIndex = model->m_cache.indexOf(cacheItem);
Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex); Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
@ -1758,12 +1761,12 @@ QV4::Value QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, u
model->addGroups(it, 1, Compositor::Cache, groupFlag); model->addGroups(it, 1, Compositor::Cache, groupFlag);
else else
model->removeGroups(it, 1, Compositor::Cache, groupFlag); model->removeGroups(it, 1, Compositor::Cache, groupFlag);
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} }
QV4::Value QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &) QV4::ReturnedValue QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
{ {
return QV4::Value::fromInt32(thisItem->groupIndex(Compositor::Group(flag))); return QV4::Encode((int)thisItem->groupIndex(Compositor::Group(flag)));
} }

View File

@ -128,7 +128,7 @@ public:
int modelIndex() const { return index; } int modelIndex() const { return index; }
void setModelIndex(int idx) { index = idx; Q_EMIT modelIndexChanged(); } void setModelIndex(int idx) { index = idx; Q_EMIT modelIndexChanged(); }
virtual QV4::Value get() { return QV4::QObjectWrapper::wrap(v4, this); } virtual QV4::ReturnedValue get() { return QV4::QObjectWrapper::wrap(v4, this); }
virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); } virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; } virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
@ -136,9 +136,9 @@ public:
static QV4::ReturnedValue get_model(QV4::SimpleCallContext *ctx); static QV4::ReturnedValue get_model(QV4::SimpleCallContext *ctx);
static QV4::ReturnedValue get_groups(QV4::SimpleCallContext *ctx); static QV4::ReturnedValue get_groups(QV4::SimpleCallContext *ctx);
static QV4::ReturnedValue set_groups(QV4::SimpleCallContext *ctx); static QV4::ReturnedValue set_groups(QV4::SimpleCallContext *ctx);
static QV4::Value get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &); static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
static QV4::Value set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
static QV4::Value get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
QV4::ExecutionEngine *v4; QV4::ExecutionEngine *v4;
QQmlDelegateModelItemMetaType * const metaType; QQmlDelegateModelItemMetaType * const metaType;

View File

@ -418,9 +418,10 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles,
QV4::Scoped<QV4::Object> o(scope); QV4::Scoped<QV4::Object> o(scope);
QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly); QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
QV4::Scoped<QV4::String> propertyName(scope);
while (1) { while (1) {
QV4::Value propertyValue; QV4::Value propertyValue;
QV4::String *propertyName = it.nextPropertyNameAsString(&propertyValue).asString(); propertyName = it.nextPropertyNameAsString(&propertyValue);
if (!propertyName) if (!propertyName)
break; break;
@ -429,13 +430,13 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles,
// Add the value now // Add the value now
if (QV4::String *s = propertyValue.asString()) { if (QV4::String *s = propertyValue.asString()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String);
roleIndex = e->setStringProperty(r, s->toQString()); roleIndex = e->setStringProperty(r, s->toQString());
} else if (propertyValue.isNumber()) { } else if (propertyValue.isNumber()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number);
roleIndex = e->setDoubleProperty(r, propertyValue.asDouble()); roleIndex = e->setDoubleProperty(r, propertyValue.asDouble());
} else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) { } else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List);
ListModel *subModel = new ListModel(r.subLayout, 0, -1); ListModel *subModel = new ListModel(r.subLayout, 0, -1);
int arrayLength = a->arrayLength(); int arrayLength = a->arrayLength();
@ -446,25 +447,25 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles,
roleIndex = e->setListProperty(r, subModel); roleIndex = e->setListProperty(r, subModel);
} else if (propertyValue.isBoolean()) { } else if (propertyValue.isBoolean()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool);
roleIndex = e->setBoolProperty(r, propertyValue.booleanValue()); roleIndex = e->setBoolProperty(r, propertyValue.booleanValue());
} else if (QV4::DateObject *dd = propertyValue.asDateObject()) { } else if (QV4::DateObject *dd = propertyValue.asDateObject()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime);
QDateTime dt = dd->toQDateTime(); QDateTime dt = dd->toQDateTime();
roleIndex = e->setDateTimeProperty(r, dt); roleIndex = e->setDateTimeProperty(r, dt);
} else if (QV4::Object *o = propertyValue.asObject()) { } else if (QV4::Object *o = propertyValue.asObject()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) { if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
QObject *o = wrapper->object(); QObject *o = wrapper->object();
const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::QObject);
if (role.type == ListLayout::Role::QObject) if (role.type == ListLayout::Role::QObject)
roleIndex = e->setQObjectProperty(role, o); roleIndex = e->setQObjectProperty(role, o);
} else { } else {
const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::VariantMap);
if (role.type == ListLayout::Role::VariantMap) if (role.type == ListLayout::Role::VariantMap)
roleIndex = e->setVariantMapProperty(role, o, eng); roleIndex = e->setVariantMapProperty(role, o, eng);
} }
} else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) { } else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) {
const ListLayout::Role *r = m_layout->getExistingRole(propertyName); const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer());
if (r) if (r)
e->clearProperty(*r); e->clearProperty(*r);
} }
@ -487,24 +488,25 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng)
QV4::Scoped<QV4::Object> o(scope); QV4::Scoped<QV4::Object> o(scope);
QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly); QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
QV4::Scoped<QV4::String> propertyName(scope);
while (1) { while (1) {
QV4::Value propertyValue; QV4::Value propertyValue;
QV4::String *propertyName = it.nextPropertyNameAsString(&propertyValue).asString(); propertyName = it.nextPropertyNameAsString(&propertyValue);
if (!propertyName) if (!propertyName)
break; break;
// Add the value now // Add the value now
if (QV4::String *s = propertyValue.asString()) { if (QV4::String *s = propertyValue.asString()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String);
if (r.type == ListLayout::Role::String) if (r.type == ListLayout::Role::String)
e->setStringPropertyFast(r, s->toQString()); e->setStringPropertyFast(r, s->toQString());
} else if (propertyValue.isNumber()) { } else if (propertyValue.isNumber()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number);
if (r.type == ListLayout::Role::Number) { if (r.type == ListLayout::Role::Number) {
e->setDoublePropertyFast(r, propertyValue.asDouble()); e->setDoublePropertyFast(r, propertyValue.asDouble());
} }
} else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) { } else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List);
if (r.type == ListLayout::Role::List) { if (r.type == ListLayout::Role::List) {
ListModel *subModel = new ListModel(r.subLayout, 0, -1); ListModel *subModel = new ListModel(r.subLayout, 0, -1);
@ -517,12 +519,12 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng)
e->setListPropertyFast(r, subModel); e->setListPropertyFast(r, subModel);
} }
} else if (propertyValue.isBoolean()) { } else if (propertyValue.isBoolean()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool);
if (r.type == ListLayout::Role::Bool) { if (r.type == ListLayout::Role::Bool) {
e->setBoolPropertyFast(r, propertyValue.booleanValue()); e->setBoolPropertyFast(r, propertyValue.booleanValue());
} }
} else if (QV4::DateObject *dd = propertyValue.asDateObject()) { } else if (QV4::DateObject *dd = propertyValue.asDateObject()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime);
if (r.type == ListLayout::Role::DateTime) { if (r.type == ListLayout::Role::DateTime) {
QDateTime dt = dd->toQDateTime();; QDateTime dt = dd->toQDateTime();;
e->setDateTimePropertyFast(r, dt); e->setDateTimePropertyFast(r, dt);
@ -530,16 +532,16 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng)
} else if (QV4::Object *o = propertyValue.asObject()) { } else if (QV4::Object *o = propertyValue.asObject()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) { if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
QObject *o = wrapper->object(); QObject *o = wrapper->object();
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::QObject);
if (r.type == ListLayout::Role::QObject) if (r.type == ListLayout::Role::QObject)
e->setQObjectPropertyFast(r, o); e->setQObjectPropertyFast(r, o);
} else { } else {
const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::VariantMap);
if (role.type == ListLayout::Role::VariantMap) if (role.type == ListLayout::Role::VariantMap)
e->setVariantMapFast(role, o, eng); e->setVariantMapFast(role, o, eng);
} }
} else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) { } else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) {
const ListLayout::Role *r = m_layout->getExistingRole(propertyName); const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer());
if (r) if (r)
e->clearProperty(*r); e->clearProperty(*r);
} }
@ -1252,7 +1254,8 @@ void ModelNodeMetaObject::propertyWritten(int index)
QString propName = QString::fromUtf8(name(index)); QString propName = QString::fromUtf8(name(index));
QVariant value = operator[](index); QVariant value = operator[](index);
QV4::Value v = eng->fromVariant(value); QV4::Scope scope(QV8Engine::getV4((eng)));
QV4::ScopedValue v(scope, eng->fromVariant(value));
int roleIndex = m_obj->m_model->m_listModel->setExistingProperty(m_obj->m_elementIndex, propName, v, eng); int roleIndex = m_obj->m_model->m_listModel->setExistingProperty(m_obj->m_elementIndex, propName, v, eng);
if (roleIndex != -1) { if (roleIndex != -1) {
@ -2103,10 +2106,11 @@ void QQmlListModel::append(QQmlV4Function *args)
*/ */
QQmlV4Handle QQmlListModel::get(int index) const QQmlV4Handle QQmlListModel::get(int index) const
{ {
QV4::Value result = QV4::Value::undefinedValue(); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine());
QV4::Scope scope(v4);
QV4::ScopedValue result(scope, QV4::Value::undefinedValue());
if (index >= 0 && index < count()) { if (index >= 0 && index < count()) {
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine());
if (m_dynamicRoles) { if (m_dynamicRoles) {
DynamicRoleModelNode *object = m_modelObjects[index]; DynamicRoleModelNode *object = m_modelObjects[index];

View File

@ -725,7 +725,8 @@ bool QQuickWorkerScript::event(QEvent *event)
if (engine) { if (engine) {
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event); WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine(); QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine();
QV4::Value value = QV4::Serialize::deserialize(workerEvent->data(), v8engine); QV4::Scope scope(QV8Engine::getV4(v8engine));
QV4::ScopedValue value(scope, QV4::Serialize::deserialize(workerEvent->data(), v8engine));
emit message(QQmlV4Handle(value)); emit message(QQmlV4Handle(value));
} }
return true; return true;

View File

@ -107,8 +107,8 @@ public:
void setValue(const QString &role, const QVariant &value); void setValue(const QString &role, const QVariant &value);
bool resolveIndex(const QQmlAdaptorModel &model, int idx); bool resolveIndex(const QQmlAdaptorModel &model, int idx);
static QV4::Value get_property(QV4::SimpleCallContext *ctx, uint propertyId); static QV4::ReturnedValue get_property(QV4::SimpleCallContext *ctx, uint propertyId);
static QV4::Value set_property(QV4::SimpleCallContext *ctx, uint propertyId); static QV4::ReturnedValue set_property(QV4::SimpleCallContext *ctx, uint propertyId);
VDMModelDelegateDataType *type; VDMModelDelegateDataType *type;
QVector<QVariant> cachedData; QVector<QVariant> cachedData;
@ -341,7 +341,7 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx)
} }
} }
QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId) QV4::ReturnedValue QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId)
{ {
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o) if (!o)
@ -357,10 +357,10 @@ QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint
return ctx->engine->v8Engine->fromVariant( return ctx->engine->v8Engine->fromVariant(
modelData->value(modelData->type->propertyRoles.at(propertyId))); modelData->value(modelData->type->propertyRoles.at(propertyId)));
} }
return QV4::Value::undefinedValue(); return QV4::Encode::undefined();
} }
QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId) QV4::ReturnedValue QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId)
{ {
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>(); QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o) if (!o)
@ -381,6 +381,7 @@ QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint
} }
} }
} }
return QV4::Encode::undefined();
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
@ -421,7 +422,7 @@ public:
type->model->aim()->index(index, 0, type->model->rootIndex), value, role); type->model->aim()->index(index, 0, type->model->rootIndex), value, role);
} }
QV4::Value get() QV4::ReturnedValue get()
{ {
if (type->prototype.isEmpty()) { if (type->prototype.isEmpty()) {
QQmlAdaptorModelEngineData * const data = engineData(v4->v8Engine); QQmlAdaptorModelEngineData * const data = engineData(v4->v8Engine);
@ -432,7 +433,7 @@ public:
o->setPrototype(proto); o->setPrototype(proto);
QV4::Value data = QV4::Value::fromObject(o); QV4::Value data = QV4::Value::fromObject(o);
++scriptRef; ++scriptRef;
return data; return data.asReturnedValue();
} }
}; };
@ -584,7 +585,7 @@ public:
if (!o) if (!o)
ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
return ctx->engine->v8Engine->fromVariant(static_cast<QQmlDMListAccessorData *>(o->item)->cachedData).asReturnedValue(); return ctx->engine->v8Engine->fromVariant(static_cast<QQmlDMListAccessorData *>(o->item)->cachedData);
} }
static QV4::ReturnedValue set_modelData(QV4::SimpleCallContext *ctx) static QV4::ReturnedValue set_modelData(QV4::SimpleCallContext *ctx)
@ -599,14 +600,14 @@ public:
return QV4::Encode::undefined(); return QV4::Encode::undefined();
} }
QV4::Value get() QV4::ReturnedValue get()
{ {
QQmlAdaptorModelEngineData *data = engineData(v4->v8Engine); QQmlAdaptorModelEngineData *data = engineData(v4->v8Engine);
QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, this); QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, this);
o->setPrototype(data->listItemProto.value().asObject()); o->setPrototype(data->listItemProto.value().asObject());
QV4::Value val = QV4::Value::fromObject(o); QV4::Value val = QV4::Value::fromObject(o);
++scriptRef; ++scriptRef;
return val; return val.asReturnedValue();
} }
void setValue(const QString &role, const QVariant &value) void setValue(const QString &role, const QVariant &value)

View File

@ -663,7 +663,7 @@ void QQuickCanvasItem::updatePolish()
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this)); QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this));
QV4::Scope scope(v4); QV4::Scope scope(v4);
QV4::ScopedCallData callData(scope, 1); QV4::ScopedCallData callData(scope, 1);
callData->thisObject = QV4::QObjectWrapper::wrap(v4, this); callData->thisObject = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, this));
foreach (int key, animationCallbacks.keys()) { foreach (int key, animationCallbacks.keys()) {
QV4::FunctionObject *f = animationCallbacks.value(key).value().asFunctionObject(); QV4::FunctionObject *f = animationCallbacks.value(key).value().asFunctionObject();

View File

@ -944,7 +944,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::SimpleCall
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>(); QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r) CHECK_CONTEXT(r)
return QV4::QObjectWrapper::wrap(ctx->engine, r->context->canvas()).asReturnedValue(); return QV4::QObjectWrapper::wrap(ctx->engine, r->context->canvas());
} }
/*! /*!
@ -1386,7 +1386,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(QV4::SimpleCallContext
CHECK_CONTEXT(r) CHECK_CONTEXT(r)
QV8Engine *engine = ctx->engine->v8Engine; QV8Engine *engine = ctx->engine->v8Engine;
return engine->fromVariant(r->context->state.fillRule).asReturnedValue(); return engine->fromVariant(r->context->state.fillRule);
} }
QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::SimpleCallContext *ctx) QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::SimpleCallContext *ctx)

View File

@ -2268,12 +2268,12 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
program.inheritContext = true; program.inheritContext = true;
QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current; QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
QV4::Scope scope(ctx);
try { try {
QV4::FunctionObject *function = program.run().asFunctionObject(); QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
if (!function) if (!function)
return false; return false;
QV4::Scope scope(ctx);
QV4::ScopedCallData d(scope, 1); QV4::ScopedCallData d(scope, 1);
d->args[0] = o; d->args[0] = o;
d->thisObject = engine->global(); d->thisObject = engine->global();
@ -2295,11 +2295,13 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
program.inheritContext = true; program.inheritContext = true;
QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current; QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
QV4::Scope scope(ctx);
try { try {
QV4::FunctionObject *function = program.run().asFunctionObject(); QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
if (!function) if (!function)
return false; return false;
QV4::Scope scope(ctx);
QV4::ScopedValue value(scope); QV4::ScopedValue value(scope);
QV4::ScopedValue res(scope, result); QV4::ScopedValue res(scope, result);
QV4::ScopedCallData d(scope, 1); QV4::ScopedCallData d(scope, 1);
@ -2320,13 +2322,14 @@ static inline QV4::Value evaluate(QV8Engine *engine, const QV4::Value & o,
QLatin1String(source) + QLatin1String(" })"); QLatin1String(source) + QLatin1String(" })");
QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current; QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
QV4::Scope scope(ctx);
QV4::Script program(QV8Engine::getV4(engine)->rootContext, functionSource); QV4::Script program(QV8Engine::getV4(engine)->rootContext, functionSource);
program.inheritContext = true; program.inheritContext = true;
try { try {
QV4::FunctionObject *function = program.run().asFunctionObject(); QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
if (!function) if (!function)
return QV4::Value::emptyValue(); return QV4::Value::emptyValue();
QV4::Scope scope(ctx);
QV4::ScopedCallData d(scope, 1); QV4::ScopedCallData d(scope, 1);
d->args[0] = o; d->args[0] = o;
d->thisObject = engine->global(); d->thisObject = engine->global();
@ -2352,8 +2355,9 @@ void tst_qqmlecmascript::callQtInvokables()
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine);
QV8Engine *engine = ep->v8engine(); QV8Engine *engine = ep->v8engine();
QV4::Scope scope(QV8Engine::getV4(engine));
QV4::Value object = QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o); QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o));
// Non-existent methods // Non-existent methods
o->reset(); o->reset();
@ -3899,7 +3903,8 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
scriptContext = QV4::QmlContextWrapper::getContext(qmlglobal); scriptContext = QV4::QmlContextWrapper::getContext(qmlglobal);
{ {
QV4::Value temporaryScope = QV4::QmlContextWrapper::qmlScope(engine, scriptContext, 0); QV4::Scope scope(QV8Engine::getV4((engine)));
QV4::ScopedValue temporaryScope(scope, QV4::QmlContextWrapper::qmlScope(engine, scriptContext, 0));
Q_UNUSED(temporaryScope) Q_UNUSED(temporaryScope)
} }
@ -4981,9 +4986,9 @@ void tst_qqmlecmascript::propertyVarInheritance()
{ {
// XXX NOTE: this is very implementation dependent. QDVMEMO->vmeProperty() is the only // XXX NOTE: this is very implementation dependent. QDVMEMO->vmeProperty() is the only
// public function which can return us a handle to something in the varProperties array. // public function which can return us a handle to something in the varProperties array.
QV4::Value tmp = icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ")); QV4::Value tmp = QV4::Value::fromReturnedValue(icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ")));
icoCanaryHandle = tmp; icoCanaryHandle = tmp;
tmp = ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ")); tmp = QV4::Value::fromReturnedValue(ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ")));
ccoCanaryHandle = tmp; ccoCanaryHandle = tmp;
tmp = QV4::Value::nullValue(); tmp = QV4::Value::nullValue();
QVERIFY(!icoCanaryHandle.isEmpty()); QVERIFY(!icoCanaryHandle.isEmpty());
@ -5027,7 +5032,7 @@ void tst_qqmlecmascript::propertyVarInheritance2()
QCOMPARE(childObject->property("textCanary").toInt(), 10); QCOMPARE(childObject->property("textCanary").toInt(), 10);
QV4::WeakValue childObjectVarArrayValueHandle; QV4::WeakValue childObjectVarArrayValueHandle;
{ {
QV4::Value tmp = QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp")); QV4::Value tmp = QV4::Value::fromReturnedValue(QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp")));
childObjectVarArrayValueHandle = tmp; childObjectVarArrayValueHandle = tmp;
tmp = QV4::Value::nullValue(); tmp = QV4::Value::nullValue();
QVERIFY(!childObjectVarArrayValueHandle.isEmpty()); QVERIFY(!childObjectVarArrayValueHandle.isEmpty());