aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4runtime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4runtime.cpp')
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp304
1 files changed, 80 insertions, 224 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 8f377dd664..5460304e7b 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -176,7 +176,7 @@ struct RuntimeCounters::Data {
}
std::sort(lines.begin(), lines.end(), Line::less);
outs << lines.size() << " counters:" << endl;
- foreach (const Line &line, lines)
+ for (const Line &line : qAsConst(lines))
outs << qSetFieldWidth(10) << line.count << qSetFieldWidth(0)
<< " | " << line.func
<< " | " << pretty(line.tag1)
@@ -252,14 +252,14 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
result->append(QLatin1Char('+'));
result->append(QString::number(decpt - 1));
} else if (decpt <= 0) {
- result->prepend(QString::fromLatin1("0.%1").arg(QString().fill(zero, -decpt)));
+ result->prepend(QLatin1String("0.") + QString(-decpt, zero));
} else if (decpt < result->length()) {
result->insert(decpt, dot);
} else {
- result->append(QString().fill(zero, decpt - result->length()));
+ result->append(QString(decpt - result->length(), zero));
}
- if (sign)
+ if (sign && num)
result->prepend(QLatin1Char('-'));
return;
@@ -387,7 +387,7 @@ QV4::ReturnedValue Runtime::method_in(ExecutionEngine *engine, const Value &left
double RuntimeHelpers::stringToNumber(const QString &string)
{
- QString s = string.trimmed();
+ const QStringRef s = QStringRef(&string).trimmed();
if (s.startsWith(QLatin1String("0x")) || s.startsWith(QLatin1String("0X")))
return s.toLong(0, 16);
bool ok;
@@ -438,9 +438,9 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH
ScopedValue conv(scope, object->get(meth1));
if (FunctionObject *o = conv->as<FunctionObject>()) {
- ScopedValue r(scope, o->call(callData));
- if (r->isPrimitive())
- return r->asReturnedValue();
+ o->call(scope, callData);
+ if (scope.result.isPrimitive())
+ return scope.result.asReturnedValue();
}
if (engine->hasException)
@@ -448,9 +448,9 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH
conv = object->get(meth2);
if (FunctionObject *o = conv->as<FunctionObject>()) {
- ScopedValue r(scope, o->call(callData));
- if (r->isPrimitive())
- return r->asReturnedValue();
+ o->call(scope, callData);
+ if (scope.result.isPrimitive())
+ return scope.result.asReturnedValue();
}
return engine->throwTypeError();
@@ -555,7 +555,7 @@ QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const Valu
if (!pright->stringValue()->d()->length())
return pleft->asReturnedValue();
MemoryManager *mm = engine->memoryManager;
- return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue();
+ return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d(), true))->asReturnedValue();
}
double x = RuntimeHelpers::toNumber(pleft);
double y = RuntimeHelpers::toNumber(pright);
@@ -572,7 +572,7 @@ QV4::ReturnedValue Runtime::method_addString(ExecutionEngine *engine, const Valu
if (!right.stringValue()->d()->length())
return left.asReturnedValue();
MemoryManager *mm = engine->memoryManager;
- return (mm->alloc<String>(mm, left.stringValue()->d(), right.stringValue()->d()))->asReturnedValue();
+ return (mm->alloc<String>(mm, left.stringValue()->d(), right.stringValue()->d(), true))->asReturnedValue();
}
Scope scope(engine);
@@ -590,7 +590,7 @@ QV4::ReturnedValue Runtime::method_addString(ExecutionEngine *engine, const Valu
if (!pright->stringValue()->d()->length())
return pleft->asReturnedValue();
MemoryManager *mm = engine->memoryManager;
- return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue();
+ return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d(), true))->asReturnedValue();
}
void Runtime::method_setProperty(ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)
@@ -943,10 +943,13 @@ ReturnedValue Runtime::method_callGlobalLookup(ExecutionEngine *engine, uint ind
return engine->throwTypeError();
ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
- if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval()))
- return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true);
+ if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) {
+ static_cast<EvalFunction *>(o.getPointer())->evalCall(scope, callData, true);
+ } else {
+ o->call(scope, callData);
+ }
- return o->call(callData);
+ return scope.result.asReturnedValue();
}
@@ -974,33 +977,38 @@ ReturnedValue Runtime::method_callActivationProperty(ExecutionEngine *engine, in
}
if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) {
- return static_cast<EvalFunction *>(o)->evalCall(callData, true);
+ static_cast<EvalFunction *>(o)->evalCall(scope, callData, true);
+ } else {
+ o->call(scope, callData);
}
- return o->call(callData);
+ return scope.result.asReturnedValue();
}
ReturnedValue Runtime::method_callQmlScopeObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData)
{
Scope scope(engine);
- ScopedFunctionObject o(scope, method_getQmlScopeObjectProperty(engine, callData->thisObject, propertyIndex));
+ ScopedFunctionObject o(scope, method_getQmlScopeObjectProperty(engine, callData->thisObject, propertyIndex, /*captureRequired*/true));
if (!o) {
QString error = QStringLiteral("Property '%1' of scope object is not a function").arg(propertyIndex);
return engine->throwTypeError(error);
}
- return o->call(callData);
+
+ o->call(scope, callData);
+ return scope.result.asReturnedValue();
}
ReturnedValue Runtime::method_callQmlContextObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData)
{
Scope scope(engine);
- ScopedFunctionObject o(scope, method_getQmlContextObjectProperty(engine, callData->thisObject, propertyIndex));
+ ScopedFunctionObject o(scope, method_getQmlContextObjectProperty(engine, callData->thisObject, propertyIndex, /*captureRequired*/true));
if (!o) {
QString error = QStringLiteral("Property '%1' of context object is not a function").arg(propertyIndex);
return engine->throwTypeError(error);
}
- return o->call(callData);
+ o->call(scope, callData);
+ return scope.result.asReturnedValue();
}
ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
@@ -1022,12 +1030,14 @@ ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, int nameInde
}
ScopedFunctionObject o(scope, baseObject->get(name));
- if (!o) {
+ if (o) {
+ o->call(scope, callData);
+ return scope.result.asReturnedValue();
+ } else {
QString error = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQStringNoThrow());
return engine->throwTypeError(error);
}
- return o->call(callData);
}
ReturnedValue Runtime::method_callPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
@@ -1035,10 +1045,13 @@ ReturnedValue Runtime::method_callPropertyLookup(ExecutionEngine *engine, uint i
Lookup *l = engine->current->lookups + index;
Value v;
v = l->getter(l, engine, callData->thisObject);
- if (!v.isObject())
+ if (v.isObject()) {
+ Scope scope(engine);
+ v.objectValue()->call(scope, callData);
+ return scope.result.asReturnedValue();
+ } else {
return engine->throwTypeError();
-
- return v.objectValue()->call(callData);
+ }
}
ReturnedValue Runtime::method_callElement(ExecutionEngine *engine, const Value &index, CallData *callData)
@@ -1055,7 +1068,8 @@ ReturnedValue Runtime::method_callElement(ExecutionEngine *engine, const Value &
if (!o)
return engine->throwTypeError();
- return o->call(callData);
+ o->call(scope, callData);
+ return scope.result.asReturnedValue();
}
ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &func, CallData *callData)
@@ -1063,7 +1077,9 @@ ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &fu
if (!func.isObject())
return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
- return func.objectValue()->call(callData);
+ Scope scope(engine);
+ func.objectValue()->call(scope, callData);
+ return scope.result.asReturnedValue();
}
@@ -1074,10 +1090,12 @@ ReturnedValue Runtime::method_constructGlobalLookup(ExecutionEngine *engine, uin
Lookup *l = engine->current->lookups + index;
ScopedObject f(scope, l->globalGetter(l, engine));
- if (!f)
+ if (f) {
+ f->construct(scope, callData);
+ return scope.result.asReturnedValue();
+ } else {
return engine->throwTypeError();
-
- return f->construct(callData);
+ }
}
@@ -1093,7 +1111,8 @@ ReturnedValue Runtime::method_constructActivationProperty(ExecutionEngine *engin
if (!f)
return engine->throwTypeError();
- return f->construct(callData);
+ f->construct(scope, callData);
+ return scope.result.asReturnedValue();
}
ReturnedValue Runtime::method_constructValue(ExecutionEngine *engine, const Value &func, CallData *callData)
@@ -1102,7 +1121,9 @@ ReturnedValue Runtime::method_constructValue(ExecutionEngine *engine, const Valu
if (!f)
return engine->throwTypeError();
- return f->construct(callData);
+ Scope scope(engine);
+ f->construct(scope, callData);
+ return scope.result.asReturnedValue();
}
ReturnedValue Runtime::method_constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
@@ -1114,10 +1135,13 @@ ReturnedValue Runtime::method_constructProperty(ExecutionEngine *engine, int nam
return Encode::undefined();
ScopedObject f(scope, thisObject->get(name));
- if (!f)
+ if (f) {
+ Scope scope(engine);
+ f->construct(scope, callData);
+ return scope.result.asReturnedValue();
+ } else {
return engine->throwTypeError();
-
- return f->construct(callData);
+ }
}
ReturnedValue Runtime::method_constructPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
@@ -1125,10 +1149,14 @@ ReturnedValue Runtime::method_constructPropertyLookup(ExecutionEngine *engine, u
Lookup *l = engine->current->lookups + index;
Value v;
v = l->getter(l, engine, callData->thisObject);
- if (!v.isObject())
+ if (v.isObject()) {
+ Scope scope(engine);
+ ScopedValue result(scope);
+ v.objectValue()->construct(scope, callData);
+ return scope.result.asReturnedValue();
+ } else {
return engine->throwTypeError();
-
- return v.objectValue()->construct(callData);
+ }
}
@@ -1181,7 +1209,7 @@ QV4::ReturnedValue Runtime::method_typeofName(ExecutionEngine *engine, int nameI
ReturnedValue Runtime::method_typeofScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
{
Scope scope(engine);
- ScopedValue prop(scope, method_getQmlScopeObjectProperty(engine, context, propertyIndex));
+ ScopedValue prop(scope, method_getQmlScopeObjectProperty(engine, context, propertyIndex, /*captureRequired*/true));
if (scope.engine->hasException)
return Encode::undefined();
return method_typeofValue(engine, prop);
@@ -1190,7 +1218,7 @@ ReturnedValue Runtime::method_typeofScopeObjectProperty(ExecutionEngine *engine,
ReturnedValue Runtime::method_typeofContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
{
Scope scope(engine);
- ScopedValue prop(scope, method_getQmlContextObjectProperty(engine, context, propertyIndex));
+ ScopedValue prop(scope, method_getQmlContextObjectProperty(engine, context, propertyIndex, /*captureRequired*/true));
if (scope.engine->hasException)
return Encode::undefined();
return method_typeofValue(engine, prop);
@@ -1234,19 +1262,19 @@ ReturnedValue Runtime::method_unwindException(ExecutionEngine *engine)
void Runtime::method_pushWithScope(const Value &o, ExecutionEngine *engine)
{
engine->pushContext(engine->currentContext->newWithContext(o.toObject(engine)));
- Q_ASSERT(engine->jsStackTop = engine->currentContext + 2);
+ Q_ASSERT(engine->jsStackTop == engine->currentContext + 2);
}
void Runtime::method_pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex)
{
ExecutionContext *c = engine->currentContext;
engine->pushContext(c->newCatchContext(c->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0)));
- Q_ASSERT(engine->jsStackTop = engine->currentContext + 2);
+ Q_ASSERT(engine->jsStackTop == engine->currentContext + 2);
}
void Runtime::method_popScope(ExecutionEngine *engine)
{
- Q_ASSERT(engine->jsStackTop = engine->currentContext + 2);
+ Q_ASSERT(engine->jsStackTop == engine->currentContext + 2);
engine->popContext();
engine->jsStackTop -= 2;
}
@@ -1415,116 +1443,6 @@ ReturnedValue Runtime::method_getQmlQObjectProperty(ExecutionEngine *engine, con
return QV4::QObjectWrapper::getProperty(scope.engine, wrapper->object(), propertyIndex, captureRequired);
}
-template <typename PropertyType>
-static inline PropertyType getQObjectProperty(QObject *object, ExecutionEngine *engine, QQmlAccessors *accessors, int coreIndex, int notifyIndex)
-{
- PropertyType t;
- accessors->read(object, &t);
- if (notifyIndex != -1) {
- QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
- if (ep && ep->propertyCapture) {
- if (accessors->notifier) {
- QQmlNotifier *n = nullptr;
- accessors->notifier(object, &n);
- if (n) {
- ep->propertyCapture->captureProperty(n);
- }
- } else {
- ep->propertyCapture->captureProperty(object, coreIndex, notifyIndex);
- }
- }
- }
-
- return t;
-}
-
-ReturnedValue Runtime::method_accessQObjectQRealProperty(ExecutionEngine *engine,
- const Value &object,
- QQmlAccessors *accessors, int coreIndex,
- int notifyIndex)
-{
- auto casted = object.as<QObjectWrapper>();
- QObject *o = casted ? casted->object() : nullptr;
- if (Q_LIKELY(o)) {
- return QV4::Encode(getQObjectProperty<qreal>(o, engine, accessors, coreIndex, notifyIndex));
- }
- engine->throwTypeError(QStringLiteral("Cannot read property of null"));
- return Encode::undefined();
-}
-
-ReturnedValue Runtime::method_accessQObjectQObjectProperty(ExecutionEngine *engine,
- const Value &object,
- QQmlAccessors *accessors, int coreIndex,
- int notifyIndex)
-{
- auto casted = object.as<QObjectWrapper>();
- QObject *o = casted ? casted->object() : nullptr;
- if (Q_LIKELY(o)) {
- return QV4::QObjectWrapper::wrap(engine, getQObjectProperty<QObject *>(o, engine, accessors,
- coreIndex,
- notifyIndex));
- }
-
- engine->throwTypeError(QStringLiteral("Cannot read property of null"));
- return Encode::undefined();
-}
-
-ReturnedValue Runtime::method_accessQObjectIntProperty(ExecutionEngine *engine, const Value &object,
- QQmlAccessors *accessors, int coreIndex,
- int notifyIndex)
-{
- auto casted = object.as<QObjectWrapper>();
- QObject *o = casted ? casted->object() : nullptr;
- if (Q_LIKELY(o)) {
- return QV4::Encode(getQObjectProperty<int>(o, engine, accessors, coreIndex, notifyIndex));
- }
- engine->throwTypeError(QStringLiteral("Cannot read property of null"));
- return Encode::undefined();
-}
-
-ReturnedValue Runtime::method_accessQObjectBoolProperty(ExecutionEngine *engine, const Value &object,
- QQmlAccessors *accessors, int coreIndex,
- int notifyIndex)
-{
- auto casted = object.as<QObjectWrapper>();
- QObject *o = casted ? casted->object() : nullptr;
- if (Q_LIKELY(o)) {
- return QV4::Encode(getQObjectProperty<bool>(o, engine, accessors, coreIndex, notifyIndex));
- }
- engine->throwTypeError(QStringLiteral("Cannot read property of null"));
- return Encode::undefined();
-}
-
-ReturnedValue Runtime::method_accessQObjectQStringProperty(ExecutionEngine *engine,
- const Value &object,
- QQmlAccessors *accessors, int coreIndex,
- int notifyIndex)
-{
- auto casted = object.as<QObjectWrapper>();
- QObject *o = casted ? casted->object() : nullptr;
- if (Q_LIKELY(o)) {
- return QV4::Encode(engine->newString(getQObjectProperty<QString>(o, engine, accessors,
- coreIndex, notifyIndex)));
- }
- engine->throwTypeError(QStringLiteral("Cannot read property of null"));
- return Encode::undefined();
-}
-
-ReturnedValue Runtime::method_accessQmlScopeObjectQObjectProperty(const Value &context,
- QQmlAccessors *accessors)
-{
-#ifndef V4_BOOTSTRAP
- const QmlContext &c = static_cast<const QmlContext &>(context);
- QObject *rv = 0;
- accessors->read(c.d()->qml->scopeObject, &rv);
- return QV4::QObjectWrapper::wrap(c.engine(), rv);
-#else
- Q_UNUSED(context);
- Q_UNUSED(accessors);
- return QV4::Encode::undefined();
-#endif
-}
-
QV4::ReturnedValue Runtime::method_getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)
{
QObject *scopeObject = engine->qmlScopeObject();
@@ -1535,16 +1453,16 @@ QV4::ReturnedValue Runtime::method_getQmlAttachedProperty(ExecutionEngine *engin
return QV4::QObjectWrapper::getProperty(engine, attachedObject, propertyIndex, /*captureRequired*/true);
}
-ReturnedValue Runtime::method_getQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
+ReturnedValue Runtime::method_getQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->scopeObject, propertyIndex, false);
+ return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->scopeObject, propertyIndex, captureRequired);
}
-ReturnedValue Runtime::method_getQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
+ReturnedValue Runtime::method_getQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->context->contextObject, propertyIndex, false);
+ return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->context->contextObject, propertyIndex, captureRequired);
}
ReturnedValue Runtime::method_getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
@@ -1798,6 +1716,8 @@ ReturnedValue Runtime::method_ushr(const Value &left, const Value &right)
return Encode(res);
}
+#endif // V4_BOOTSTRAP
+
ReturnedValue Runtime::method_greaterThan(const Value &left, const Value &right)
{
TRACE2(left, right);
@@ -1906,70 +1826,6 @@ Bool Runtime::method_toBoolean(const Value &value)
return value.toBoolean();
}
-ReturnedValue Runtime::method_accessQmlScopeObjectQRealProperty(const Value &context,
- QQmlAccessors *accessors)
-{
-#ifndef V4_BOOTSTRAP
- const QmlContext &c = static_cast<const QmlContext &>(context);
- qreal rv = 0;
- accessors->read(c.d()->qml->scopeObject, &rv);
- return QV4::Encode(rv);
-#else
- Q_UNUSED(context);
- Q_UNUSED(accessors);
- return QV4::Encode::undefined();
-#endif
-}
-
-ReturnedValue Runtime::method_accessQmlScopeObjectIntProperty(const Value &context,
- QQmlAccessors *accessors)
-{
-#ifndef V4_BOOTSTRAP
- const QmlContext &c = static_cast<const QmlContext &>(context);
- int rv = 0;
- accessors->read(c.d()->qml->scopeObject, &rv);
- return QV4::Encode(rv);
-#else
- Q_UNUSED(context);
- Q_UNUSED(accessors);
- return QV4::Encode::undefined();
-#endif
-}
-
-ReturnedValue Runtime::method_accessQmlScopeObjectBoolProperty(const Value &context,
- QQmlAccessors *accessors)
-{
-#ifndef V4_BOOTSTRAP
- const QmlContext &c = static_cast<const QmlContext &>(context);
- bool rv = false;
- accessors->read(c.d()->qml->scopeObject, &rv);
- return QV4::Encode(rv);
-#else
- Q_UNUSED(context);
- Q_UNUSED(accessors);
- return QV4::Encode::undefined();
-#endif
-}
-
-ReturnedValue Runtime::method_accessQmlScopeObjectQStringProperty(ExecutionEngine *engine,
- const Value &context,
- QQmlAccessors *accessors)
-{
-#ifndef V4_BOOTSTRAP
- const QmlContext &c = static_cast<const QmlContext &>(context);
- QString rv;
- accessors->read(c.d()->qml->scopeObject, &rv);
- return QV4::Encode(engine->newString(rv));
-#else
- Q_UNUSED(engine);
- Q_UNUSED(context);
- Q_UNUSED(accessors);
- return QV4::Encode::undefined();
-#endif
-}
-
-#endif // V4_BOOTSTRAP
-
} // namespace QV4
QT_END_NAMESPACE