diff options
22 files changed, 163 insertions, 136 deletions
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp index 40d0df1a22..09f8967045 100644 --- a/src/particles/qquickcustomaffector.cpp +++ b/src/particles/qquickcustomaffector.cpp @@ -146,13 +146,14 @@ void QQuickCustomAffector::affectSystem(qreal dt) QQmlEngine *qmlEngine = ::qmlEngine(this); QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle()); - QV4::ArrayObject *array = v4->newArrayObject(toAffect.size()); + QV4::Scope scope(v4); + QV4::Scoped<QV4::ArrayObject> array(scope, v4->newArrayObject(toAffect.size())); for (int i=0; i<toAffect.size(); i++) array->putIndexed(i, toAffect[i]->v4Value().toValue()); if (dt >= simulationCutoff || dt <= simulationDelta) { affectProperties(toAffect, dt); - emit affectParticles(QQmlV4Handle(QV4::Value::fromObject(array)), dt); + emit affectParticles(QQmlV4Handle(array.asValue()), dt); } else { int realTime = m_system->timeInt; m_system->timeInt -= dt * 1000.0; @@ -160,12 +161,12 @@ void QQuickCustomAffector::affectSystem(qreal dt) m_system->timeInt += simulationDelta * 1000.0; dt -= simulationDelta; affectProperties(toAffect, simulationDelta); - emit affectParticles(QQmlV4Handle(QV4::Value::fromObject(array)), simulationDelta); + emit affectParticles(QQmlV4Handle(array.asValue()), simulationDelta); } m_system->timeInt = realTime; if (dt > 0.0) { affectProperties(toAffect, dt); - emit affectParticles(QQmlV4Handle(QV4::Value::fromObject(array)), dt); + emit affectParticles(QQmlV4Handle(array.asValue()), dt); } } diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp index 6627291c55..404554c9b6 100644 --- a/src/particles/qquickparticleemitter.cpp +++ b/src/particles/qquickparticleemitter.cpp @@ -481,14 +481,15 @@ void QQuickParticleEmitter::emitWindow(int timeStamp) if (isEmitConnected()) { QQmlEngine *qmlEngine = ::qmlEngine(this); QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle()); + QV4::Scope scope(v4); //Done after emitParticle so that the Painter::load is done first, this allows you to customize its static variables //We then don't need to request another reload, because the first reload isn't scheduled until we get back to the render thread - QV4::ArrayObject *array = v4->newArrayObject(toEmit.size()); + QV4::Scoped<QV4::ArrayObject> array(scope, v4->newArrayObject(toEmit.size())); for (int i=0; i<toEmit.size(); i++) array->putIndexed(i, toEmit[i]->v4Value().toValue()); - emitParticles(QQmlV4Handle(QV4::Value::fromObject(array)));//A chance for arbitrary JS changes + emitParticles(QQmlV4Handle(array.asValue()));//A chance for arbitrary JS changes } m_last_emission = pt; diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp index 4f4a05d09a..84caebf5be 100644 --- a/src/particles/qquicktrailemitter.cpp +++ b/src/particles/qquicktrailemitter.cpp @@ -272,14 +272,15 @@ void QQuickTrailEmitter::emitWindow(int timeStamp) QQmlEngine *qmlEngine = ::qmlEngine(this); QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle()); - QV4::ArrayObject *array = v4->newArrayObject(toEmit.size()); + QV4::Scope scope(v4); + QV4::Scoped<QV4::ArrayObject> array(scope, v4->newArrayObject(toEmit.size())); for (int i=0; i<toEmit.size(); i++) array->putIndexed(i, toEmit[i]->v4Value().toValue()); if (isEmitFollowConnected()) - emitFollowParticles(QQmlV4Handle(QV4::Value::fromObject(array)), d->v4Value());//A chance for many arbitrary JS changes + emitFollowParticles(QQmlV4Handle(array.asValue()), d->v4Value());//A chance for many arbitrary JS changes else if (isEmitConnected()) - emitParticles(QQmlV4Handle(QV4::Value::fromObject(array)));//A chance for arbitrary JS changes + emitParticles(QQmlV4Handle(array.asValue()));//A chance for arbitrary JS changes } m_lastEmission[d->index] = pt; } diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 0f291d7c98..b66dd51648 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -296,11 +296,12 @@ QJSValue QJSEngine::newObject() */ QJSValue QJSEngine::newArray(uint length) { - QV4::ArrayObject *array = d->m_v4Engine->newArrayObject(); + QV4::Scope scope(d->m_v4Engine); + QV4::Scoped<QV4::ArrayObject> array(scope, d->m_v4Engine->newArrayObject()); if (length < 0x1000) array->arrayReserve(length); array->setArrayLengthUnchecked(length); - return new QJSValuePrivate(array); + return new QJSValuePrivate(d->m_v4Engine, array.asValue()); } /*! diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 5508372265..1f09b97d5c 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -57,7 +57,8 @@ ArrayCtor::ArrayCtor(ExecutionContext *scope) ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData) { ExecutionEngine *v4 = m->engine(); - ArrayObject *a = v4->newArrayObject(); + Scope scope(v4); + Scoped<ArrayObject> a(scope, v4->newArrayObject()); uint len; if (callData->argc == 1 && callData->args[0].isNumber()) { bool ok; @@ -77,7 +78,7 @@ ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData) } a->setArrayLengthUnchecked(len); - return Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } ReturnedValue ArrayCtor::call(Managed *that, CallData *callData) @@ -156,7 +157,8 @@ ReturnedValue ArrayPrototype::method_toLocaleString(SimpleCallContext *ctx) ReturnedValue ArrayPrototype::method_concat(SimpleCallContext *ctx) { - ArrayObject *result = ctx->engine->newArrayObject(); + Scope scope(ctx); + Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject()); if (ArrayObject *instance = ctx->thisObject.asArrayObject()) { result->copyArrayData(instance); @@ -178,10 +180,10 @@ ReturnedValue ArrayPrototype::method_concat(SimpleCallContext *ctx) result->arrayConcat(elt); else - result->arraySet(getLength(ctx, result), arg); + result->arraySet(getLength(ctx, result.getPointer()), arg); } - return Value::fromObject(result).asReturnedValue(); + return result.asReturnedValue(); } ReturnedValue ArrayPrototype::method_join(SimpleCallContext *ctx) @@ -404,7 +406,7 @@ ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx) Scope scope(ctx); Object *o = ctx->thisObject.toObject(ctx); - ArrayObject *result = ctx->engine->newArrayObject(); + Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject()); uint len = ArrayPrototype::getLength(ctx, o); double s = ctx->argument(0).toInteger(); uint start; @@ -435,7 +437,7 @@ ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx) } ++n; } - return Value::fromObject(result).asReturnedValue(); + return result.asReturnedValue(); } ReturnedValue ArrayPrototype::method_sort(SimpleCallContext *ctx) @@ -455,7 +457,7 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx) Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); - ArrayObject *newArray = ctx->engine->newArrayObject(); + Scoped<ArrayObject> newArray(scope, ctx->engine->newArrayObject()); double rs = ctx->argument(0).toInteger(); uint start; @@ -508,7 +510,7 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx) ctx->strictMode = true; instance->put(ctx->engine->id_length, Value::fromDouble(len - deleteCount + itemCount)); - return Value::fromObject(newArray).asReturnedValue(); + return newArray.asReturnedValue(); } ReturnedValue ArrayPrototype::method_unshift(SimpleCallContext *ctx) @@ -750,7 +752,7 @@ ReturnedValue ArrayPrototype::method_map(SimpleCallContext *ctx) Value thisArg = ctx->argument(1); - ArrayObject *a = ctx->engine->newArrayObject(); + Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject()); a->arrayReserve(len); a->setArrayLengthUnchecked(len); @@ -771,7 +773,7 @@ ReturnedValue ArrayPrototype::method_map(SimpleCallContext *ctx) mapped = callback->call(callData); a->arraySet(k, mapped); } - return Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } ReturnedValue ArrayPrototype::method_filter(SimpleCallContext *ctx) @@ -787,7 +789,7 @@ ReturnedValue ArrayPrototype::method_filter(SimpleCallContext *ctx) Value thisArg = ctx->argument(1); - ArrayObject *a = ctx->engine->newArrayObject(); + Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject()); a->arrayReserve(len); ScopedValue selected(scope); @@ -812,7 +814,7 @@ ReturnedValue ArrayPrototype::method_filter(SimpleCallContext *ctx) ++to; } } - return Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } ReturnedValue ArrayPrototype::method_reduce(SimpleCallContext *ctx) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 0187099f62..1a084905ae 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -393,7 +393,7 @@ Returned<Object> *ExecutionEngine::newBooleanObject(const Value &value) return object->asReturned<Object>(); } -ArrayObject *ExecutionEngine::newArrayObject(int count) +Returned<ArrayObject> *ExecutionEngine::newArrayObject(int count) { ArrayObject *object = new (memoryManager) ArrayObject(this); @@ -402,19 +402,19 @@ ArrayObject *ExecutionEngine::newArrayObject(int count) object->arrayReserve(count); object->setArrayLengthUnchecked(count); } - return object; + return object->asReturned<ArrayObject>(); } -ArrayObject *ExecutionEngine::newArrayObject(const QStringList &list) +Returned<ArrayObject> *ExecutionEngine::newArrayObject(const QStringList &list) { ArrayObject *object = new (memoryManager) ArrayObject(this, list); - return object; + return object->asReturned<ArrayObject>(); } -ArrayObject *ExecutionEngine::newArrayObject(InternalClass *ic) +Returned<ArrayObject> *ExecutionEngine::newArrayObject(InternalClass *ic) { ArrayObject *object = new (memoryManager) ArrayObject(ic); - return object; + return object->asReturned<ArrayObject>(); } @@ -474,43 +474,50 @@ Returned<Object> *ExecutionEngine::newSyntaxErrorObject(const QString &message, } -Object *ExecutionEngine::newReferenceErrorObject(const QString &message) +Returned<Object> *ExecutionEngine::newReferenceErrorObject(const QString &message) { - return new (memoryManager) ReferenceErrorObject(this, message); + Object *o = new (memoryManager) ReferenceErrorObject(this, message); + return o->asReturned<Object>(); } -Object *ExecutionEngine::newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber) +Returned<Object> *ExecutionEngine::newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber) { - return new (memoryManager) ReferenceErrorObject(this, message, fileName, lineNumber, columnNumber); + Object *o = new (memoryManager) ReferenceErrorObject(this, message, fileName, lineNumber, columnNumber); + return o->asReturned<Object>(); } -Object *ExecutionEngine::newTypeErrorObject(const QString &message) +Returned<Object> *ExecutionEngine::newTypeErrorObject(const QString &message) { - return new (memoryManager) TypeErrorObject(this, message); + Object *o = new (memoryManager) TypeErrorObject(this, message); + return o->asReturned<Object>(); } -Object *ExecutionEngine::newRangeErrorObject(const QString &message) +Returned<Object> *ExecutionEngine::newRangeErrorObject(const QString &message) { - return new (memoryManager) RangeErrorObject(this, message); + Object *o = new (memoryManager) RangeErrorObject(this, message); + return o->asReturned<Object>(); } -Object *ExecutionEngine::newURIErrorObject(Value message) +Returned<Object> *ExecutionEngine::newURIErrorObject(Value message) { - return new (memoryManager) URIErrorObject(this, message); + Object *o = new (memoryManager) URIErrorObject(this, message); + return o->asReturned<Object>(); } -Object *ExecutionEngine::newVariantObject(const QVariant &v) +Returned<Object> *ExecutionEngine::newVariantObject(const QVariant &v) { - return new (memoryManager) VariantObject(this, v); + Object *o = new (memoryManager) VariantObject(this, v); + return o->asReturned<Object>(); } -Object *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o) +Returned<Object> *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o) { - return new (memoryManager) ForEachIteratorObject(ctx, o); + Object *obj = new (memoryManager) ForEachIteratorObject(ctx, o); + return obj->asReturned<Object>(); } -Object *ExecutionEngine::qmlContextObject() const +Returned<Object> *ExecutionEngine::qmlContextObject() const { ExecutionContext *ctx = current; @@ -527,7 +534,7 @@ Object *ExecutionEngine::qmlContextObject() const if (ctx->type != ExecutionContext::Type_QmlContext) return 0; - return static_cast<CallContext *>(ctx)->activation; + return static_cast<CallContext *>(ctx)->activation->asReturned<Object>(); } namespace { diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 5ef7d08a4a..297f756033 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -274,9 +274,9 @@ struct Q_QML_EXPORT ExecutionEngine Returned<Object> *newNumberObject(const Value &value); Returned<Object> *newBooleanObject(const Value &value); - ArrayObject *newArrayObject(int count = 0); - ArrayObject *newArrayObject(const QStringList &list); - ArrayObject *newArrayObject(InternalClass *ic); + Returned<ArrayObject> *newArrayObject(int count = 0); + Returned<ArrayObject> *newArrayObject(const QStringList &list); + Returned<ArrayObject> *newArrayObject(InternalClass *ic); Returned<DateObject> *newDateObject(const Value &value); Returned<DateObject> *newDateObject(const QDateTime &dt); @@ -288,17 +288,17 @@ struct Q_QML_EXPORT ExecutionEngine Returned<Object> *newErrorObject(const Value &value); Returned<Object> *newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column); Returned<Object> *newSyntaxErrorObject(const QString &message); - Object *newReferenceErrorObject(const QString &message); - Object *newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber); - Object *newTypeErrorObject(const QString &message); - Object *newRangeErrorObject(const QString &message); - Object *newURIErrorObject(Value message); + Returned<Object> *newReferenceErrorObject(const QString &message); + Returned<Object> *newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber); + Returned<Object> *newTypeErrorObject(const QString &message); + Returned<Object> *newRangeErrorObject(const QString &message); + Returned<Object> *newURIErrorObject(Value message); - Object *newVariantObject(const QVariant &v); + Returned<Object> *newVariantObject(const QVariant &v); - Object *newForEachIteratorObject(ExecutionContext *ctx, Object *o); + Returned<Object> *newForEachIteratorObject(ExecutionContext *ctx, Object *o); - Object *qmlContextObject() const; + Returned<Object> *qmlContextObject() const; struct StackFrame { QString source; diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index ac9a50c3a1..740bb406f3 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -196,11 +196,11 @@ QV4::ReturnedValue QV4Include::method_include(QV4::SimpleCallContext *ctx) QString localFile = QQmlFile::urlToLocalFileOrQrc(url); QV4::ScopedValue result(scope); + QV4::Scoped<QV4::Object> qmlcontextobject(scope, v4->qmlContextObject()); if (localFile.isEmpty()) { - QV4Include *i = new QV4Include(url, engine, context, - QV4::Value::fromObject(v4->qmlContextObject()), + qmlcontextobject.asValue(), callbackFunction); result = i->result(); @@ -213,8 +213,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::SimpleCallContext *ctx) QString code = QString::fromUtf8(data); QQmlScript::Parser::extractPragmas(code); - QV4::Scoped<QV4::Object> qmlglobal(scope, QV4::Value::fromObject(v4->qmlContextObject())); - QV4::Script script(v4, qmlglobal.getPointer(), code, url.toString()); + QV4::Script script(v4, qmlcontextobject.getPointer(), code, url.toString()); QV4::ExecutionContext *ctx = v4->current; try { diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index a42cfd4873..2bb755b537 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -77,8 +77,8 @@ private: inline bool eatSpace(); inline QChar nextToken(); - Value parseObject(); - Value parseArray(); + ReturnedValue parseObject(); + ReturnedValue parseArray(); bool parseMember(Object *o); bool parseString(QString *string); bool parseValue(Value *val); @@ -224,42 +224,42 @@ Value JsonParser::parse(QJsonParseError *error) end-object */ -Value JsonParser::parseObject() +ReturnedValue JsonParser::parseObject() { if (++nestingLevel > nestingLimit) { lastError = QJsonParseError::DeepNesting; - return Value::undefinedValue(); + return Encode::undefined(); } BEGIN << "parseObject pos=" << json; + Scope scope(context); - Object *o = context->engine->newObject(); - Value objectVal = Value::fromObject(o); + Scoped<Object> o(scope, context->engine->newObject()); QChar token = nextToken(); while (token == Quote) { - if (!parseMember(o)) - return Value::undefinedValue(); + if (!parseMember(o.getPointer())) + return Encode::undefined(); token = nextToken(); if (token != ValueSeparator) break; token = nextToken(); if (token == EndObject) { lastError = QJsonParseError::MissingObject; - return Value::undefinedValue(); + return Encode::undefined(); } } DEBUG << "end token=" << token; if (token != EndObject) { lastError = QJsonParseError::UnterminatedObject; - return Value::undefinedValue(); + return Encode::undefined(); } END; --nestingLevel; - return objectVal; + return o.asReturnedValue(); } /* @@ -291,19 +291,20 @@ bool JsonParser::parseMember(Object *o) /* array = begin-array [ value *( value-separator value ) ] end-array */ -Value JsonParser::parseArray() +ReturnedValue JsonParser::parseArray() { + Scope scope(context); BEGIN << "parseArray"; - ArrayObject *array = context->engine->newArrayObject(); + Scoped<ArrayObject> array(scope, context->engine->newArrayObject()); if (++nestingLevel > nestingLimit) { lastError = QJsonParseError::DeepNesting; - return Value::undefinedValue(); + return Encode::undefined(); } if (!eatSpace()) { lastError = QJsonParseError::UnterminatedArray; - return Value::undefinedValue(); + return Encode::undefined(); } if (*json == EndArray) { nextToken(); @@ -312,7 +313,7 @@ Value JsonParser::parseArray() while (1) { Value val; if (!parseValue(&val)) - return Value::undefinedValue(); + return Encode::undefined(); array->arraySet(index, val); QChar token = nextToken(); if (token == EndArray) @@ -322,7 +323,7 @@ Value JsonParser::parseArray() lastError = QJsonParseError::UnterminatedArray; else lastError = QJsonParseError::MissingValueSeparator; - return Value::undefinedValue(); + return Encode::undefined(); } ++index; } @@ -332,7 +333,7 @@ Value JsonParser::parseArray() END; --nestingLevel; - return Value::fromObject(array); + return array.asReturnedValue(); } /* @@ -401,7 +402,7 @@ bool JsonParser::parseValue(Value *val) return true; } case BeginArray: { - *val = parseArray(); + *val = Value::fromReturnedValue(parseArray()); if (val->isUndefined()) return false; DEBUG << "value: array"; @@ -409,7 +410,7 @@ bool JsonParser::parseValue(Value *val) return true; } case BeginObject: { - *val = parseObject(); + *val = Value::fromReturnedValue(parseObject()); if (val->isUndefined()) return false; DEBUG << "value: object"; @@ -1020,14 +1021,15 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array) { + Scope scope(engine); int size = array.size(); - ArrayObject *a = engine->newArrayObject(); + Scoped<ArrayObject> a(scope, engine->newArrayObject()); a->arrayReserve(size); a->arrayDataLen = size; for (int i = 0; i < size; i++) a->arrayData[i].value = Value::fromReturnedValue(fromJsonValue(engine, array.at(i))); a->setArrayLengthUnchecked(size); - return Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects) diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 7b372a4e17..6496a0354a 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -1424,6 +1424,8 @@ void Object::markArrayObjects() const } } +DEFINE_MANAGED_VTABLE(ArrayObject); + ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list) : Object(engine->arrayClass) { diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index b7b08c2b34..765ec18728 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -375,6 +375,7 @@ protected: }; struct ArrayObject: Object { + Q_MANAGED enum { LengthPropertyIndex = 0 }; diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index fe041f0bd7..073d588e56 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -355,7 +355,7 @@ ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx) Scope scope(ctx); Object *o = ctx->argument(0).objectValue(); - ArrayObject *a = ctx->engine->newArrayObject(); + Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject()); ObjectIterator it(o, ObjectIterator::EnumerableOnly); ScopedValue name(scope); @@ -366,7 +366,7 @@ ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx) a->push_back(name); } - return Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } ReturnedValue ObjectPrototype::method_toString(SimpleCallContext *ctx) @@ -608,10 +608,10 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Value &o) { Scope scope(v4); - ArrayObject *array = v4->newArrayObject(); + Scoped<ArrayObject> array(scope, v4->newArrayObject()); Object *O = o.asObject(); if (!O) - return array; + return array.getPointer(); ObjectIterator it(O, ObjectIterator::NoFlags); ScopedValue name(scope); @@ -621,5 +621,5 @@ ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Val break; array->push_back(name); } - return array; + return array.getPointer(); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index abff3ac93d..d774014073 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -323,8 +323,9 @@ ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextD Q_ASSERT(vmemo); return vmemo->vmeMethod(result->coreIndex); } else if (result->isV4Function()) { + QV4::Scoped<QV4::Object> qmlcontextobject(scope, ctx->engine->qmlContextObject()); return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex, - QV4::Value::fromObject(ctx->engine->qmlContextObject())).asReturnedValue(); + qmlcontextobject.asValue()).asReturnedValue(); } else if (result->isSignalHandler()) { QV4::QmlSignalHandler *handler = new (ctx->engine->memoryManager) QV4::QmlSignalHandler(ctx->engine, m_object, result->coreIndex); @@ -1603,13 +1604,13 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine) // XXX Can this be made more by using Array as a prototype and implementing // directly against QList<QObject*>? QList<QObject *> &list = *qlistPtr; - QV4::ArrayObject *array = v4->newArrayObject(); + QV4::Scoped<ArrayObject> array(scope, v4->newArrayObject()); array->arrayReserve(list.count()); array->arrayDataLen = list.count(); for (int ii = 0; ii < list.count(); ++ii) array->arrayData[ii].value = Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, list.at(ii))); array->setArrayLengthUnchecked(list.count()); - return QV4::Value::fromObject(array).asReturnedValue(); + return array.asReturnedValue(); } else if (type == qMetaTypeId<QQmlV4Handle>()) { return handlePtr->toValue().asReturnedValue(); } else if (type == QMetaType::QJsonArray) { diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 38ebf8d9e6..60a5026772 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -321,7 +321,7 @@ ReturnedValue RegExpPrototype::method_exec(SimpleCallContext *ctx) } // fill in result data - ArrayObject *array = ctx->engine->newArrayObject(ctx->engine->regExpExecArrayClass); + Scoped<ArrayObject> array(scope, ctx->engine->newArrayObject(ctx->engine->regExpExecArrayClass)); int len = r->value->captureCount(); array->arrayReserve(len); for (int i = 0; i < len; ++i) { @@ -338,7 +338,7 @@ ReturnedValue RegExpPrototype::method_exec(SimpleCallContext *ctx) if (r->global) r->lastIndexProperty(ctx)->value = Value::fromInt32(matchOffsets[1]); - return Value::fromObject(array).asReturnedValue(); + return array.asReturnedValue(); } ReturnedValue RegExpPrototype::method_test(SimpleCallContext *ctx) diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index d98087b6a4..f2c655f5fe 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -735,11 +735,12 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val ReturnedValue __qmljs_foreach_iterator_object(ExecutionContext *ctx, const ValueRef in) { - Object *o = 0; + Scope scope(ctx); + Scoped<Object> o(scope, (Object *)0); if (!in->isNullOrUndefined()) - o = in->toObject(ctx); - Object *it = ctx->engine->newForEachIteratorObject(ctx, o); - return Value::fromObject(it).asReturnedValue(); + o = in; + Scoped<Object> it(scope, ctx->engine->newForEachIteratorObject(ctx, o.getPointer())); + return it.asReturnedValue(); } ReturnedValue __qmljs_foreach_next_property_name(const ValueRef foreach_iterator) @@ -1161,7 +1162,8 @@ void __qmljs_builtin_define_property(ExecutionContext *ctx, const ValueRef objec ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, Value *values, uint length) { - ArrayObject *a = ctx->engine->newArrayObject(); + Scope scope(ctx); + Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject()); // ### FIXME: We need to allocate the array data to avoid crashes other places // This should rather be done when required @@ -1181,7 +1183,7 @@ ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, Value *values, } a->setArrayLengthUnchecked(length); } - return Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const ValueRef object, String *name, const ValueRef getter, const ValueRef setter) diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 4bbd3303ee..5fe870c21d 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -197,6 +197,7 @@ struct Scoped #endif } + // ### GC FIX casting below to be safe Scoped(const Scope &scope, const Value &v) { ptr = scope.engine->jsStackTop++; diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index f76f76b6d2..41481ac1b8 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -317,13 +317,13 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine) case WorkerArray: { quint32 size = headersize(header); - QV4::ArrayObject *a = v4->newArrayObject(); + Scoped<ArrayObject> a(scope, v4->newArrayObject()); ScopedValue v(scope); for (quint32 ii = 0; ii < size; ++ii) { v = deserialize(data, engine); a->putIndexed(ii, v); } - return QV4::Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } case WorkerObject: { @@ -377,7 +377,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine) quint32 seqLength = length - 1; value = deserialize(data, engine); int sequenceType = value->integerValue(); - QV4::ArrayObject *array = v4->newArrayObject(); + Scoped<ArrayObject> array(scope, v4->newArrayObject()); array->arrayReserve(seqLength); array->arrayDataLen = seqLength; for (quint32 ii = 0; ii < seqLength; ++ii) { @@ -385,7 +385,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine) array->arrayData[ii].value = value; } array->setArrayLengthUnchecked(seqLength); - QVariant seqVariant = QV4::SequencePrototype::toVariant(QV4::Value::fromObject(array), sequenceType, &succeeded); + QVariant seqVariant = QV4::SequencePrototype::toVariant(array.asValue(), sequenceType, &succeeded); return QV4::SequencePrototype::fromVariant(v4, seqVariant, &succeeded); } } diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 2223432ec9..811c5b26b9 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -379,7 +379,7 @@ ReturnedValue StringPrototype::method_match(SimpleCallContext *context) String *lastIndex = context->engine->newString(QStringLiteral("lastIndex")); rx->put(lastIndex, Value::fromInt32(0)); - ArrayObject *a = context->engine->newArrayObject(); + Scoped<ArrayObject> a(scope, context->engine->newArrayObject()); double previousLastIndex = 0; uint n = 0; @@ -406,7 +406,7 @@ ReturnedValue StringPrototype::method_match(SimpleCallContext *context) if (!n) return Encode::null(); - return Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } @@ -618,6 +618,7 @@ ReturnedValue StringPrototype::method_slice(SimpleCallContext *ctx) ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx) { + Scope scope(ctx); QString text; if (StringObject *thisObject = ctx->thisObject.asStringObject()) text = thisObject->value.stringValue()->toQString(); @@ -627,13 +628,12 @@ ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx) Value separatorValue = ctx->argumentCount > 0 ? ctx->argument(0) : Value::undefinedValue(); Value limitValue = ctx->argumentCount > 1 ? ctx->argument(1) : Value::undefinedValue(); - ArrayObject* array = ctx->engine->newArrayObject(); - Value result = Value::fromObject(array); + Scoped<ArrayObject> array(scope, ctx->engine->newArrayObject()); if (separatorValue.isUndefined()) { if (limitValue.isUndefined()) { array->push_back(Value::fromString(ctx, text)); - return result.asReturnedValue(); + return array.asReturnedValue(); } return Value::fromString(ctx, text.left(limitValue.toInteger())).asReturnedValue(); } @@ -641,7 +641,7 @@ ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx) uint limit = limitValue.isUndefined() ? UINT_MAX : limitValue.toUInt32(); if (limit == 0) - return result.asReturnedValue(); + return array.asReturnedValue(); if (RegExpObject* re = separatorValue.as<RegExpObject>()) { if (re->value->pattern().isEmpty()) { @@ -679,7 +679,7 @@ ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx) if (separator.isEmpty()) { for (uint i = 0; i < qMin(limit, uint(text.length())); ++i) array->push_back(Value::fromString(ctx, text.mid(i, 1))); - return result.asReturnedValue(); + return array.asReturnedValue(); } int start = 0; @@ -693,7 +693,7 @@ ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx) if (array->arrayLength() < limit && start != -1) array->push_back(Value::fromString(ctx, text.mid(start))); } - return result.asReturnedValue(); + return array.asReturnedValue(); } ReturnedValue StringPrototype::method_substr(SimpleCallContext *context) diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 153743aa58..de317a2dcb 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -97,22 +97,22 @@ ReturnedValue QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url) QQmlContextData *QmlContextWrapper::callingContext(ExecutionEngine *v4) { - QV4::Object *qmlglobal = v4->qmlContextObject(); - if (!qmlglobal) - return 0; + Scope scope(v4); + QV4::Scoped<QmlContextWrapper> c(scope, v4->qmlContextObject()->getPointer()->as<QmlContextWrapper>()); - QmlContextWrapper *c = qmlglobal->as<QmlContextWrapper>(); - return c ? c->getContext() : 0; + return !!c ? c->getContext() : 0; } QQmlContextData *QmlContextWrapper::getContext(const Value &value) { - Object *o = value.asObject(); - QmlContextWrapper *c = o ? o->as<QmlContextWrapper>() : 0; - if (!c) + QV4::ExecutionEngine *v4 = value.engine(); + if (!v4) return 0; - return c ? c->getContext():0; + Scope scope(v4); + QV4::Scoped<QmlContextWrapper> c(scope, value.as<QmlContextWrapper>()); + + return !!c ? c->getContext():0; } void QmlContextWrapper::takeContextOwnership(const Value &qmlglobal) diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 5dcc807ab0..5e7116e271 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -519,10 +519,11 @@ QV4::ReturnedValue QQmlLocaleData::method_get_textDirection(QV4::SimpleCallConte QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::SimpleCallContext *ctx) { + QV4::Scope scope(ctx); QLocale locale = getThisLocale(ctx); QList<Qt::DayOfWeek> days = locale.weekdays(); - QV4::ArrayObject *result = ctx->engine->newArrayObject(); + QV4::Scoped<QV4::ArrayObject> result(scope, ctx->engine->newArrayObject()); result->arrayReserve(days.size()); result->arrayDataLen = days.size(); for (int i = 0; i < days.size(); ++i) { @@ -533,21 +534,22 @@ QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::SimpleCallContext *c } result->setArrayLengthUnchecked(days.size()); - return QV4::Value::fromObject(result).asReturnedValue(); + return result.asReturnedValue(); } QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::SimpleCallContext *ctx) { + QV4::Scope scope(ctx); QLocale locale = getThisLocale(ctx); QStringList langs = locale.uiLanguages(); - QV4::ArrayObject *result = ctx->engine->newArrayObject(); + QV4::Scoped<QV4::ArrayObject> result(scope, ctx->engine->newArrayObject()); result->arrayReserve(langs.size()); result->arrayDataLen = langs.size(); for (int i = 0; i < langs.size(); ++i) result->arrayData[i].value = QV4::Value::fromString(ctx, langs.at(i)); result->setArrayLengthUnchecked(langs.size()); - return QV4::Value::fromObject(result).asReturnedValue(); + return result.asReturnedValue(); } QV4::ReturnedValue QQmlLocaleData::method_currencySymbol(QV4::SimpleCallContext *ctx) diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 488b4a0adf..6739143979 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1245,7 +1245,8 @@ void QQmlVMEMetaObject::allocateVarPropertiesArray() QQmlEngine *qml = qmlEngine(object); assert(qml); QV4::ExecutionEngine *v4 = QV8Engine::getV4(qml->handle()); - varProperties = QV4::Value::fromObject(v4->newArrayObject(metaData->varPropertyCount)); + QV4::Scope scope(v4); + varProperties = QV4::ScopedValue(scope, v4->newArrayObject(metaData->varPropertyCount)); varPropertiesInitialized = true; } diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index a84de5798c..08bbd4c960 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -184,27 +184,29 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringList &list) { QV4::ExecutionEngine *e = QV8Engine::getV4(engine); - QV4::ArrayObject *a = e->newArrayObject(); + QV4::Scope scope(e); + QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject()); int len = list.count(); a->arrayReserve(len); a->arrayDataLen = len; for (int ii = 0; ii < len; ++ii) a->arrayData[ii].value = QV4::Value::fromString(e->newString(list.at(ii))); a->setArrayLengthUnchecked(len); - return QV4::Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariantList &list) { QV4::ExecutionEngine *e = QV8Engine::getV4(engine); - QV4::ArrayObject *a = e->newArrayObject(); + QV4::Scope scope(e); + QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject()); int len = list.count(); a->arrayReserve(len); a->arrayDataLen = len; for (int ii = 0; ii < len; ++ii) a->arrayData[ii].value = QV4::Value::fromReturnedValue(engine->fromVariant(list.at(ii))); a->setArrayLengthUnchecked(len); - return QV4::Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } static QV4::ReturnedValue objectFromVariantMap(QV8Engine *engine, const QVariantMap &map) @@ -308,13 +310,13 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant) // XXX Can this be made more by using Array as a prototype and implementing // directly against QList<QObject*>? const QList<QObject *> &list = *(QList<QObject *>*)ptr; - QV4::ArrayObject *a = m_v4Engine->newArrayObject(); + QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject()); a->arrayReserve(list.count()); a->arrayDataLen = list.count(); for (int ii = 0; ii < list.count(); ++ii) a->arrayData[ii].value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii))); a->setArrayLengthUnchecked(list.count()); - return QV4::Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) { return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr)); } @@ -337,7 +339,7 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant) // + QObjectList // + QList<int> - return QV4::Value::fromObject(m_v4Engine->newVariantObject(variant)).asReturnedValue(); + return QV4::Encode(m_v4Engine->newVariantObject(variant)); } QNetworkAccessManager *QV8Engine::networkAccessManager() @@ -517,13 +519,14 @@ QV4::Value QV8Engine::global() // elements converted to JS, recursively. QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst) { - QV4::ArrayObject *a = m_v4Engine->newArrayObject(); + QV4::Scope scope(m_v4Engine); + QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject()); a->arrayReserve(lst.size()); a->arrayDataLen = lst.size(); for (int i = 0; i < lst.size(); i++) a->arrayData[i].value = QV4::Value::fromReturnedValue(variantToJS(lst.at(i))); a->setArrayLengthUnchecked(lst.size()); - return QV4::Value::fromObject(a).asReturnedValue(); + return a.asReturnedValue(); } // Converts a JS Array object to a QVariantList. @@ -655,7 +658,7 @@ QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data) case QMetaType::QChar: return QV4::Encode((int)(*reinterpret_cast<const QChar*>(data)).unicode()); case QMetaType::QStringList: - return QV4::Value::fromObject(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(data))).asReturnedValue(); + return QV4::Encode(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(data))); case QMetaType::QVariantList: return variantListToJS(*reinterpret_cast<const QVariantList *>(data)); case QMetaType::QVariantMap: @@ -685,7 +688,7 @@ QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data) return QV4::Encode::null(); } else { // Fall back to wrapping in a QVariant. - return QV4::Value::fromObject(m_v4Engine->newVariantObject(QVariant(type, data))).asReturnedValue(); + return QV4::Encode(m_v4Engine->newVariantObject(QVariant(type, data))); } } } |