aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4engine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4engine.cpp')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp95
1 files changed, 66 insertions, 29 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 26f473a7aa..a9284f2e69 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -86,7 +86,9 @@
#include "qv4isel_masm_p.h"
#endif // V4_ENABLE_JIT
+#if QT_CONFIG(qml_interpreter)
#include "qv4isel_moth_p.h"
+#endif
#if USE(PTHREADS)
# include <pthread.h>
@@ -136,8 +138,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
, currentContext(0)
, bumperPointerAllocator(new WTF::BumpPointerAllocator)
, jsStack(new WTF::PageAllocation)
- , debugger(0)
- , profiler(0)
, globalCode(0)
, v8Engine(0)
, argumentsAccessors(0)
@@ -145,6 +145,10 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
, m_engineId(engineSerial.fetchAndAddOrdered(1))
, regExpCache(0)
, m_multiplyWrappedQObjects(0)
+#ifndef QT_NO_QML_DEBUGGER
+ , m_debugger(0)
+ , m_profiler(0)
+#endif
{
if (maxCallDepth == -1) {
bool ok = false;
@@ -158,6 +162,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
MemoryManager::GCBlocker gcBlocker(memoryManager);
if (!factory) {
+#if QT_CONFIG(qml_interpreter)
bool jitDisabled = true;
#ifdef V4_ENABLE_JIT
@@ -178,6 +183,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
"very slow. Visit https://wiki.qt.io/V4 to learn about possible "
"solutions for your platform.");
}
+#else
+ factory = new JIT::ISelFactory;
+#endif
}
iselFactory.reset(factory);
@@ -442,10 +450,12 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
ExecutionEngine::~ExecutionEngine()
{
- delete debugger;
- debugger = 0;
- delete profiler;
- profiler = 0;
+#ifndef QT_NO_QML_DEBUGGER
+ delete m_debugger;
+ m_debugger = 0;
+ delete m_profiler;
+ m_profiler = 0;
+#endif
delete m_multiplyWrappedQObjects;
m_multiplyWrappedQObjects = 0;
delete identifierTable;
@@ -467,23 +477,26 @@ ExecutionEngine::~ExecutionEngine()
delete [] argumentsAccessors;
}
-void ExecutionEngine::setDebugger(Debugging::Debugger *debugger_)
+#ifndef QT_NO_QML_DEBUGGER
+void ExecutionEngine::setDebugger(Debugging::Debugger *debugger)
{
- Q_ASSERT(!debugger);
- debugger = debugger_;
+ Q_ASSERT(!m_debugger);
+ m_debugger = debugger;
}
-void ExecutionEngine::enableProfiler()
+void ExecutionEngine::setProfiler(Profiling::Profiler *profiler)
{
- Q_ASSERT(!profiler);
- profiler = new QV4::Profiling::Profiler(this);
+ Q_ASSERT(!m_profiler);
+ m_profiler = profiler;
}
+#endif // QT_NO_QML_DEBUGGER
void ExecutionEngine::initRootContext()
{
Scope scope(this);
- Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>(sizeof(GlobalContext::Data) + sizeof(CallData)));
- new (r->d()) GlobalContext::Data(this);
+ Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>(
+ sizeof(GlobalContext::Data) + sizeof(CallData)));
+ r->d_unchecked()->init(this);
r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1);
r->d()->callData->tag = QV4::Value::Integer_Type_Internal;
r->d()->callData->argc = 0;
@@ -566,7 +579,7 @@ Heap::ArrayObject *ExecutionEngine::newArrayObject(const Value *values, int leng
if (length) {
size_t size = sizeof(Heap::ArrayData) + (length-1)*sizeof(Value);
Heap::SimpleArrayData *d = scope.engine->memoryManager->allocManaged<SimpleArrayData>(size);
- new (d) Heap::SimpleArrayData;
+ d->init();
d->alloc = length;
d->type = Heap::ArrayData::Simple;
d->offset = 0;
@@ -615,6 +628,13 @@ Heap::DateObject *ExecutionEngine::newDateObject(const QDateTime &dt)
return object->d();
}
+Heap::DateObject *ExecutionEngine::newDateObjectFromTime(const QTime &t)
+{
+ Scope scope(this);
+ Scoped<DateObject> object(scope, memoryManager->allocObject<DateObject>(t));
+ return object->d();
+}
+
Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int flags)
{
bool global = (flags & IR::RegExp::RegExp_Global);
@@ -730,7 +750,7 @@ QQmlContextData *ExecutionEngine::callingQmlContext() const
if (!ctx)
return 0;
- return ctx->qml->context.contextData();
+ return ctx->qml->context->contextData();
}
QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
@@ -906,12 +926,12 @@ ReturnedValue ExecutionEngine::throwError(const Value &value)
QV4::Scope scope(this);
QV4::Scoped<ErrorObject> error(scope, value);
if (!!error)
- exceptionStackTrace = error->d()->stackTrace;
+ exceptionStackTrace = *error->d()->stackTrace;
else
exceptionStackTrace = stackTrace();
- if (debugger)
- debugger->aboutToThrow();
+ if (QV4::Debugging::Debugger *debug = debugger())
+ debug->aboutToThrow();
return Encode::undefined();
}
@@ -969,7 +989,7 @@ ReturnedValue ExecutionEngine::throwReferenceError(const Value &value)
{
Scope scope(this);
ScopedString s(scope, value.toString(this));
- QString msg = s->toQString() + QStringLiteral(" is not defined");
+ QString msg = s->toQString() + QLatin1String(" is not defined");
ScopedObject error(scope, newReferenceErrorObject(msg));
return throwError(error);
}
@@ -993,7 +1013,7 @@ ReturnedValue ExecutionEngine::throwRangeError(const Value &value)
{
Scope scope(this);
ScopedString s(scope, value.toString(this));
- QString msg = s->toQString() + QStringLiteral(" out of range");
+ QString msg = s->toQString() + QLatin1String(" out of range");
ScopedObject error(scope, newRangeErrorObject(msg));
return throwError(error);
}
@@ -1065,7 +1085,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
QV4::Scope scope(e);
if (const QV4::VariantObject *v = value.as<QV4::VariantObject>())
- return v->d()->data;
+ return v->d()->data();
if (typeHint == QVariant::Bool)
return QVariant(value.toBoolean());
@@ -1124,7 +1144,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
if (value.isUndefined())
return QVariant();
if (value.isNull())
- return QVariant(QMetaType::VoidStar, (void *)0);
+ return QVariant::fromValue(nullptr);
if (value.isBoolean())
return value.booleanValue();
if (value.isInteger())
@@ -1139,10 +1159,10 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return str;
}
if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>())
- return ld->d()->locale;
+ return *ld->d()->locale;
if (const QV4::DateObject *d = value.as<DateObject>())
return d->toQDateTime();
- if (const QV4::ArrayBuffer *d = value.as<ArrayBuffer>())
+ if (const ArrayBuffer *d = value.as<ArrayBuffer>())
return d->asByteArray();
// NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)!
@@ -1254,6 +1274,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
case QMetaType::UnknownType:
case QMetaType::Void:
return QV4::Encode::undefined();
+ case QMetaType::Nullptr:
case QMetaType::VoidStar:
return QV4::Encode::null();
case QMetaType::Bool:
@@ -1270,6 +1291,8 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
return QV4::Encode(*reinterpret_cast<const double*>(ptr));
case QMetaType::QString:
return newString(*reinterpret_cast<const QString*>(ptr))->asReturnedValue();
+ case QMetaType::QByteArray:
+ return newArrayBuffer(*reinterpret_cast<const QByteArray*>(ptr))->asReturnedValue();
case QMetaType::Float:
return QV4::Encode(*reinterpret_cast<const float*>(ptr));
case QMetaType::Short:
@@ -1287,7 +1310,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
case QMetaType::QDate:
return QV4::Encode(newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
case QMetaType::QTime:
- return QV4::Encode(newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr))));
+ return QV4::Encode(newDateObjectFromTime(*reinterpret_cast<const QTime *>(ptr)));
case QMetaType::QRegExp:
return QV4::Encode(newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
case QMetaType::QObjectStar:
@@ -1423,6 +1446,7 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
case QMetaType::UnknownType:
case QMetaType::Void:
return QV4::Encode::undefined();
+ case QMetaType::Nullptr:
case QMetaType::VoidStar:
return QV4::Encode::null();
case QMetaType::Bool:
@@ -1446,6 +1470,8 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
return QV4::Encode(*reinterpret_cast<const double*>(data));
case QMetaType::QString:
return newString(*reinterpret_cast<const QString*>(data))->asReturnedValue();
+ case QMetaType::QByteArray:
+ return newArrayBuffer(*reinterpret_cast<const QByteArray*>(data))->asReturnedValue();
case QMetaType::Float:
return QV4::Encode(*reinterpret_cast<const float*>(data));
case QMetaType::Short:
@@ -1507,6 +1533,11 @@ void ExecutionEngine::assertObjectBelongsToEngine(const Heap::Base &baseObject)
Q_UNUSED(baseObject);
}
+void ExecutionEngine::failStackLimitCheck(Scope &scope)
+{
+ scope.result = throwRangeError(QStringLiteral("Maximum call stack size exceeded."));
+}
+
// Converts a JS value to a meta-type.
// data must point to a place that can store a value of the given type.
// Returns true if conversion succeeded, false otherwise.
@@ -1538,6 +1569,12 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
else
*reinterpret_cast<QString*>(data) = value->toQString();
return true;
+ case QMetaType::QByteArray:
+ if (const ArrayBuffer *ab = value->as<ArrayBuffer>())
+ *reinterpret_cast<QByteArray*>(data) = ab->asByteArray();
+ else
+ *reinterpret_cast<QByteArray*>(data) = QByteArray();
+ return true;
case QMetaType::Float:
*reinterpret_cast<float*>(data) = value->toNumber();
return true;
@@ -1662,7 +1699,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
return true;
if (value->as<QV4::VariantObject>() && name.endsWith('*')) {
int valueType = QMetaType::type(name.left(name.size()-1));
- QVariant &var = value->as<QV4::VariantObject>()->d()->data;
+ QVariant &var = value->as<QV4::VariantObject>()->d()->data();
if (valueType == var.userType()) {
// We have T t, T* is requested, so return &t.
*reinterpret_cast<void* *>(data) = var.data();
@@ -1674,7 +1711,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
while (proto) {
bool canCast = false;
if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
- const QVariant &v = vo->d()->data;
+ const QVariant &v = vo->d()->data();
canCast = (type == v.userType()) || (valueType && (valueType == v.userType()));
}
else if (proto->as<QV4::QObjectWrapper>()) {
@@ -1729,7 +1766,7 @@ static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const Value &value)
QV4::Scoped<QV4::VariantObject> v(scope, value);
if (v) {
- QVariant variant = v->d()->data;
+ QVariant variant = v->d()->data();
int type = variant.userType();
if (type == QMetaType::QObjectStar)
return *reinterpret_cast<QObject* const *>(variant.constData());