aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp1
-rw-r--r--src/qml/jsruntime/qv4engine.cpp12
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp12
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4object.cpp4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp4
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp3
-rw-r--r--src/qml/jsruntime/qv4urlobject.cpp31
-rw-r--r--src/qml/jsruntime/qv4value_p.h3
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};