diff options
Diffstat (limited to 'src/qml/jsruntime')
| -rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 1 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 12 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 12 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4globalobject.cpp | 18 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 4 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 4 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4sequenceobject.cpp | 3 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4urlobject.cpp | 31 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 3 |
9 files changed, 53 insertions, 35 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 05e73d0295..e4170b459e 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -576,6 +576,7 @@ ReturnedValue ArrayPrototype::method_join(const FunctionObject *functionObject, const Value *thisObject, const Value *argv, int argc) { Scope scope(functionObject); + CHECK_STACK_LIMITS(scope.engine) ScopedObject instance(scope, thisObject->toObject(scope.engine)); if (!instance) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index a807cc42df..3bb140a4fd 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -2453,9 +2453,12 @@ bool convertToIterable(QMetaType metaType, void *data, Source *sequence) return false; const QMetaType elementMetaType = iterable.valueMetaType(); + QV4::Scope scope(sequence->engine()); + QV4::ScopedValue v(scope); for (qsizetype i = 0, end = sequence->getLength(); i < end; ++i) { QVariant element(elementMetaType); - ExecutionEngine::metaTypeFromJS(sequence->get(i), elementMetaType, element.data()); + v = sequence->get(i); + ExecutionEngine::metaTypeFromJS(v, elementMetaType, element.data()); iterable.addValue(element, QSequentialIterable::AtEnd); } return true; @@ -2515,9 +2518,12 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi QByteArray result; const qint64 length = ao->getLength(); result.reserve(length); + QV4::Scope scope(ao->engine()); + QV4::ScopedValue v(scope); for (qint64 i = 0; i < length; ++i) { char value = 0; - ExecutionEngine::metaTypeFromJS(ao->get(i), QMetaType::fromType<char>(), &value); + v = ao->get(i); + ExecutionEngine::metaTypeFromJS(v, QMetaType::fromType<char>(), &value); result.push_back(value); } *reinterpret_cast<QByteArray*>(data) = std::move(result); @@ -2778,7 +2784,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value &value, QMetaType metaType, voi *reinterpret_cast<void* *>(data) = nullptr; return true; } else if (metaType == QMetaType::fromType<QJSValue>()) { - QJSValuePrivate::setValue(reinterpret_cast<QJSValue*>(data), value.asReturnedValue()); + QJSValuePrivate::setValue(reinterpret_cast<QJSValue*>(data), value); return true; } else if (metaType == QMetaType::fromType<QJSPrimitiveValue>()) { *reinterpret_cast<QJSPrimitiveValue *>(data) = createPrimitive(&value); diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index dc24f2d2a9..aed1a84f63 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -695,8 +695,10 @@ const Value *ExecutableCompilationUnit::resolveExportRecursively( return fragment.native; ScopedObject o(scope, dependentModule.native); - if (o) - return engine->registerNativeModule(request, o->get(importName)); + if (o) { + ScopedValue nativeModule(scope, o->get(importName)); + return engine->registerNativeModule(request, nativeModule); + } return nullptr; } else { @@ -727,8 +729,10 @@ const Value *ExecutableCompilationUnit::resolveExportRecursively( resolution = fragment.native; } else { ScopedObject o(scope, dependentModule.native); - if (o) - resolution = engine->registerNativeModule(request, o->get(exportName)); + if (o) { + ScopedValue nativeModule(scope, o->get(exportName)); + resolution = engine->registerNativeModule(request, nativeModule); + } } } } diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 32e93cedb4..ec74fbceed 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -301,15 +301,15 @@ ReturnedValue EvalFunction::evalCall(const Value *, const Value *argv, int argc, return Encode::undefined(); ExecutionEngine *v4 = engine(); - bool isStrict = v4->currentStackFrame->v4Function->isStrict(); + const Function *v4Function = v4->currentStackFrame + ? v4->currentStackFrame->v4Function + : v4->globalCode; + const bool isStrict = v4Function && v4Function->isStrict(); Scope scope(v4); - ScopedContext ctx(scope, v4->currentContext()); - if (!directCall) { - // the context for eval should be the global scope - ctx = v4->scriptContext(); - } + // In case of !directCall, the context for eval should be the global scope + ScopedContext ctx(scope, directCall ? v4->currentContext() : v4->scriptContext()); String *scode = argv[0].stringValue(); if (!scode) @@ -330,14 +330,14 @@ ReturnedValue EvalFunction::evalCall(const Value *, const Value *argv, int argc, return Encode::undefined(); function->kind = Function::Eval; + ScopedValue thisObject(scope, directCall + ? scope.engine->currentStackFrame->thisObject() + : scope.engine->globalObject->asReturnedValue()); if (function->isStrict() || isStrict) { ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function)); - ScopedValue thisObject(scope, directCall ? scope.engine->currentStackFrame->thisObject() : scope.engine->globalObject->asReturnedValue()); return checkedResult(v4, e->call(thisObject, nullptr, 0)); } - ScopedValue thisObject(scope, scope.engine->currentStackFrame->thisObject()); - return checkedResult(v4, function->call(thisObject, nullptr, 0, ctx)); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 0851b2f5ab..2071e39520 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -42,7 +42,9 @@ void Object::setInternalClass(Heap::InternalClass *ic) for (uint i = 0; i < ic->size; ++i) { // Note that some members might have been deleted. The key may be invalid. const PropertyKey key = ic->nameMap.at(i); - newMembers->set(scope.engine, i, key.isValid() ? get(key) : Encode::undefined()); + // fromReturnedValue is safe, we directly write it through the WriteBarrier + newMembers->set(scope.engine, i, + QV4::Value::fromReturnedValue(key.isValid() ? get(key) : Encode::undefined())); } p->internalClass.set(scope.engine, ic); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index e19c57fd40..6d08764a11 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -2219,7 +2219,9 @@ bool CallArgument::fromValue(QMetaType metaType, ExecutionEngine *engine, const default: if (type == qMetaTypeId<QJSValue>()) { qjsValuePtr = new (&allocData) QJSValue; - QJSValuePrivate::setValue(qjsValuePtr, value.asReturnedValue()); + Scope scope(engine); + ScopedValue v(scope, value); + QJSValuePrivate::setValue(qjsValuePtr, v); return true; } diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 1dd2654382..2cafd9a741 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -709,7 +709,8 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, QMetaType typeHin QV4::ScopedValue v(scope); for (quint32 i = 0; i < quint32(length); ++i) { const QMetaType valueMetaType = priv->typeId; - QVariant variant = ExecutionEngine::toVariant(a->get(i), valueMetaType, false); + QV4::ScopedValue element(scope, a->get(i)); + QVariant variant = ExecutionEngine::toVariant(element, valueMetaType, false); if (valueMetaType == QMetaType::fromType<QVariant>()) { meta->addValueAtEnd(result.data(), &variant); } else { diff --git a/src/qml/jsruntime/qv4urlobject.cpp b/src/qml/jsruntime/qv4urlobject.cpp index 637d033bd4..aa0d47c766 100644 --- a/src/qml/jsruntime/qv4urlobject.cpp +++ b/src/qml/jsruntime/qv4urlobject.cpp @@ -806,7 +806,8 @@ ReturnedValue UrlSearchParamsCtor::virtualCallAsConstructor(const FunctionObject uint len = argArray->getLength(); for (uint i = 0; i < len; i++) { - QV4::Value pair = argArray->get(i); + // safe to user fromReturnedValue: Normal array, which will ensure marking + QV4::Value pair = Value::fromReturnedValue(argArray->get(i)); auto *pairArrayObject = pair.as<ArrayObject>(); if (pairArrayObject == nullptr) { @@ -895,11 +896,14 @@ void UrlSearchParamsObject::initializeParams(ScopedArrayObject& params) for (uint i = 0; i < len; i++) { - QV4::Value pair = params->get(i); + // fromReturnedValue is safe; everything is reachable via params + // so the gc won't collect it; we control params, so there can't be + // any weird proxy magic + QV4::Value pair = Value::fromReturnedValue(params->get(i)); auto *pairArrayObject = pair.as<ArrayObject>(); - QV4::Value key = pairArrayObject->get(uint(0)); - QV4::Value value = pairArrayObject->get(uint(1)); + QV4::Value key = Value::fromReturnedValue(pairArrayObject->get(uint(0))); + QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(uint(1))); scopedKeys->put(i, key); scopedValues->put(i, value); @@ -1014,11 +1018,11 @@ QList<QStringList> UrlSearchParamsObject::params() const uint len = scopedArray->getLength(); for (uint i = 0; i < len; i++) { - QV4::Value pair = scopedArray->get(i); + QV4::Value pair = Value::fromReturnedValue(scopedArray->get(i)); auto *pairArrayObject = pair.as<ArrayObject>(); - QV4::Value key = pairArrayObject->get(uint(0)); - QV4::Value value = pairArrayObject->get(uint(1)); + QV4::Value key = Value::fromReturnedValue(pairArrayObject->get(uint(0))); + QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(uint(1))); result << QStringList { key.toQString(), value.toQString() }; } @@ -1063,10 +1067,11 @@ int UrlSearchParamsObject::indexOf(QString name, int last) const int len = scopedArray->getLength(); for (int i = last + 1; i < len; i++) { - QV4::Value pair = scopedArray->get(i); + // fromReturnedValue is safe, scopedArray is a normal array and takes care of marking + QV4::Value pair = Value::fromReturnedValue(scopedArray->get(i)); auto *pairArrayObject = pair.as<ArrayObject>(); - QV4::Value key = pairArrayObject->get(uint(0)); + QV4::Value key = Value::fromReturnedValue(pairArrayObject->get(uint(0))); if (key.toQString() == name) return i; @@ -1084,10 +1089,10 @@ QString UrlSearchParamsObject::stringAt(int index, int pairIndex) const if (index >= scopedArray->getLength()) return {}; - QV4::Value pair = scopedArray->get(index); + QV4::Value pair = Value::fromReturnedValue(scopedArray->get(index)); auto *pairArrayObject = pair.as<ArrayObject>(); - QV4::Value value = pairArrayObject->get(pairIndex); + QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(pairIndex)); return value.toQString(); } @@ -1101,10 +1106,10 @@ QV4::Heap::String * UrlSearchParamsObject::stringAtRaw(int index, int pairIndex) if (index >= scopedArray->getLength()) return nullptr; - QV4::Value pair = scopedArray->get(index); + QV4::Value pair = Value::fromReturnedValue(scopedArray->get(index)); auto *pairArrayObject = pair.as<ArrayObject>(); - QV4::Value value = pairArrayObject->get(pairIndex); + QV4::Value value = Value::fromReturnedValue(pairArrayObject->get(pairIndex)); return value.as<String>()->d(); } diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 643d6c16a9..36fe261dea 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -38,9 +38,6 @@ struct Q_QML_PRIVATE_EXPORT Value : public StaticValue { using ManagedPtr = Managed *; - Value() = default; - constexpr Value(quint64 val) : StaticValue(val) {} - static constexpr Value fromStaticValue(StaticValue staticValue) { return {staticValue._val}; |
