aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules5
-rw-r--r--examples/quick/demos/stocqt/content/StockListModel.qml35
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp15
-rw-r--r--src/plugins/scenegraph/openvg/openvg.pro7
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp5
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h2
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp4
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h2
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgspritenode.h2
-rw-r--r--src/qml/compiler/qv4codegen.cpp4
-rw-r--r--src/qml/compiler/qv4compilationunitmapper.cpp7
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_p.h4
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_unix.cpp5
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_win.cpp4
-rw-r--r--src/qml/compiler/qv4compileddata.cpp7
-rw-r--r--src/qml/compiler/qv4compileddata_p.h18
-rw-r--r--src/qml/compiler/qv4compiler.cpp2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp75
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h2
-rw-r--r--src/qml/compiler/qv4jsir_p.h4
-rw-r--r--src/qml/jit/qv4assembler.cpp31
-rw-r--r--src/qml/jit/qv4assembler_p.h25
-rw-r--r--src/qml/jit/qv4binop.cpp10
-rw-r--r--src/qml/jit/qv4binop_p.h4
-rw-r--r--src/qml/jit/qv4isel_masm.cpp30
-rw-r--r--src/qml/jit/qv4unop.cpp2
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp2
-rw-r--r--src/qml/jsruntime/qv4context.cpp4
-rw-r--r--src/qml/jsruntime/qv4context_p.h70
-rw-r--r--src/qml/jsruntime/qv4engine.cpp7
-rw-r--r--src/qml/jsruntime/qv4engine_p.h10
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4global_p.h2
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h7
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp14
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h388
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h2
-rw-r--r--src/qml/jsruntime/qv4script_p.h2
-rw-r--r--src/qml/jsruntime/qv4value_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp162
-rw-r--r--src/qml/memory/qv4heap_p.h6
-rw-r--r--src/qml/memory/qv4mm.cpp16
-rw-r--r--src/qml/memory/qv4mmdefs_p.h28
-rw-r--r--src/qml/qml/qqmlmetatype.cpp12
-rw-r--r--src/qml/qml/qqmltypeloader.cpp114
-rw-r--r--src/qml/qml/qqmltypeloader_p.h31
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
-rw-r--r--src/quick/items/qquickevents.cpp8
-rw-r--r--src/quick/items/qquickflickable.cpp6
-rw-r--r--src/quick/items/qquickshadereffect.cpp2
-rw-r--r--src/quick/items/qquickshadereffect_p.h2
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp2
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations (renamed from tests/manual/v4/TestExpectations)0
-rw-r--r--tests/auto/qml/ecmascripttests/ecmascripttests.pro20
m---------tests/auto/qml/ecmascripttests/test2620
-rwxr-xr-xtests/auto/qml/ecmascripttests/test262.py (renamed from tests/manual/v4/test262.py)19
-rw-r--r--tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp77
-rw-r--r--tests/auto/qml/qml.pro3
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp2
-rw-r--r--tests/auto/qml/qmlmin/tst_qmlmin.cpp1
-rw-r--r--tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp28
-rw-r--r--tests/auto/qml/v4misc/tst_v4misc.cpp10
-rw-r--r--tests/auto/qmltest/BLACKLIST1
-rw-r--r--tests/auto/toolsupport/tst_toolsupport.cpp4
-rw-r--r--tests/benchmarks/qml/holistic/testtypes.h1
-rw-r--r--tests/manual/scenegraph_lancelot/scenegrabber/main.cpp5
m---------tests/manual/v4/test2620
-rw-r--r--tests/manual/v4/tests.pro15
-rw-r--r--tools/qml/main.cpp2
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp4
-rw-r--r--tools/qmljs/qmljs.cpp2
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp1
-rw-r--r--tools/qmlscene/main.cpp1
74 files changed, 794 insertions, 618 deletions
diff --git a/.gitmodules b/.gitmodules
index 881629497e..c9561f396d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,3 @@
-[submodule "tests/manual/v4/test262"]
- path = tests/manual/v4/test262
+[submodule "tests/auto/qml/ecmascripttests/test262"]
+ path = tests/auto/qml/ecmascripttests/test262
url = ../qtdeclarative-testsuites.git
- update = none
diff --git a/examples/quick/demos/stocqt/content/StockListModel.qml b/examples/quick/demos/stocqt/content/StockListModel.qml
index 9b48124bda..02ece32a49 100644
--- a/examples/quick/demos/stocqt/content/StockListModel.qml
+++ b/examples/quick/demos/stocqt/content/StockListModel.qml
@@ -82,27 +82,28 @@ ListModel {
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.LOADING || xhr.readyState === XMLHttpRequest.DONE) {
var records = xhr.responseText.split('\n');
+ var unknown = "n/a";
+ set(index, {"value": unknown, "change": unknown, "changePercentage": unknown});
if (records.length > 0 && xhr.status == 200) {
var r = records[1].split(',');
var today = parseFloat(r[4]);
- setProperty(index, "value", today.toFixed(2));
+ if (!isNaN(today))
+ setProperty(index, "value", today.toFixed(2));
+ if (records.length > 2) {
+ r = records[2].split(',');
+ var yesterday = parseFloat(r[4]);
+ var change = today - yesterday;
+ if (change >= 0.0)
+ setProperty(index, "change", "+" + change.toFixed(2));
+ else
+ setProperty(index, "change", change.toFixed(2));
- r = records[2].split(',');
- var yesterday = parseFloat(r[4]);
- var change = today - yesterday;
- if (change >= 0.0)
- setProperty(index, "change", "+" + change.toFixed(2));
- else
- setProperty(index, "change", change.toFixed(2));
-
- var changePercentage = (change / yesterday) * 100.0;
- if (changePercentage >= 0.0)
- setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%");
- else
- setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%");
- } else {
- var unknown = "n/a";
- set(index, {"value": unknown, "change": unknown, "changePercentage": unknown});
+ var changePercentage = (change / yesterday) * 100.0;
+ if (changePercentage >= 0.0)
+ setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%");
+ else
+ setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%");
+ }
}
}
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 5d2e754057..b4b95f6713 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -95,7 +95,7 @@ QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeType
QV4::ScopedContext it(scope, sctxt);
for (; it; it = it->d()->outer)
- types.append(it->d()->type);
+ types.append(QV4::Heap::ExecutionContext::ContextType(it->d()->type));
return types;
}
@@ -187,10 +187,19 @@ const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::Execution
case QV4::Value::Integer_Type:
dict.insert(valueKey, value->integerValue());
return 0;
- default: // double
- dict.insert(valueKey, value->doubleValue());
+ default: {// double
+ const double val = value->doubleValue();
+ if (qIsFinite(val))
+ dict.insert(valueKey, val);
+ else if (qIsNaN(val))
+ dict.insert(valueKey, QStringLiteral("NaN"));
+ else if (val < 0)
+ dict.insert(valueKey, QStringLiteral("-Infinity"));
+ else
+ dict.insert(valueKey, QStringLiteral("Infinity"));
return 0;
}
+ }
}
QJsonObject QV4DataCollector::lookupRef(Ref ref, bool deep)
diff --git a/src/plugins/scenegraph/openvg/openvg.pro b/src/plugins/scenegraph/openvg/openvg.pro
index 6d5b190b37..43c2636343 100644
--- a/src/plugins/scenegraph/openvg/openvg.pro
+++ b/src/plugins/scenegraph/openvg/openvg.pro
@@ -31,7 +31,6 @@ HEADERS += \
qsgopenvghelpers.h \
qsgopenvgfontglyphcache.h \
qsgopenvgpainternode.h \
- qsgopenvgspritenode.h \
qsgopenvgrenderable.h \
qopenvgoffscreensurface.h
@@ -52,6 +51,10 @@ SOURCES += \
qsgopenvghelpers.cpp \
qsgopenvgfontglyphcache.cpp \
qsgopenvgpainternode.cpp \
- qsgopenvgspritenode.cpp \
qsgopenvgrenderable.cpp \
qopenvgoffscreensurface.cpp
+
+qtConfig(quick-sprite) {
+ HEADERS += qsgopenvgspritenode.h
+ SOURCES += qsgopenvgspritenode.cpp
+}
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
index 41fce7c7fc..76ebb7c4ee 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
@@ -45,7 +45,9 @@
#include "qsgopenvgglyphnode_p.h"
#include "qsgopenvgfontglyphcache.h"
#include "qsgopenvgpainternode.h"
+#if QT_CONFIG(quick_sprite)
#include "qsgopenvgspritenode.h"
+#endif
#include "qopenvgcontext_p.h"
@@ -171,11 +173,12 @@ int QSGOpenVGRenderContext::maxTextureSize() const
return qMin(width, height);
}
-
+#if QT_CONFIG(quick_sprite)
QSGSpriteNode *QSGOpenVGContext::createSpriteNode()
{
return new QSGOpenVGSpriteNode();
}
+#endif
QSGRendererInterface *QSGOpenVGContext::rendererInterface(QSGRenderContext *renderContext)
{
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h
index fa9939a253..31a1e8643f 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext_p.h
@@ -95,7 +95,9 @@ public:
QSurfaceFormat defaultSurfaceFormat() const override;
QSGInternalRectangleNode *createInternalRectangleNode() override;
QSGInternalImageNode *createInternalImageNode() override;
+#if QT_CONFIG(quick_sprite)
QSGSpriteNode *createSpriteNode() override;
+#endif
QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext) override;
};
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
index 8aa179f705..41606c653a 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.cpp
@@ -43,7 +43,9 @@
#include "qsgopenvgpublicnodes.h"
#include "qsgopenvgglyphnode_p.h"
#include "qsgopenvgpainternode.h"
+#if QT_CONFIG(quick_sprite)
#include "qsgopenvgspritenode.h"
+#endif
#include "qsgopenvgrenderable.h"
#include "qopenvgcontext_p.h"
@@ -209,6 +211,7 @@ void QSGOpenVGNodeVisitor::endVisit(QSGRootNode *)
{
}
+#if QT_CONFIG(quick_sprite)
bool QSGOpenVGNodeVisitor::visit(QSGSpriteNode *node)
{
renderRenderableNode(static_cast<QSGOpenVGSpriteNode*>(node));
@@ -218,6 +221,7 @@ bool QSGOpenVGNodeVisitor::visit(QSGSpriteNode *node)
void QSGOpenVGNodeVisitor::endVisit(QSGSpriteNode *)
{
}
+#endif
bool QSGOpenVGNodeVisitor::visit(QSGRenderNode *)
{
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h
index 4805d63024..c6461ca67d 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h
+++ b/src/plugins/scenegraph/openvg/qsgopenvgnodevisitor.h
@@ -73,8 +73,10 @@ public:
void endVisit(QSGGlyphNode *) override;
bool visit(QSGRootNode *) override;
void endVisit(QSGRootNode *) override;
+#if QT_CONFIG(quick_sprite)
bool visit(QSGSpriteNode *) override;
void endVisit(QSGSpriteNode *) override;
+#endif
bool visit(QSGRenderNode *) override;
void endVisit(QSGRenderNode *) override;
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h
index 3ade2ef8ad..d47b389a0b 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h
+++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h
@@ -43,6 +43,8 @@
#include <private/qsgadaptationlayer_p.h>
#include "qsgopenvgrenderable.h"
+QT_REQUIRE_CONFIG(quick_sprite);
+
QT_BEGIN_NAMESPACE
class QSGOpenVGTexture;
class QSGOpenVGSpriteNode : public QSGSpriteNode, public QSGOpenVGRenderable
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 2c1b5c57cc..a10c0730bf 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1485,7 +1485,7 @@ IR::Expr *Codegen::identifier(const QString &name, int line, int col)
IR::Function *f = _function;
while (f && e->parent) {
- if (f->insideWithOrCatch || (f->isNamedExpression && f->name == name))
+ if (f->insideWithOrCatch || (f->isNamedExpression && QStringRef(f->name) == name))
return _block->NAME(name, line, col);
int index = e->findMember(name);
@@ -1496,7 +1496,7 @@ IR::Expr *Codegen::identifier(const QString &name, int line, int col)
al->isArgumentsOrEval = true;
return al;
}
- const int argIdx = f->indexOfArgument(&name);
+ const int argIdx = f->indexOfArgument(QStringRef(&name));
if (argIdx != -1)
return _block->ARG(argIdx, scope);
diff --git a/src/qml/compiler/qv4compilationunitmapper.cpp b/src/qml/compiler/qv4compilationunitmapper.cpp
index 1ae0fb190c..d94f7ac238 100644
--- a/src/qml/compiler/qv4compilationunitmapper.cpp
+++ b/src/qml/compiler/qv4compilationunitmapper.cpp
@@ -59,7 +59,7 @@ CompilationUnitMapper::~CompilationUnitMapper()
close();
}
-bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, const QString &sourcePath, QString *errorString)
+bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString)
{
if (strncmp(header->magic, CompiledData::magic_str, sizeof(header->magic))) {
*errorString = QStringLiteral("Magic bytes in the header do not match");
@@ -77,11 +77,6 @@ bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, const
}
if (header->sourceTimeStamp) {
- QFileInfo sourceCode(sourcePath);
- QDateTime sourceTimeStamp;
- if (sourceCode.exists())
- sourceTimeStamp = sourceCode.lastModified();
-
// Files from the resource system do not have any time stamps, so fall back to the application
// executable.
if (!sourceTimeStamp.isValid())
diff --git a/src/qml/compiler/qv4compilationunitmapper_p.h b/src/qml/compiler/qv4compilationunitmapper_p.h
index 5b6939f1cf..b24f98df7c 100644
--- a/src/qml/compiler/qv4compilationunitmapper_p.h
+++ b/src/qml/compiler/qv4compilationunitmapper_p.h
@@ -68,11 +68,11 @@ public:
CompilationUnitMapper();
~CompilationUnitMapper();
- CompiledData::Unit *open(const QString &cacheFilePath, const QString &sourcePath, QString *errorString);
+ CompiledData::Unit *open(const QString &cacheFilePath, const QDateTime &sourceTimeStamp, QString *errorString);
void close();
private:
- static bool verifyHeader(const QV4::CompiledData::Unit *header, const QString &sourcePath, QString *errorString);
+ static bool verifyHeader(const QV4::CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString);
#if defined(Q_OS_UNIX)
size_t length;
diff --git a/src/qml/compiler/qv4compilationunitmapper_unix.cpp b/src/qml/compiler/qv4compilationunitmapper_unix.cpp
index 1aa3e05f5f..38dabc41cf 100644
--- a/src/qml/compiler/qv4compilationunitmapper_unix.cpp
+++ b/src/qml/compiler/qv4compilationunitmapper_unix.cpp
@@ -43,6 +43,7 @@
#include <functional>
#include <private/qcore_unix_p.h>
#include <private/qdeferredcleanup_p.h>
+#include <QDateTime>
#include "qv4compileddata_p.h"
@@ -50,7 +51,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString)
+CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QDateTime &sourceTimeStamp, QString *errorString)
{
close();
@@ -72,7 +73,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
return nullptr;
}
- if (!verifyHeader(&header, sourcePath, errorString))
+ if (!verifyHeader(&header, sourceTimeStamp, errorString))
return nullptr;
// Data structure and qt version matched, so now we can access the rest of the file safely.
diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp
index 37cac846a0..d7a93ae233 100644
--- a/src/qml/compiler/qv4compilationunitmapper_win.cpp
+++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString)
+CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QDateTime &sourceTimeStamp, QString *errorString)
{
close();
@@ -87,7 +87,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
return nullptr;
}
- if (!verifyHeader(&header, sourcePath, errorString))
+ if (!verifyHeader(&header, sourceTimeStamp, errorString))
return nullptr;
const uint mappingFlags = header.flags & QV4::CompiledData::Unit::ContainsMachineCode
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index aad0a04b9f..f1f0ec282c 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -95,7 +95,6 @@ static QString cacheFilePath(const QUrl &url)
#ifndef V4_BOOTSTRAP
CompilationUnit::CompilationUnit()
: data(0)
- , runtimeStrings(0)
, engine(0)
, runtimeLookups(0)
, runtimeRegularExpressions(0)
@@ -343,7 +342,7 @@ bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHashe
sizeof(data->dependencyMD5Checksum)) == 0;
}
-bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory, QString *errorString)
+bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString)
{
if (!QQmlFile::isLocalFile(url)) {
*errorString = QStringLiteral("File has to be a local file.");
@@ -353,7 +352,7 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory
const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url);
QScopedPointer<CompilationUnitMapper> cacheFile(new CompilationUnitMapper());
- CompiledData::Unit *mappedUnit = cacheFile->open(cacheFilePath(url), sourcePath, errorString);
+ CompiledData::Unit *mappedUnit = cacheFile->open(cacheFilePath(url), sourceTimeStamp, errorString);
if (!mappedUnit)
return false;
@@ -776,7 +775,7 @@ void Unit::generateChecksum()
#ifndef V4_BOOTSTRAP
QCryptographicHash hash(QCryptographicHash::Md5);
- const int checksummableDataOffset = qOffsetOf(QV4::CompiledData::Unit, md5Checksum) + sizeof(md5Checksum);
+ const int checksummableDataOffset = offsetof(QV4::CompiledData::Unit, md5Checksum) + sizeof(md5Checksum);
const char *dataPtr = reinterpret_cast<const char *>(this) + checksummableDataOffset;
hash.addData(dataPtr, unitSize - checksummableDataOffset);
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 61762ef474..23f5e31ebe 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -71,7 +71,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x09
+#define QV4_DATA_STRUCTURE_VERSION 0x11
class QIODevice;
class QQmlPropertyCache;
@@ -797,11 +797,15 @@ typedef QVector<QQmlPropertyData*> BindingPropertyData;
// This is how this hooks into the existing structures:
-//VM::Function
-// CompilationUnit * (for functions that need to clean up)
-// CompiledData::Function *compiledFunction
+struct Q_QML_PRIVATE_EXPORT CompilationUnitBase
+{
+ QV4::Heap::String **runtimeStrings = 0; // Array
+};
-struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
+Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value);
+Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeStrings) == 0);
+
+struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public QQmlRefCount
{
#ifdef V4_BOOTSTRAP
CompilationUnit()
@@ -818,8 +822,6 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
// Called only when building QML, when we build the header for JS first and append QML data
virtual QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument);
- QV4::Heap::String **runtimeStrings; // Array
-
#ifndef V4_BOOTSTRAP
ExecutionEngine *engine;
@@ -898,7 +900,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
void destroy() Q_DECL_OVERRIDE;
- bool loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory, QString *errorString);
+ bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString);
protected:
virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 9cfac4a676..64f034ddcb 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -425,7 +425,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
}
unit.indexOfRootFunction = -1;
unit.sourceFileIndex = getStringId(irModule->fileName);
- unit.sourceTimeStamp = irModule->sourceTimeStamp;
+ unit.sourceTimeStamp = irModule->sourceTimeStamp.isValid() ? irModule->sourceTimeStamp.toMSecsSinceEpoch() : 0;
unit.nImports = 0;
unit.offsetToImports = 0;
unit.nObjects = 0;
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 53d9956315..fbd6ac8f99 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -690,7 +690,7 @@ union Instr
};
struct instr_binop {
MOTH_INSTR_HEADER
- uint alu; // offset inside the runtime methods
+ int alu; // QV4::Runtime::RuntimeMethods enum value
Param lhs;
Param rhs;
Param result;
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 04844302d9..aefb084971 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -55,70 +55,70 @@ using namespace QV4::Moth;
namespace {
-inline uint aluOpFunction(IR::AluOp op)
+inline QV4::Runtime::RuntimeMethods aluOpFunction(IR::AluOp op)
{
switch (op) {
case IR::OpInvalid:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpIfTrue:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpNot:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpUMinus:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpUPlus:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpCompl:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpBitAnd:
- return offsetof(QV4::Runtime, bitAnd);
+ return QV4::Runtime::bitAnd;
case IR::OpBitOr:
- return offsetof(QV4::Runtime, bitOr);
+ return QV4::Runtime::bitOr;
case IR::OpBitXor:
- return offsetof(QV4::Runtime, bitXor);
+ return QV4::Runtime::bitXor;
case IR::OpAdd:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpSub:
- return offsetof(QV4::Runtime, sub);
+ return QV4::Runtime::sub;
case IR::OpMul:
- return offsetof(QV4::Runtime, mul);
+ return QV4::Runtime::mul;
case IR::OpDiv:
- return offsetof(QV4::Runtime, div);
+ return QV4::Runtime::div;
case IR::OpMod:
- return offsetof(QV4::Runtime, mod);
+ return QV4::Runtime::mod;
case IR::OpLShift:
- return offsetof(QV4::Runtime, shl);
+ return QV4::Runtime::shl;
case IR::OpRShift:
- return offsetof(QV4::Runtime, shr);
+ return QV4::Runtime::shr;
case IR::OpURShift:
- return offsetof(QV4::Runtime, ushr);
+ return QV4::Runtime::ushr;
case IR::OpGt:
- return offsetof(QV4::Runtime, greaterThan);
+ return QV4::Runtime::greaterThan;
case IR::OpLt:
- return offsetof(QV4::Runtime, lessThan);
+ return QV4::Runtime::lessThan;
case IR::OpGe:
- return offsetof(QV4::Runtime, greaterEqual);
+ return QV4::Runtime::greaterEqual;
case IR::OpLe:
- return offsetof(QV4::Runtime, lessEqual);
+ return QV4::Runtime::lessEqual;
case IR::OpEqual:
- return offsetof(QV4::Runtime, equal);
+ return QV4::Runtime::equal;
case IR::OpNotEqual:
- return offsetof(QV4::Runtime, notEqual);
+ return QV4::Runtime::notEqual;
case IR::OpStrictEqual:
- return offsetof(QV4::Runtime, strictEqual);
+ return QV4::Runtime::strictEqual;
case IR::OpStrictNotEqual:
- return offsetof(QV4::Runtime, strictNotEqual);
+ return QV4::Runtime::strictNotEqual;
case IR::OpInstanceof:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpIn:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpAnd:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
case IR::OpOr:
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
default:
Q_ASSERT(!"Unknown AluOp");
- return 0;
+ return QV4::Runtime::InvalidRuntimeMethod;
}
};
@@ -889,24 +889,25 @@ Param InstructionSelection::binopHelper(IR::AluOp oper, IR::Expr *leftSource, IR
if (oper == IR::OpInstanceof || oper == IR::OpIn || oper == IR::OpAdd) {
Instruction::BinopContext binop;
if (oper == IR::OpInstanceof)
- binop.alu = offsetof(QV4::Runtime, instanceof);
+ binop.alu = QV4::Runtime::instanceof;
else if (oper == IR::OpIn)
- binop.alu = offsetof(QV4::Runtime, in);
+ binop.alu = QV4::Runtime::in;
else
- binop.alu = offsetof(QV4::Runtime, add);
+ binop.alu = QV4::Runtime::add;
binop.lhs = getParam(leftSource);
binop.rhs = getParam(rightSource);
binop.result = getResultParam(target);
- Q_ASSERT(binop.alu);
+ Q_ASSERT(binop.alu != QV4::Runtime::InvalidRuntimeMethod);
addInstruction(binop);
return binop.result;
} else {
+ auto binopFunc = aluOpFunction(oper);
+ Q_ASSERT(binopFunc != QV4::Runtime::InvalidRuntimeMethod);
Instruction::Binop binop;
- binop.alu = aluOpFunction(oper);
+ binop.alu = binopFunc;
binop.lhs = getParam(leftSource);
binop.rhs = getParam(rightSource);
binop.result = getResultParam(target);
- Q_ASSERT(binop.alu);
addInstruction(binop);
return binop.result;
}
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index 41469f1985..4b84bd2831 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -179,7 +179,7 @@ private:
int scratchTempIndex() const { return _function->tempCount; }
int callDataStart() const { return scratchTempIndex() + 1; }
- int outgoingArgumentTempStart() const { return callDataStart() + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value); }
+ int outgoingArgumentTempStart() const { return callDataStart() + offsetof(QV4::CallData, args)/sizeof(QV4::Value); }
int frameSize() const { return outgoingArgumentTempStart() + _function->maxNumberOfArguments; }
template <int Instr>
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 23ebe0c962..d9192c1a3b 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -61,6 +61,7 @@
#include <QtCore/QBitArray>
#include <QtCore/qurl.h>
#include <QtCore/QVarLengthArray>
+#include <QtCore/QDateTime>
#include <qglobal.h>
#if defined(CONST) && defined(Q_OS_WIN)
@@ -942,7 +943,7 @@ struct Q_QML_PRIVATE_EXPORT Module {
QVector<Function *> functions;
Function *rootFunction;
QString fileName;
- qint64 sourceTimeStamp;
+ QDateTime sourceTimeStamp;
bool isQmlModule; // implies rootFunction is always 0
uint unitFlags; // flags merged into CompiledData::Unit::flags
#ifdef QT_NO_QML_DEBUGGER
@@ -955,7 +956,6 @@ struct Q_QML_PRIVATE_EXPORT Module {
Module(bool debugMode)
: rootFunction(0)
- , sourceTimeStamp(0)
, isQmlModule(false)
, unitFlags(0)
#ifndef QT_NO_QML_DEBUGGER
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index ad8a5823e2..5c90aba464 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -269,24 +269,29 @@ typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>:
{
int32_t offset = 0;
int scope = al->scope;
- loadPtr(Address(EngineRegister, qOffsetOf(ExecutionEngine, current)), baseReg);
+ loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(EngineBase, current))), baseReg);
+
+ const qint32 outerOffset = targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, outer));
+
if (scope) {
- loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, outer)), baseReg);
+ loadPtr(Address(baseReg, outerOffset), baseReg);
--scope;
while (scope) {
- loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, outer)), baseReg);
+ loadPtr(Address(baseReg, outerOffset), baseReg);
--scope;
}
}
switch (al->kind) {
case IR::ArgLocal::Formal:
case IR::ArgLocal::ScopedFormal: {
- loadPtr(Address(baseReg, qOffsetOf(ExecutionContext::Data, callData)), baseReg);
+ const qint32 callDataOffset = targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, callData));
+ loadPtr(Address(baseReg, callDataOffset), baseReg);
offset = sizeof(CallData) + (al->index - 1) * sizeof(Value);
} break;
case IR::ArgLocal::Local:
case IR::ArgLocal::ScopedLocal: {
- loadPtr(Address(baseReg, qOffsetOf(CallContext::Data, locals)), baseReg);
+ const qint32 localsOffset = targetStructureOffset(Heap::CallContext::baseOffset + offsetof(Heap::CallContextData, locals));
+ loadPtr(Address(baseReg, localsOffset), baseReg);
offset = al->index * sizeof(Value);
} break;
default:
@@ -298,9 +303,9 @@ typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>:
template <typename TargetConfiguration>
typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>::loadStringAddress(RegisterID reg, const QString &string)
{
- loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), Assembler::ScratchRegister);
- loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::Heap::ExecutionContext, compilationUnit)), Assembler::ScratchRegister);
- loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
+ loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), Assembler::ScratchRegister);
+ loadPtr(Address(Assembler::ScratchRegister, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, compilationUnit))), Assembler::ScratchRegister);
+ loadPtr(Address(Assembler::ScratchRegister, offsetof(CompiledData::CompilationUnitBase, runtimeStrings)), reg);
const int id = _jsGenerator->registerString(string);
return Pointer(reg, id * sizeof(QV4::String*));
}
@@ -314,8 +319,8 @@ typename Assembler<TargetConfiguration>::Address Assembler<TargetConfiguration>:
template <typename TargetConfiguration>
typename Assembler<TargetConfiguration>::Address Assembler<TargetConfiguration>::loadConstant(const Primitive &v, RegisterID baseReg)
{
- loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), baseReg);
- loadPtr(Address(baseReg, qOffsetOf(QV4::Heap::ExecutionContext, constantTable)), baseReg);
+ loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), baseReg);
+ loadPtr(Address(baseReg, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, constantTable))), baseReg);
const int index = _jsGenerator->registerConstant(v.asReturnedValue());
return Address(baseReg, index * sizeof(QV4::Value));
}
@@ -518,9 +523,9 @@ void Assembler<TargetConfiguration>::returnFromFunction(IR::Ret *s, RegisterInfo
const int locals = stackLayout().calculateJSStackFrameSize();
subPtr(TrustedImm32(sizeof(QV4::Value)*locals), JITTargetPlatform::LocalsRegister);
- loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister);
- loadPtr(Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionContext::Data, engine)), JITTargetPlatform::ScratchRegister);
- storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop)));
+ loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister);
+ loadPtr(Address(JITTargetPlatform::ScratchRegister, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, engine))), JITTargetPlatform::ScratchRegister);
+ storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))));
leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave);
ret();
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 720c522e1d..e507a14f12 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -131,7 +131,7 @@ typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingS
#define isel_stringIfy(s) isel_stringIfyx(s)
#define generateRuntimeCall(as, t, function, ...) \
- as->generateFunctionCallImp(Runtime::Method_##function##_NeedsExceptionCheck, t, "Runtime::" isel_stringIfy(function), typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, function)), __VA_ARGS__)
+ as->generateFunctionCallImp(Runtime::Method_##function##_NeedsExceptionCheck, t, "Runtime::" isel_stringIfy(function), typename JITAssembler::RuntimeCall(QV4::Runtime::function), __VA_ARGS__)
template <typename JITAssembler, typename MacroAssembler, typename TargetPlatform, int RegisterSize>
@@ -713,6 +713,12 @@ public:
using JITTargetPlatform::platformFinishEnteringStandardStackFrame;
using JITTargetPlatform::platformLeaveStandardStackFrame;
+ static qint32 targetStructureOffset(qint32 hostOffset)
+ {
+ Q_ASSERT(hostOffset % QT_POINTER_SIZE == 0);
+ return (hostOffset * RegisterSize) / QT_POINTER_SIZE;
+ }
+
using RegisterSizeDependentOps = RegisterSizeDependentAssembler<Assembler<TargetConfiguration>, MacroAssembler, JITTargetPlatform, RegisterSize>;
struct LookupCall {
@@ -728,7 +734,7 @@ public:
struct RuntimeCall {
Address addr;
- inline RuntimeCall(uint offset = uint(INT_MIN));
+ inline RuntimeCall(Runtime::RuntimeMethods method = Runtime::InvalidRuntimeMethod);
bool isValid() const { return addr.offset >= 0; }
};
@@ -1249,7 +1255,7 @@ public:
const RegisterInformation &fpRegistersToSave);
void checkException() {
- load32(Address(EngineRegister, qOffsetOf(QV4::ExecutionEngine, hasException)), ScratchRegister);
+ load32(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, hasException))), ScratchRegister);
Jump exceptionThrown = branch32(RelationalCondition::NotEqual, ScratchRegister, TrustedImm32(0));
if (catchBlock)
addPatch(catchBlock, exceptionThrown);
@@ -1317,8 +1323,8 @@ public:
// IMPORTANT! See generateLookupCall in qv4isel_masm_p.h for details!
// load the table from the context
- loadPtr(Address(EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), ScratchRegister);
- loadPtr(Address(ScratchRegister, qOffsetOf(QV4::Heap::ExecutionContext, lookups)),
+ loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), ScratchRegister);
+ loadPtr(Address(ScratchRegister, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, lookups))),
lookupCall.addr.base);
// pre-calculate the indirect address for the lookupCall table:
if (lookupCall.addr.offset)
@@ -1616,9 +1622,9 @@ public:
const int locals = _stackLayout->calculateJSStackFrameSize();
if (locals <= 0)
return;
- loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(ExecutionEngine, jsStackTop)), JITTargetPlatform::LocalsRegister);
+ loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))), JITTargetPlatform::LocalsRegister);
RegisterSizeDependentOps::initializeLocalVariables(this, locals);
- storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, qOffsetOf(ExecutionEngine, jsStackTop)));
+ storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))));
}
Label exceptionReturnLabel;
@@ -1679,8 +1685,9 @@ void Assembler<TargetConfiguration>::copyValue(Result result, IR::Expr* source)
}
template <typename TargetConfiguration>
-inline Assembler<TargetConfiguration>::RuntimeCall::RuntimeCall(uint offset)
- : addr(Assembler::EngineRegister, offset + qOffsetOf(QV4::ExecutionEngine, runtime))
+inline Assembler<TargetConfiguration>::RuntimeCall::RuntimeCall(Runtime::RuntimeMethods method)
+ : addr(Assembler::EngineRegister,
+ method == Runtime::InvalidRuntimeMethod ? -1 : (Assembler<TargetConfiguration>::targetStructureOffset(offsetof(EngineBase, runtime) + Runtime::runtimeMethodOffset(method))))
{
}
diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp
index 22067bbb13..feb30ee298 100644
--- a/src/qml/jit/qv4binop.cpp
+++ b/src/qml/jit/qv4binop.cpp
@@ -165,17 +165,17 @@ struct ArchitectureSpecificBinaryOperation<Assembler<AssemblerTargetConfiguratio
#endif
#define OP(op) \
- { "Runtime::" isel_stringIfy(op), offsetof(QV4::Runtime, op), INT_MIN, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
+ { "Runtime::" isel_stringIfy(op), QV4::Runtime::op, QV4::Runtime::InvalidRuntimeMethod, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
#define OPCONTEXT(op) \
- { "Runtime::" isel_stringIfy(op), INT_MIN, offsetof(QV4::Runtime, op), 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
+ { "Runtime::" isel_stringIfy(op), QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::op, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
#define INLINE_OP(op, memOp, immOp) \
- { "Runtime::" isel_stringIfy(op), offsetof(QV4::Runtime, op), INT_MIN, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
+ { "Runtime::" isel_stringIfy(op), QV4::Runtime::op, QV4::Runtime::InvalidRuntimeMethod, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
#define INLINE_OPCONTEXT(op, memOp, immOp) \
- { "Runtime::" isel_stringIfy(op), INT_MIN, offsetof(QV4::Runtime, op), memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
+ { "Runtime::" isel_stringIfy(op), QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::op, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
#define NULL_OP \
- { 0, 0, 0, 0, 0, false }
+ { 0, QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::InvalidRuntimeMethod, 0, 0, false }
template <typename JITAssembler>
const typename Binop<JITAssembler>::OpInfo Binop<JITAssembler>::operations[IR::LastAluOp + 1] = {
diff --git a/src/qml/jit/qv4binop_p.h b/src/qml/jit/qv4binop_p.h
index d2d9ba7753..1b1ab7f24d 100644
--- a/src/qml/jit/qv4binop_p.h
+++ b/src/qml/jit/qv4binop_p.h
@@ -88,8 +88,8 @@ struct Binop {
struct OpInfo {
const char *name;
- int fallbackImplementation; // offsetOf(Runtime,...)
- int contextImplementation; // offsetOf(Runtime,...)
+ Runtime::RuntimeMethods fallbackImplementation;
+ Runtime::RuntimeMethods contextImplementation;
MemRegOp inlineMemRegOp;
ImmRegOp inlineImmRegOp;
bool needsExceptionCheck;
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 69d6951bb9..4a222e20f4 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -132,8 +132,8 @@ void InstructionSelection<JITAssembler>::run(int functionIndex)
for (IR::Stmt *s : _block->statements()) {
if (s->location.isValid()) {
if (int(s->location.startLine) != lastLine) {
- _as->loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister);
- Address lineAddr(JITTargetPlatform::ScratchRegister, qOffsetOf(QV4::ExecutionContext::Data, lineNumber));
+ _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister);
+ Address lineAddr(JITTargetPlatform::ScratchRegister, JITAssembler::targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, lineNumber)));
_as->store32(TrustedImm32(s->location.startLine), lineAddr);
lastLine = s->location.startLine;
}
@@ -447,9 +447,9 @@ void InstructionSelection<JITAssembler>::callValue(IR::Expr *value, IR::ExprList
template <typename JITAssembler>
void InstructionSelection<JITAssembler>::loadThisObject(IR::Expr *temp)
{
- _as->loadPtr(Address(JITTargetPlatform::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), JITTargetPlatform::ScratchRegister);
- _as->loadPtr(Address(JITTargetPlatform::ScratchRegister, qOffsetOf(ExecutionContext::Data, callData)), JITTargetPlatform::ScratchRegister);
- _as->copyValue(temp, Address(JITTargetPlatform::ScratchRegister, qOffsetOf(CallData, thisObject)));
+ _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister);
+ _as->loadPtr(Address(JITTargetPlatform::ScratchRegister, JITAssembler::targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, callData))), JITTargetPlatform::ScratchRegister);
+ _as->copyValue(temp, Address(JITTargetPlatform::ScratchRegister, offsetof(CallData, thisObject)));
}
template <typename JITAssembler>
@@ -519,7 +519,7 @@ void InstructionSelection<JITAssembler>::getActivationProperty(const IR::Name *n
{
if (useFastLookups && name->global) {
uint index = registerGlobalGetterLookup(*name->id);
- generateLookupCall(target, index, qOffsetOf(QV4::Lookup, globalGetter), JITTargetPlatform::EngineRegister, JITAssembler::Void);
+ generateLookupCall(target, index, offsetof(QV4::Lookup, globalGetter), JITTargetPlatform::EngineRegister, JITAssembler::Void);
return;
}
generateRuntimeCall(_as, target, getActivationProperty, JITTargetPlatform::EngineRegister, StringToIndex(*name->id));
@@ -545,7 +545,7 @@ void InstructionSelection<JITAssembler>::getProperty(IR::Expr *base, const QStri
{
if (useFastLookups) {
uint index = registerGetterLookup(name);
- generateLookupCall(target, index, qOffsetOf(QV4::Lookup, getter), JITTargetPlatform::EngineRegister, PointerToValue(base), JITAssembler::Void);
+ generateLookupCall(target, index, offsetof(QV4::Lookup, getter), JITTargetPlatform::EngineRegister, PointerToValue(base), JITAssembler::Void);
} else {
generateRuntimeCall(_as, target, getProperty, JITTargetPlatform::EngineRegister,
PointerToValue(base), StringToIndex(name));
@@ -584,7 +584,7 @@ void InstructionSelection<JITAssembler>::setProperty(IR::Expr *source, IR::Expr
{
if (useFastLookups) {
uint index = registerSetterLookup(targetName);
- generateLookupCall(JITAssembler::Void, index, qOffsetOf(QV4::Lookup, setter),
+ generateLookupCall(JITAssembler::Void, index, offsetof(QV4::Lookup, setter),
JITTargetPlatform::EngineRegister,
PointerToValue(targetBase),
PointerToValue(source));
@@ -620,7 +620,7 @@ void InstructionSelection<JITAssembler>::getElement(IR::Expr *base, IR::Expr *in
{
if (useFastLookups) {
uint lookup = registerIndexedGetterLookup();
- generateLookupCall(target, lookup, qOffsetOf(QV4::Lookup, indexedGetter),
+ generateLookupCall(target, lookup, offsetof(QV4::Lookup, indexedGetter),
PointerToValue(base),
PointerToValue(index));
return;
@@ -635,7 +635,7 @@ void InstructionSelection<JITAssembler>::setElement(IR::Expr *source, IR::Expr *
{
if (useFastLookups) {
uint lookup = registerIndexedSetterLookup();
- generateLookupCall(JITAssembler::Void, lookup, qOffsetOf(QV4::Lookup, indexedSetter),
+ generateLookupCall(JITAssembler::Void, lookup, offsetof(QV4::Lookup, indexedSetter),
PointerToValue(targetBase), PointerToValue(targetIndex),
PointerToValue(source));
return;
@@ -791,12 +791,12 @@ void InstructionSelection<JITAssembler>::swapValues(IR::Expr *source, IR::Expr *
#define setOp(op, opName, operation) \
do { \
- op = typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); opName = "Runtime::" isel_stringIfy(operation); \
+ op = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); opName = "Runtime::" isel_stringIfy(operation); \
needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \
} while (0)
#define setOpContext(op, opName, operation) \
do { \
- opContext = typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); opName = "Runtime::" isel_stringIfy(operation); \
+ opContext = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); opName = "Runtime::" isel_stringIfy(operation); \
needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \
} while (0)
@@ -1313,11 +1313,11 @@ int InstructionSelection<JITAssembler>::prepareCallData(IR::ExprList* args, IR::
++argc;
}
- Pointer p = _as->stackLayout().callDataAddress(qOffsetOf(CallData, tag));
+ Pointer p = _as->stackLayout().callDataAddress(offsetof(CallData, tag));
_as->store32(TrustedImm32(QV4::Value::Integer_Type_Internal), p);
- p = _as->stackLayout().callDataAddress(qOffsetOf(CallData, argc));
+ p = _as->stackLayout().callDataAddress(offsetof(CallData, argc));
_as->store32(TrustedImm32(argc), p);
- p = _as->stackLayout().callDataAddress(qOffsetOf(CallData, thisObject));
+ p = _as->stackLayout().callDataAddress(offsetof(CallData, thisObject));
if (!thisObject)
_as->storeValue(QV4::Primitive::undefinedValue(), p);
else
diff --git a/src/qml/jit/qv4unop.cpp b/src/qml/jit/qv4unop.cpp
index 76c6457d67..896be07ed5 100644
--- a/src/qml/jit/qv4unop.cpp
+++ b/src/qml/jit/qv4unop.cpp
@@ -48,7 +48,7 @@ using namespace JIT;
#define stringIfy(s) stringIfyx(s)
#define setOp(operation) \
do { \
- call = typename JITAssembler::RuntimeCall(qOffsetOf(QV4::Runtime, operation)); name = "Runtime::" stringIfy(operation); \
+ call = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); name = "Runtime::" stringIfy(operation); \
needsExceptionCheck = Runtime::Method_##operation##_NeedsExceptionCheck; \
} while (0)
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index d8a7de5466..c29cedaa9b 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -697,7 +697,7 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const
callData->thisObject = Primitive::undefinedValue();
callData->args[0] = v1;
callData->args[1] = v2;
- result = scope.engine->runtime.callValue(scope.engine, m_comparefn, callData);
+ result = QV4::Runtime::method_callValue(scope.engine, m_comparefn, callData);
return result->toNumber() < 0;
}
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 60b90e4bf0..c4a0539750 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -78,8 +78,8 @@ Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData
c->activation = 0;
c->compilationUnit = function->compilationUnit;
- c->lookups = c->compilationUnit->runtimeLookups;
- c->constantTable = c->compilationUnit->constants;
+ c->lookups = function->compilationUnit->runtimeLookups;
+ c->constantTable = function->compilationUnit->constants;
c->locals = (Value *)((quintptr(c + 1) + 7) & ~7);
const CompiledData::Function *compiledFunction = function->compiledFunction;
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index bcfee2e1f8..c769dcd142 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -61,7 +61,7 @@ class QQmlContextData;
namespace QV4 {
namespace CompiledData {
-struct CompilationUnit;
+struct CompilationUnitBase;
struct Function;
}
@@ -73,6 +73,8 @@ struct WithContext;
struct QmlContext;
struct QmlContextWrapper;
+// Attention: Make sure that this structure is the same size on 32-bit and 64-bit
+// architecture or you'll have to change the JIT code.
struct CallData
{
// below is to be compatible with Value. Initialize tag to 0
@@ -91,11 +93,45 @@ struct CallData
Value args[1];
};
+Q_STATIC_ASSERT(std::is_standard_layout<CallData>::value);
+Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 8);
+Q_STATIC_ASSERT(offsetof(CallData, args) == 16);
+
namespace Heap {
struct QmlContext;
-struct ExecutionContext : Base {
+// ### Temporary arrangment until this code hits the dev branch and
+// can use the Members macro
+struct ExecutionContextData {
+ CallData *callData;
+ ExecutionEngine *engine;
+ ExecutionContext *outer;
+ Lookup *lookups;
+ const QV4::Value *constantTable;
+ CompiledData::CompilationUnitBase *compilationUnit;
+ // as member of non-pointer size this has to come last to preserve the ability to
+ // translate offsetof of it between 64-bit and 32-bit.
+ int lineNumber;
+#if QT_POINTER_SIZE == 8
+ uint padding_;
+#endif
+};
+
+Q_STATIC_ASSERT(std::is_standard_layout<ExecutionContextData>::value);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, callData) == 0);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, engine) == offsetof(ExecutionContextData, callData) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, outer) == offsetof(ExecutionContextData, engine) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, lookups) == offsetof(ExecutionContextData, outer) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, constantTable) == offsetof(ExecutionContextData, lookups) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, compilationUnit) == offsetof(ExecutionContextData, constantTable) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, lineNumber) == offsetof(ExecutionContextData, compilationUnit) + QT_POINTER_SIZE);
+
+struct ExecutionContextSizeStruct : public Base, public ExecutionContextData {};
+
+struct ExecutionContext : Base, public ExecutionContextData {
+ static Q_CONSTEXPR size_t baseOffset = sizeof(ExecutionContextSizeStruct) - sizeof(ExecutionContextData);
+
enum ContextType {
Type_GlobalContext = 0x1,
Type_CatchContext = 0x2,
@@ -114,21 +150,28 @@ struct ExecutionContext : Base {
lineNumber = -1;
}
- CallData *callData;
-
- ExecutionEngine *engine;
- Pointer<ExecutionContext> outer;
- Lookup *lookups;
- const QV4::Value *constantTable;
- CompiledData::CompilationUnit *compilationUnit;
-
- ContextType type : 8;
+ quint8 type;
bool strictMode : 8;
- int lineNumber;
+#if QT_POINTER_SIZE == 8
+ quint8 padding_[6];
+#else
+ quint8 padding_[2];
+#endif
};
V4_ASSERT_IS_TRIVIAL(ExecutionContext)
+Q_STATIC_ASSERT(sizeof(ExecutionContext) == sizeof(Base) + sizeof(ExecutionContextData) + QT_POINTER_SIZE);
-struct CallContext : ExecutionContext {
+struct CallContextData {
+ Value *locals;
+};
+
+Q_STATIC_ASSERT(std::is_standard_layout<CallContextData>::value);
+Q_STATIC_ASSERT(offsetof(CallContextData, locals) == 0);
+
+struct CallContextSizeStruct : public ExecutionContext, public CallContextData {};
+
+struct CallContext : ExecutionContext, public CallContextData {
+ static Q_CONSTEXPR size_t baseOffset = sizeof(CallContextSizeStruct) - sizeof(CallContextData);
static CallContext *createSimpleContext(ExecutionEngine *v4);
void freeSimpleCallContext();
@@ -141,7 +184,6 @@ struct CallContext : ExecutionContext {
Pointer<FunctionObject> function;
QV4::Function *v4Function;
- Value *locals;
Pointer<Object> activation;
};
V4_ASSERT_IS_TRIVIAL(CallContext)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index f925c9184c..83b00f0356 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -130,10 +130,7 @@ QQmlEngine *ExecutionEngine::qmlEngine() const
qint32 ExecutionEngine::maxCallDepth = -1;
ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
- : current(0)
- , hasException(false)
- , callDepth(0)
- , memoryManager(new QV4::MemoryManager(this))
+ : callDepth(0)
, executableAllocator(new QV4::ExecutableAllocator)
, regExpAllocator(new QV4::ExecutableAllocator)
, currentContext(0)
@@ -151,6 +148,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
, m_profiler(0)
#endif
{
+ memoryManager = new QV4::MemoryManager(this);
+
if (maxCallDepth == -1) {
bool ok = false;
maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 69aa389c44..5182f24235 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -54,7 +54,6 @@
#include "private/qv4isel_p.h"
#include "qv4managed_p.h"
#include "qv4context_p.h"
-#include "qv4runtimeapi_p.h"
#include <private/qintrusivelist_p.h>
#ifndef V4_BOOTSTRAP
@@ -88,7 +87,7 @@ struct CompilationUnit;
struct InternalClass;
struct InternalClassPool;
-struct Q_QML_EXPORT ExecutionEngine
+struct Q_QML_EXPORT ExecutionEngine : public EngineBase
{
private:
static qint32 maxCallDepth;
@@ -97,13 +96,8 @@ private:
friend struct ExecutionContext;
friend struct Heap::ExecutionContext;
public:
- Heap::ExecutionContext *current;
-
- Value *jsStackTop;
- quint32 hasException;
qint32 callDepth;
- MemoryManager *memoryManager;
ExecutableAllocator *executableAllocator;
ExecutableAllocator *regExpAllocator;
QScopedPointer<EvalISelFactory> iselFactory;
@@ -112,8 +106,6 @@ public:
Value *jsStackLimit;
- Runtime runtime;
-
WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine.
enum { JSStackLimit = 4*1024*1024 };
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 45d7485f1b..f4ac37219c 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -81,7 +81,7 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }
bool needsActivation() const { return function ? function->needsActivation() : false; }
- const QV4::Object *protoProperty() const { return propertyData(Index_Prototype)->cast<QV4::Object>(); }
+ const QV4::Object *protoProperty() const { return propertyData(Index_Prototype)->as<QV4::Object>(); }
Pointer<ExecutionContext> scope;
Function *function;
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 66861bf697..c2a5e75a1f 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -89,8 +89,6 @@ inline bool signbit(double d) { return _copysign(1.0, d) < 0; }
inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
#endif
-#define qOffsetOf(s, m) ((size_t)((((char *)&(((s *)64)->m)) - 64)))
-
// Decide whether to enable or disable the JIT
// White list architectures
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index c5ee92fedd..2ffb43cce9 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -141,6 +141,13 @@ struct Lookup {
};
+Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value);
+// Ensure that these offsets are always at this point to keep generated code compatible
+// across 32-bit and 64-bit (matters when cross-compiling).
+Q_STATIC_ASSERT(offsetof(Lookup, indexedGetter) == 0);
+Q_STATIC_ASSERT(offsetof(Lookup, getter) == 0);
+Q_STATIC_ASSERT(offsetof(Lookup, engine) == offsetof(Lookup, getter) + QT_POINTER_SIZE);
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index b16de02fd3..43e99cf768 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -219,6 +219,14 @@ void RuntimeCounters::count(const char *func, uint tag1, uint tag2)
#endif // QV4_COUNT_RUNTIME_FUNCTIONS
#ifndef V4_BOOTSTRAP
+
+Runtime::Runtime()
+{
+#define INIT_METHOD(returnvalue, name, args) runtimeMethods[name] = reinterpret_cast<void*>(&method_##name);
+FOR_EACH_RUNTIME_METHOD(INIT_METHOD)
+#undef INIT_METHOD
+}
+
void RuntimeHelpers::numberToString(QString *result, double num, int radix)
{
Q_ASSERT(result);
@@ -300,7 +308,7 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
ReturnedValue Runtime::method_closure(ExecutionEngine *engine, int functionId)
{
- QV4::Function *clos = engine->current->compilationUnit->runtimeFunctions[functionId];
+ QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeFunctions[functionId];
Q_ASSERT(clos);
return FunctionObject::createScriptFunction(engine->currentContext, clos)->asReturnedValue();
}
@@ -1301,7 +1309,7 @@ ReturnedValue Runtime::method_arrayLiteral(ExecutionEngine *engine, Value *value
ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)
{
Scope scope(engine);
- QV4::InternalClass *klass = engine->current->compilationUnit->runtimeClasses[classId];
+ QV4::InternalClass *klass = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeClasses[classId];
ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype()));
{
@@ -1413,7 +1421,7 @@ ReturnedValue Runtime::method_getQmlContext(NoThrowEngine *engine)
ReturnedValue Runtime::method_regexpLiteral(ExecutionEngine *engine, int id)
{
- return engine->current->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
+ return static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeRegularExpressions[id].asReturnedValue();
}
ReturnedValue Runtime::method_getQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 355b7890b6..302facba06 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+typedef uint Bool;
struct NoThrowEngine;
namespace {
@@ -90,256 +91,169 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
};
} // anonymous namespace
-#define RUNTIME_METHOD(returnvalue, name, args) \
- typedef returnvalue (*Method_##name)args; \
- enum { Method_##name##_NeedsExceptionCheck = ExceptionCheck<Method_##name>::NeedsCheck }; \
- static returnvalue method_##name args; \
- const Method_##name name
-
-#define INIT_RUNTIME_METHOD(name) \
- name(method_##name)
+#define FOR_EACH_RUNTIME_METHOD(F) \
+ /* call */ \
+ F(ReturnedValue, callGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
+ F(ReturnedValue, callActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
+ F(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)) \
+ F(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)) \
+ F(ReturnedValue, callProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
+ F(ReturnedValue, callPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
+ F(ReturnedValue, callElement, (ExecutionEngine *engine, const Value &index, CallData *callData)) \
+ F(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, CallData *callData)) \
+ \
+ /* construct */ \
+ F(ReturnedValue, constructGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
+ F(ReturnedValue, constructActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
+ F(ReturnedValue, constructProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
+ F(ReturnedValue, constructPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
+ F(ReturnedValue, constructValue, (ExecutionEngine *engine, const Value &func, CallData *callData)) \
+ \
+ /* set & get */ \
+ F(void, setActivationProperty, (ExecutionEngine *engine, int nameIndex, const Value &value)) \
+ F(void, setProperty, (ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)) \
+ F(void, setElement, (ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)) \
+ F(ReturnedValue, getProperty, (ExecutionEngine *engine, const Value &object, int nameIndex)) \
+ F(ReturnedValue, getActivationProperty, (ExecutionEngine *engine, int nameIndex)) \
+ F(ReturnedValue, getElement, (ExecutionEngine *engine, const Value &object, const Value &index)) \
+ \
+ /* typeof */ \
+ F(ReturnedValue, typeofValue, (ExecutionEngine *engine, const Value &val)) \
+ F(ReturnedValue, typeofName, (ExecutionEngine *engine, int nameIndex)) \
+ F(ReturnedValue, typeofScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)) \
+ F(ReturnedValue, typeofContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)) \
+ F(ReturnedValue, typeofMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \
+ F(ReturnedValue, typeofElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \
+ \
+ /* delete */ \
+ F(ReturnedValue, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \
+ F(ReturnedValue, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \
+ F(ReturnedValue, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name)) \
+ F(ReturnedValue, deleteName, (ExecutionEngine *engine, int nameIndex)) \
+ \
+ /* exceptions & scopes */ \
+ F(void, throwException, (ExecutionEngine *engine, const Value &value)) \
+ F(ReturnedValue, unwindException, (ExecutionEngine *engine)) \
+ F(void, pushWithScope, (const Value &o, NoThrowEngine *engine)) \
+ F(void, pushCatchScope, (NoThrowEngine *engine, int exceptionVarNameIndex)) \
+ F(void, popScope, (NoThrowEngine *engine)) \
+ \
+ /* closures */ \
+ F(ReturnedValue, closure, (ExecutionEngine *engine, int functionId)) \
+ \
+ /* function header */ \
+ F(void, declareVar, (ExecutionEngine *engine, bool deletable, int nameIndex)) \
+ F(ReturnedValue, setupArgumentsObject, (ExecutionEngine *engine)) \
+ F(void, convertThisToObject, (ExecutionEngine *engine)) \
+ \
+ /* literals */ \
+ F(ReturnedValue, arrayLiteral, (ExecutionEngine *engine, Value *values, uint length)) \
+ F(ReturnedValue, objectLiteral, (ExecutionEngine *engine, const Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)) \
+ F(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id)) \
+ \
+ /* foreach */ \
+ F(ReturnedValue, foreachIterator, (ExecutionEngine *engine, const Value &in)) \
+ F(ReturnedValue, foreachNextPropertyName, (const Value &foreach_iterator)) \
+ \
+ /* unary operators */ \
+ F(ReturnedValue, uPlus, (const Value &value)) \
+ F(ReturnedValue, uMinus, (const Value &value)) \
+ F(ReturnedValue, uNot, (const Value &value)) \
+ F(ReturnedValue, complement, (const Value &value)) \
+ F(ReturnedValue, increment, (const Value &value)) \
+ F(ReturnedValue, decrement, (const Value &value)) \
+ \
+ /* binary operators */ \
+ F(ReturnedValue, instanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \
+ F(ReturnedValue, in, (ExecutionEngine *engine, const Value &left, const Value &right)) \
+ F(ReturnedValue, add, (ExecutionEngine *engine, const Value &left, const Value &right)) \
+ F(ReturnedValue, addString, (ExecutionEngine *engine, const Value &left, const Value &right)) \
+ F(ReturnedValue, bitOr, (const Value &left, const Value &right)) \
+ F(ReturnedValue, bitXor, (const Value &left, const Value &right)) \
+ F(ReturnedValue, bitAnd, (const Value &left, const Value &right)) \
+ F(ReturnedValue, sub, (const Value &left, const Value &right)) \
+ F(ReturnedValue, mul, (const Value &left, const Value &right)) \
+ F(ReturnedValue, div, (const Value &left, const Value &right)) \
+ F(ReturnedValue, mod, (const Value &left, const Value &right)) \
+ F(ReturnedValue, shl, (const Value &left, const Value &right)) \
+ F(ReturnedValue, shr, (const Value &left, const Value &right)) \
+ F(ReturnedValue, ushr, (const Value &left, const Value &right)) \
+ F(ReturnedValue, greaterThan, (const Value &left, const Value &right)) \
+ F(ReturnedValue, lessThan, (const Value &left, const Value &right)) \
+ F(ReturnedValue, greaterEqual, (const Value &left, const Value &right)) \
+ F(ReturnedValue, lessEqual, (const Value &left, const Value &right)) \
+ F(ReturnedValue, equal, (const Value &left, const Value &right)) \
+ F(ReturnedValue, notEqual, (const Value &left, const Value &right)) \
+ F(ReturnedValue, strictEqual, (const Value &left, const Value &right)) \
+ F(ReturnedValue, strictNotEqual, (const Value &left, const Value &right)) \
+ \
+ /* comparisons */ \
+ F(Bool, compareGreaterThan, (const Value &l, const Value &r)) \
+ F(Bool, compareLessThan, (const Value &l, const Value &r)) \
+ F(Bool, compareGreaterEqual, (const Value &l, const Value &r)) \
+ F(Bool, compareLessEqual, (const Value &l, const Value &r)) \
+ F(Bool, compareEqual, (const Value &left, const Value &right)) \
+ F(Bool, compareNotEqual, (const Value &left, const Value &right)) \
+ F(Bool, compareStrictEqual, (const Value &left, const Value &right)) \
+ F(Bool, compareStrictNotEqual, (const Value &left, const Value &right)) \
+ \
+ F(Bool, compareInstanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \
+ F(Bool, compareIn, (ExecutionEngine *engine, const Value &left, const Value &right)) \
+ \
+ /* conversions */ \
+ F(Bool, toBoolean, (const Value &value)) \
+ F(ReturnedValue, toDouble, (const Value &value)) \
+ F(int, toInt, (const Value &value)) \
+ F(int, doubleToInt, (const double &d)) \
+ F(unsigned, toUInt, (const Value &value)) \
+ F(unsigned, doubleToUInt, (const double &d)) \
+ \
+ /* qml */ \
+ F(ReturnedValue, getQmlContext, (NoThrowEngine *engine)) \
+ F(ReturnedValue, getQmlImportedScripts, (NoThrowEngine *engine)) \
+ F(ReturnedValue, getQmlSingleton, (NoThrowEngine *engine, int nameIndex)) \
+ F(ReturnedValue, getQmlAttachedProperty, (ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)) \
+ F(ReturnedValue, getQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
+ F(ReturnedValue, getQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
+ F(ReturnedValue, getQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)) \
+ F(ReturnedValue, getQmlSingletonQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)) \
+ F(ReturnedValue, getQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)) \
+ \
+ F(void, setQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
+ F(void, setQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
+ F(void, setQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value))
struct Q_QML_PRIVATE_EXPORT Runtime {
- Runtime()
- : INIT_RUNTIME_METHOD(callGlobalLookup)
- , INIT_RUNTIME_METHOD(callActivationProperty)
- , INIT_RUNTIME_METHOD(callQmlScopeObjectProperty)
- , INIT_RUNTIME_METHOD(callQmlContextObjectProperty)
- , INIT_RUNTIME_METHOD(callProperty)
- , INIT_RUNTIME_METHOD(callPropertyLookup)
- , INIT_RUNTIME_METHOD(callElement)
- , INIT_RUNTIME_METHOD(callValue)
- , INIT_RUNTIME_METHOD(constructGlobalLookup)
- , INIT_RUNTIME_METHOD(constructActivationProperty)
- , INIT_RUNTIME_METHOD(constructProperty)
- , INIT_RUNTIME_METHOD(constructPropertyLookup)
- , INIT_RUNTIME_METHOD(constructValue)
- , INIT_RUNTIME_METHOD(setActivationProperty)
- , INIT_RUNTIME_METHOD(setProperty)
- , INIT_RUNTIME_METHOD(setElement)
- , INIT_RUNTIME_METHOD(getProperty)
- , INIT_RUNTIME_METHOD(getActivationProperty)
- , INIT_RUNTIME_METHOD(getElement)
- , INIT_RUNTIME_METHOD(typeofValue)
- , INIT_RUNTIME_METHOD(typeofName)
- , INIT_RUNTIME_METHOD(typeofScopeObjectProperty)
- , INIT_RUNTIME_METHOD(typeofContextObjectProperty)
- , INIT_RUNTIME_METHOD(typeofMember)
- , INIT_RUNTIME_METHOD(typeofElement)
- , INIT_RUNTIME_METHOD(deleteElement)
- , INIT_RUNTIME_METHOD(deleteMember)
- , INIT_RUNTIME_METHOD(deleteMemberString)
- , INIT_RUNTIME_METHOD(deleteName)
- , INIT_RUNTIME_METHOD(throwException)
- , INIT_RUNTIME_METHOD(unwindException)
- , INIT_RUNTIME_METHOD(pushWithScope)
- , INIT_RUNTIME_METHOD(pushCatchScope)
- , INIT_RUNTIME_METHOD(popScope)
- , INIT_RUNTIME_METHOD(closure)
- , INIT_RUNTIME_METHOD(declareVar)
- , INIT_RUNTIME_METHOD(setupArgumentsObject)
- , INIT_RUNTIME_METHOD(convertThisToObject)
- , INIT_RUNTIME_METHOD(arrayLiteral)
- , INIT_RUNTIME_METHOD(objectLiteral)
- , INIT_RUNTIME_METHOD(regexpLiteral)
- , INIT_RUNTIME_METHOD(foreachIterator)
- , INIT_RUNTIME_METHOD(foreachNextPropertyName)
- , INIT_RUNTIME_METHOD(uPlus)
- , INIT_RUNTIME_METHOD(uMinus)
- , INIT_RUNTIME_METHOD(uNot)
- , INIT_RUNTIME_METHOD(complement)
- , INIT_RUNTIME_METHOD(increment)
- , INIT_RUNTIME_METHOD(decrement)
- , INIT_RUNTIME_METHOD(instanceof)
- , INIT_RUNTIME_METHOD(in)
- , INIT_RUNTIME_METHOD(add)
- , INIT_RUNTIME_METHOD(addString)
- , INIT_RUNTIME_METHOD(bitOr)
- , INIT_RUNTIME_METHOD(bitXor)
- , INIT_RUNTIME_METHOD(bitAnd)
- , INIT_RUNTIME_METHOD(sub)
- , INIT_RUNTIME_METHOD(mul)
- , INIT_RUNTIME_METHOD(div)
- , INIT_RUNTIME_METHOD(mod)
- , INIT_RUNTIME_METHOD(shl)
- , INIT_RUNTIME_METHOD(shr)
- , INIT_RUNTIME_METHOD(ushr)
- , INIT_RUNTIME_METHOD(greaterThan)
- , INIT_RUNTIME_METHOD(lessThan)
- , INIT_RUNTIME_METHOD(greaterEqual)
- , INIT_RUNTIME_METHOD(lessEqual)
- , INIT_RUNTIME_METHOD(equal)
- , INIT_RUNTIME_METHOD(notEqual)
- , INIT_RUNTIME_METHOD(strictEqual)
- , INIT_RUNTIME_METHOD(strictNotEqual)
- , INIT_RUNTIME_METHOD(compareGreaterThan)
- , INIT_RUNTIME_METHOD(compareLessThan)
- , INIT_RUNTIME_METHOD(compareGreaterEqual)
- , INIT_RUNTIME_METHOD(compareLessEqual)
- , INIT_RUNTIME_METHOD(compareEqual)
- , INIT_RUNTIME_METHOD(compareNotEqual)
- , INIT_RUNTIME_METHOD(compareStrictEqual)
- , INIT_RUNTIME_METHOD(compareStrictNotEqual)
- , INIT_RUNTIME_METHOD(compareInstanceof)
- , INIT_RUNTIME_METHOD(compareIn)
- , INIT_RUNTIME_METHOD(toBoolean)
- , INIT_RUNTIME_METHOD(toDouble)
- , INIT_RUNTIME_METHOD(toInt)
- , INIT_RUNTIME_METHOD(doubleToInt)
- , INIT_RUNTIME_METHOD(toUInt)
- , INIT_RUNTIME_METHOD(doubleToUInt)
- , INIT_RUNTIME_METHOD(getQmlContext)
- , INIT_RUNTIME_METHOD(getQmlImportedScripts)
- , INIT_RUNTIME_METHOD(getQmlSingleton)
- , INIT_RUNTIME_METHOD(getQmlAttachedProperty)
- , INIT_RUNTIME_METHOD(getQmlScopeObjectProperty)
- , INIT_RUNTIME_METHOD(getQmlContextObjectProperty)
- , INIT_RUNTIME_METHOD(getQmlQObjectProperty)
- , INIT_RUNTIME_METHOD(getQmlSingletonQObjectProperty)
- , INIT_RUNTIME_METHOD(getQmlIdObject)
- , INIT_RUNTIME_METHOD(setQmlScopeObjectProperty)
- , INIT_RUNTIME_METHOD(setQmlContextObjectProperty)
- , INIT_RUNTIME_METHOD(setQmlQObjectProperty)
- { }
-
- // call
- RUNTIME_METHOD(ReturnedValue, callGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, callActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, callProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, callPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, callElement, (ExecutionEngine *engine, const Value &index, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, CallData *callData));
-
- // construct
- RUNTIME_METHOD(ReturnedValue, constructGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, constructActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, constructProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, constructPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData));
- RUNTIME_METHOD(ReturnedValue, constructValue, (ExecutionEngine *engine, const Value &func, CallData *callData));
-
- // set & get
- RUNTIME_METHOD(void, setActivationProperty, (ExecutionEngine *engine, int nameIndex, const Value &value));
- RUNTIME_METHOD(void, setProperty, (ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value));
- RUNTIME_METHOD(void, setElement, (ExecutionEngine *engine, const Value &object, const Value &index, const Value &value));
- RUNTIME_METHOD(ReturnedValue, getProperty, (ExecutionEngine *engine, const Value &object, int nameIndex));
- RUNTIME_METHOD(ReturnedValue, getActivationProperty, (ExecutionEngine *engine, int nameIndex));
- RUNTIME_METHOD(ReturnedValue, getElement, (ExecutionEngine *engine, const Value &object, const Value &index));
-
- // typeof
- RUNTIME_METHOD(ReturnedValue, typeofValue, (ExecutionEngine *engine, const Value &val));
- RUNTIME_METHOD(ReturnedValue, typeofName, (ExecutionEngine *engine, int nameIndex));
- RUNTIME_METHOD(ReturnedValue, typeofScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex));
- RUNTIME_METHOD(ReturnedValue, typeofContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex));
- RUNTIME_METHOD(ReturnedValue, typeofMember, (ExecutionEngine *engine, const Value &base, int nameIndex));
- RUNTIME_METHOD(ReturnedValue, typeofElement, (ExecutionEngine *engine, const Value &base, const Value &index));
-
- // delete
- RUNTIME_METHOD(ReturnedValue, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index));
- RUNTIME_METHOD(ReturnedValue, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex));
- RUNTIME_METHOD(ReturnedValue, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name));
- RUNTIME_METHOD(ReturnedValue, deleteName, (ExecutionEngine *engine, int nameIndex));
-
- // exceptions & scopes
- RUNTIME_METHOD(void, throwException, (ExecutionEngine *engine, const Value &value));
- RUNTIME_METHOD(ReturnedValue, unwindException, (ExecutionEngine *engine));
- RUNTIME_METHOD(void, pushWithScope, (const Value &o, NoThrowEngine *engine));
- RUNTIME_METHOD(void, pushCatchScope, (NoThrowEngine *engine, int exceptionVarNameIndex));
- RUNTIME_METHOD(void, popScope, (NoThrowEngine *engine));
-
- // closures
- RUNTIME_METHOD(ReturnedValue, closure, (ExecutionEngine *engine, int functionId));
+ Runtime();
- // function header
- RUNTIME_METHOD(void, declareVar, (ExecutionEngine *engine, bool deletable, int nameIndex));
- RUNTIME_METHOD(ReturnedValue, setupArgumentsObject, (ExecutionEngine *engine));
- RUNTIME_METHOD(void, convertThisToObject, (ExecutionEngine *engine));
-
- // literals
- RUNTIME_METHOD(ReturnedValue, arrayLiteral, (ExecutionEngine *engine, Value *values, uint length));
- RUNTIME_METHOD(ReturnedValue, objectLiteral, (ExecutionEngine *engine, const Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags));
- RUNTIME_METHOD(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id));
-
- // foreach
- RUNTIME_METHOD(ReturnedValue, foreachIterator, (ExecutionEngine *engine, const Value &in));
- RUNTIME_METHOD(ReturnedValue, foreachNextPropertyName, (const Value &foreach_iterator));
-
- // unary operators
typedef ReturnedValue (*UnaryOperation)(const Value &value);
- RUNTIME_METHOD(ReturnedValue, uPlus, (const Value &value));
- RUNTIME_METHOD(ReturnedValue, uMinus, (const Value &value));
- RUNTIME_METHOD(ReturnedValue, uNot, (const Value &value));
- RUNTIME_METHOD(ReturnedValue, complement, (const Value &value));
- RUNTIME_METHOD(ReturnedValue, increment, (const Value &value));
- RUNTIME_METHOD(ReturnedValue, decrement, (const Value &value));
-
- // binary operators
typedef ReturnedValue (*BinaryOperation)(const Value &left, const Value &right);
typedef ReturnedValue (*BinaryOperationContext)(ExecutionEngine *engine, const Value &left, const Value &right);
- RUNTIME_METHOD(ReturnedValue, instanceof, (ExecutionEngine *engine, const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, in, (ExecutionEngine *engine, const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, add, (ExecutionEngine *engine, const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, addString, (ExecutionEngine *engine, const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, bitOr, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, bitXor, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, bitAnd, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, sub, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, mul, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, div, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, mod, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, shl, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, shr, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, ushr, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, greaterThan, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, lessThan, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, greaterEqual, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, lessEqual, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, equal, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, notEqual, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, strictEqual, (const Value &left, const Value &right));
- RUNTIME_METHOD(ReturnedValue, strictNotEqual, (const Value &left, const Value &right));
-
- // comparisons
- RUNTIME_METHOD(Bool, compareGreaterThan, (const Value &l, const Value &r));
- RUNTIME_METHOD(Bool, compareLessThan, (const Value &l, const Value &r));
- RUNTIME_METHOD(Bool, compareGreaterEqual, (const Value &l, const Value &r));
- RUNTIME_METHOD(Bool, compareLessEqual, (const Value &l, const Value &r));
- RUNTIME_METHOD(Bool, compareEqual, (const Value &left, const Value &right));
- RUNTIME_METHOD(Bool, compareNotEqual, (const Value &left, const Value &right));
- RUNTIME_METHOD(Bool, compareStrictEqual, (const Value &left, const Value &right));
- RUNTIME_METHOD(Bool, compareStrictNotEqual, (const Value &left, const Value &right));
+#define DEFINE_RUNTIME_METHOD_ENUM(returnvalue, name, args) name,
+ enum RuntimeMethods {
+ FOR_EACH_RUNTIME_METHOD(DEFINE_RUNTIME_METHOD_ENUM)
+ RuntimeMethodCount,
+ InvalidRuntimeMethod = RuntimeMethodCount
+ };
+#undef DEFINE_RUNTIME_METHOD_ENUM
- RUNTIME_METHOD(Bool, compareInstanceof, (ExecutionEngine *engine, const Value &left, const Value &right));
- RUNTIME_METHOD(Bool, compareIn, (ExecutionEngine *engine, const Value &left, const Value &right));
+ void *runtimeMethods[RuntimeMethodCount];
- // conversions
- RUNTIME_METHOD(Bool, toBoolean, (const Value &value));
- RUNTIME_METHOD(ReturnedValue, toDouble, (const Value &value));
- RUNTIME_METHOD(int, toInt, (const Value &value));
- RUNTIME_METHOD(int, doubleToInt, (const double &d));
- RUNTIME_METHOD(unsigned, toUInt, (const Value &value));
- RUNTIME_METHOD(unsigned, doubleToUInt, (const double &d));
+ static uint runtimeMethodOffset(RuntimeMethods method) { return method*QT_POINTER_SIZE; }
- // qml
- RUNTIME_METHOD(ReturnedValue, getQmlContext, (NoThrowEngine *engine));
- RUNTIME_METHOD(ReturnedValue, getQmlImportedScripts, (NoThrowEngine *engine));
- RUNTIME_METHOD(ReturnedValue, getQmlSingleton, (NoThrowEngine *engine, int nameIndex));
- RUNTIME_METHOD(ReturnedValue, getQmlAttachedProperty, (ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex));
- RUNTIME_METHOD(ReturnedValue, getQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired));
- RUNTIME_METHOD(ReturnedValue, getQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired));
- RUNTIME_METHOD(ReturnedValue, getQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired));
- RUNTIME_METHOD(ReturnedValue, getQmlSingletonQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired));
- RUNTIME_METHOD(ReturnedValue, getQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index));
+#define RUNTIME_METHOD(returnvalue, name, args) \
+ typedef returnvalue (*Method_##name)args; \
+ enum { Method_##name##_NeedsExceptionCheck = ExceptionCheck<Method_##name>::NeedsCheck }; \
+ static returnvalue method_##name args;
+ FOR_EACH_RUNTIME_METHOD(RUNTIME_METHOD)
+#undef RUNTIME_METHOD
- RUNTIME_METHOD(void, setQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value));
- RUNTIME_METHOD(void, setQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value));
- RUNTIME_METHOD(void, setQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value));
};
-#undef RUNTIME_METHOD
-#undef INIT_RUNTIME_METHOD
+static_assert(std::is_standard_layout<Runtime>::value, "Runtime needs to be standard layout in order for us to be able to use offsetof");
+static_assert(offsetof(Runtime, runtimeMethods) == 0, "JIT expects this to be the first member");
+static_assert(sizeof(Runtime::BinaryOperation) == sizeof(void*), "JIT expects a function pointer to fit into a regular pointer, for cross-compilation offset translation");
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 6775028272..894434be16 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -366,7 +366,7 @@ struct Scoped
struct ScopedCallData {
ScopedCallData(const Scope &scope, int argc = 0)
{
- int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value);
+ int size = qMax(argc, QV4::Global::ReservedArgumentCount + int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)));
ptr = reinterpret_cast<CallData *>(scope.alloc(size));
ptr->tag = QV4::Value::Integer_Type_Internal;
ptr->argc = argc;
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index f96f0254a5..4ebe2dd609 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -72,7 +72,7 @@ struct ContextStateSaver {
bool strictMode;
Lookup *lookups;
const QV4::Value *constantTable;
- CompiledData::CompilationUnit *compilationUnit;
+ CompiledData::CompilationUnitBase *compilationUnit;
int lineNumber;
ContextStateSaver(const Scope &scope, ExecutionContext *context)
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 4ff0565f9b..5662432f0d 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -68,8 +68,6 @@ namespace Heap {
struct Base;
}
-typedef uint Bool;
-
struct Q_QML_PRIVATE_EXPORT Value
{
private:
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index be2772c23f..075a9a4a5d 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -404,7 +404,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
Q_ALLOCA_VAR(QV4::Value*, scopes, sizeof(QV4::Value *)*(2 + 2*scopeDepth));
{
- scopes[0] = const_cast<QV4::Value *>(context->d()->compilationUnit->constants);
+ scopes[0] = const_cast<QV4::Value *>(static_cast<CompiledData::CompilationUnit*>(context->d()->compilationUnit)->constants);
// stack gets setup in push instruction
scopes[1] = 0;
QV4::Heap::ExecutionContext *scope = context->d();
@@ -451,16 +451,16 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_BEGIN_INSTR(LoadRegExp)
// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
- VALUE(instr.result) = context->d()->compilationUnit->runtimeRegularExpressions[instr.regExpId];
+ VALUE(instr.result) = static_cast<CompiledData::CompilationUnit*>(context->d()->compilationUnit)->runtimeRegularExpressions[instr.regExpId];
MOTH_END_INSTR(LoadRegExp)
MOTH_BEGIN_INSTR(LoadClosure)
- STOREVALUE(instr.result, engine->runtime.closure(engine, instr.value));
+ STOREVALUE(instr.result, Runtime::method_closure(engine, instr.value));
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
- STOREVALUE(instr.result, engine->runtime.getActivationProperty(engine, instr.name));
+ STOREVALUE(instr.result, Runtime::method_getActivationProperty(engine, instr.name));
MOTH_END_INSTR(LoadName)
MOTH_BEGIN_INSTR(GetGlobalLookup)
@@ -470,12 +470,12 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_BEGIN_INSTR(StoreName)
TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
- engine->runtime.setActivationProperty(engine, instr.name, VALUE(instr.source));
+ Runtime::method_setActivationProperty(engine, instr.name, VALUE(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
- STOREVALUE(instr.result, engine->runtime.getElement(engine, VALUE(instr.base), VALUE(instr.index)));
+ STOREVALUE(instr.result, Runtime::method_getElement(engine, VALUE(instr.base), VALUE(instr.index)));
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(LoadElementLookup)
@@ -484,7 +484,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(LoadElementLookup)
MOTH_BEGIN_INSTR(StoreElement)
- engine->runtime.setElement(engine, VALUE(instr.base), VALUE(instr.index), VALUE(instr.source));
+ Runtime::method_setElement(engine, VALUE(instr.base), VALUE(instr.index), VALUE(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElement)
@@ -495,7 +495,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(StoreElementLookup)
MOTH_BEGIN_INSTR(LoadProperty)
- STOREVALUE(instr.result, engine->runtime.getProperty(engine, VALUE(instr.base), instr.name));
+ STOREVALUE(instr.result, Runtime::method_getProperty(engine, VALUE(instr.base), instr.name));
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(GetLookup)
@@ -504,7 +504,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(GetLookup)
MOTH_BEGIN_INSTR(StoreProperty)
- engine->runtime.setProperty(engine, VALUE(instr.base), instr.name, VALUE(instr.source));
+ Runtime::method_setProperty(engine, VALUE(instr.base), instr.name, VALUE(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreProperty)
@@ -515,42 +515,42 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(SetLookup)
MOTH_BEGIN_INSTR(StoreQObjectProperty)
- engine->runtime.setQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
+ Runtime::method_setQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreQObjectProperty)
MOTH_BEGIN_INSTR(LoadQObjectProperty)
- STOREVALUE(instr.result, engine->runtime.getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STOREVALUE(instr.result, Runtime::method_getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
MOTH_END_INSTR(LoadQObjectProperty)
MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
- engine->runtime.setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
+ Runtime::method_setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreScopeObjectProperty)
MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
- STOREVALUE(instr.result, engine->runtime.getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STOREVALUE(instr.result, Runtime::method_getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
MOTH_END_INSTR(LoadScopeObjectProperty)
MOTH_BEGIN_INSTR(StoreContextObjectProperty)
- engine->runtime.setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
+ Runtime::method_setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreContextObjectProperty)
MOTH_BEGIN_INSTR(LoadContextObjectProperty)
- STOREVALUE(instr.result, engine->runtime.getQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STOREVALUE(instr.result, Runtime::method_getQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
MOTH_END_INSTR(LoadContextObjectProperty)
MOTH_BEGIN_INSTR(LoadIdObject)
- STOREVALUE(instr.result, engine->runtime.getQmlIdObject(engine, VALUE(instr.base), instr.index));
+ STOREVALUE(instr.result, Runtime::method_getQmlIdObject(engine, VALUE(instr.base), instr.index));
MOTH_END_INSTR(LoadIdObject)
MOTH_BEGIN_INSTR(LoadAttachedQObjectProperty)
- STOREVALUE(instr.result, engine->runtime.getQmlAttachedProperty(engine, instr.attachedPropertiesId, instr.propertyIndex));
+ STOREVALUE(instr.result, Runtime::method_getQmlAttachedProperty(engine, instr.attachedPropertiesId, instr.propertyIndex));
MOTH_END_INSTR(LoadAttachedQObjectProperty)
MOTH_BEGIN_INSTR(LoadSingletonQObjectProperty)
- STOREVALUE(instr.result, engine->runtime.getQmlSingletonQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STOREVALUE(instr.result, Runtime::method_getQmlSingletonQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
MOTH_END_INSTR(LoadSingletonQObjectProperty)
MOTH_BEGIN_INSTR(Push)
@@ -571,73 +571,73 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
}
}
#endif // DO_TRACE_INSTR
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, engine->runtime.callValue(engine, VALUE(instr.dest), callData));
+ STOREVALUE(instr.result, Runtime::method_callValue(engine, VALUE(instr.dest), callData));
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, engine->runtime.callProperty(engine, instr.name, callData));
+ STOREVALUE(instr.result, Runtime::method_callProperty(engine, instr.name, callData));
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallPropertyLookup)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, engine->runtime.callPropertyLookup(engine, instr.lookupIndex, callData));
+ STOREVALUE(instr.result, Runtime::method_callPropertyLookup(engine, instr.lookupIndex, callData));
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallScopeObjectProperty)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, engine->runtime.callQmlScopeObjectProperty(engine, instr.index, callData));
+ STOREVALUE(instr.result, Runtime::method_callQmlScopeObjectProperty(engine, instr.index, callData));
MOTH_END_INSTR(CallScopeObjectProperty)
MOTH_BEGIN_INSTR(CallContextObjectProperty)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, engine->runtime.callQmlContextObjectProperty(engine, instr.index, callData));
+ STOREVALUE(instr.result, Runtime::method_callQmlContextObjectProperty(engine, instr.index, callData));
MOTH_END_INSTR(CallContextObjectProperty)
MOTH_BEGIN_INSTR(CallElement)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, engine->runtime.callElement(engine, VALUE(instr.index), callData));
+ STOREVALUE(instr.result, Runtime::method_callElement(engine, VALUE(instr.index), callData));
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallActivationProperty)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, engine->runtime.callActivationProperty(engine, instr.name, callData));
+ STOREVALUE(instr.result, Runtime::method_callActivationProperty(engine, instr.name, callData));
MOTH_END_INSTR(CallActivationProperty)
MOTH_BEGIN_INSTR(CallGlobalLookup)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
@@ -650,141 +650,141 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(SetExceptionHandler)
MOTH_BEGIN_INSTR(CallBuiltinThrow)
- engine->runtime.throwException(engine, VALUE(instr.arg));
+ Runtime::method_throwException(engine, VALUE(instr.arg));
CHECK_EXCEPTION;
MOTH_END_INSTR(CallBuiltinThrow)
MOTH_BEGIN_INSTR(CallBuiltinUnwindException)
- STOREVALUE(instr.result, engine->runtime.unwindException(engine));
+ STOREVALUE(instr.result, Runtime::method_unwindException(engine));
MOTH_END_INSTR(CallBuiltinUnwindException)
MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope)
- engine->runtime.pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
+ Runtime::method_pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
context = engine->currentContext;
MOTH_END_INSTR(CallBuiltinPushCatchScope)
MOTH_BEGIN_INSTR(CallBuiltinPushScope)
- engine->runtime.pushWithScope(VALUE(instr.arg), static_cast<QV4::NoThrowEngine*>(engine));
+ Runtime::method_pushWithScope(VALUE(instr.arg), static_cast<QV4::NoThrowEngine*>(engine));
context = engine->currentContext;
CHECK_EXCEPTION;
MOTH_END_INSTR(CallBuiltinPushScope)
MOTH_BEGIN_INSTR(CallBuiltinPopScope)
- engine->runtime.popScope(static_cast<QV4::NoThrowEngine*>(engine));
+ Runtime::method_popScope(static_cast<QV4::NoThrowEngine*>(engine));
context = engine->currentContext;
MOTH_END_INSTR(CallBuiltinPopScope)
MOTH_BEGIN_INSTR(CallBuiltinForeachIteratorObject)
- STOREVALUE(instr.result, engine->runtime.foreachIterator(engine, VALUE(instr.arg)));
+ STOREVALUE(instr.result, Runtime::method_foreachIterator(engine, VALUE(instr.arg)));
MOTH_END_INSTR(CallBuiltinForeachIteratorObject)
MOTH_BEGIN_INSTR(CallBuiltinForeachNextPropertyName)
- STOREVALUE(instr.result, engine->runtime.foreachNextPropertyName(VALUE(instr.arg)));
+ STOREVALUE(instr.result, Runtime::method_foreachNextPropertyName(VALUE(instr.arg)));
MOTH_END_INSTR(CallBuiltinForeachNextPropertyName)
MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
- STOREVALUE(instr.result, engine->runtime.deleteMember(engine, VALUE(instr.base), instr.member));
+ STOREVALUE(instr.result, Runtime::method_deleteMember(engine, VALUE(instr.base), instr.member));
MOTH_END_INSTR(CallBuiltinDeleteMember)
MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
- STOREVALUE(instr.result, engine->runtime.deleteElement(engine, VALUE(instr.base), VALUE(instr.index)));
+ STOREVALUE(instr.result, Runtime::method_deleteElement(engine, VALUE(instr.base), VALUE(instr.index)));
MOTH_END_INSTR(CallBuiltinDeleteSubscript)
MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
- STOREVALUE(instr.result, engine->runtime.deleteName(engine, instr.name));
+ STOREVALUE(instr.result, Runtime::method_deleteName(engine, instr.name));
MOTH_END_INSTR(CallBuiltinDeleteName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofScopeObjectProperty)
- STOREVALUE(instr.result, engine->runtime.typeofScopeObjectProperty(engine, VALUE(instr.base), instr.index));
+ STOREVALUE(instr.result, Runtime::method_typeofScopeObjectProperty(engine, VALUE(instr.base), instr.index));
MOTH_END_INSTR(CallBuiltinTypeofMember)
MOTH_BEGIN_INSTR(CallBuiltinTypeofContextObjectProperty)
- STOREVALUE(instr.result, engine->runtime.typeofContextObjectProperty(engine, VALUE(instr.base), instr.index));
+ STOREVALUE(instr.result, Runtime::method_typeofContextObjectProperty(engine, VALUE(instr.base), instr.index));
MOTH_END_INSTR(CallBuiltinTypeofMember)
MOTH_BEGIN_INSTR(CallBuiltinTypeofMember)
- STOREVALUE(instr.result, engine->runtime.typeofMember(engine, VALUE(instr.base), instr.member));
+ STOREVALUE(instr.result, Runtime::method_typeofMember(engine, VALUE(instr.base), instr.member));
MOTH_END_INSTR(CallBuiltinTypeofMember)
MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript)
- STOREVALUE(instr.result, engine->runtime.typeofElement(engine, VALUE(instr.base), VALUE(instr.index)));
+ STOREVALUE(instr.result, Runtime::method_typeofElement(engine, VALUE(instr.base), VALUE(instr.index)));
MOTH_END_INSTR(CallBuiltinTypeofSubscript)
MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
- STOREVALUE(instr.result, engine->runtime.typeofName(engine, instr.name));
+ STOREVALUE(instr.result, Runtime::method_typeofName(engine, instr.name));
MOTH_END_INSTR(CallBuiltinTypeofName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
- STOREVALUE(instr.result, engine->runtime.typeofValue(engine, VALUE(instr.value)));
+ STOREVALUE(instr.result, Runtime::method_typeofValue(engine, VALUE(instr.value)));
MOTH_END_INSTR(CallBuiltinTypeofValue)
MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
- engine->runtime.declareVar(engine, instr.isDeletable, instr.varName);
+ Runtime::method_declareVar(engine, instr.isDeletable, instr.varName);
MOTH_END_INSTR(CallBuiltinDeclareVar)
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
Q_ASSERT(instr.args + instr.argc <= stackSize);
QV4::Value *args = stack + instr.args;
- STOREVALUE(instr.result, engine->runtime.arrayLiteral(engine, args, instr.argc));
+ STOREVALUE(instr.result, Runtime::method_arrayLiteral(engine, args, instr.argc));
MOTH_END_INSTR(CallBuiltinDefineArray)
MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
QV4::Value *args = stack + instr.args;
- STOREVALUE(instr.result, engine->runtime.objectLiteral(engine, args, instr.internalClassId, instr.arrayValueCount, instr.arrayGetterSetterCountAndFlags));
+ STOREVALUE(instr.result, Runtime::method_objectLiteral(engine, args, instr.internalClassId, instr.arrayValueCount, instr.arrayGetterSetterCountAndFlags));
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject)
- STOREVALUE(instr.result, engine->runtime.setupArgumentsObject(engine));
+ STOREVALUE(instr.result, Runtime::method_setupArgumentsObject(engine));
MOTH_END_INSTR(CallBuiltinSetupArgumentsObject)
MOTH_BEGIN_INSTR(CallBuiltinConvertThisToObject)
- engine->runtime.convertThisToObject(engine);
+ Runtime::method_convertThisToObject(engine);
CHECK_EXCEPTION;
MOTH_END_INSTR(CallBuiltinConvertThisToObject)
MOTH_BEGIN_INSTR(CreateValue)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, engine->runtime.constructValue(engine, VALUE(instr.func), callData));
+ STOREVALUE(instr.result, Runtime::method_constructValue(engine, VALUE(instr.func), callData));
MOTH_END_INSTR(CreateValue)
MOTH_BEGIN_INSTR(CreateProperty)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, engine->runtime.constructProperty(engine, instr.name, callData));
+ STOREVALUE(instr.result, Runtime::method_constructProperty(engine, instr.name, callData));
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(ConstructPropertyLookup)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, engine->runtime.constructPropertyLookup(engine, instr.index, callData));
+ STOREVALUE(instr.result, Runtime::method_constructPropertyLookup(engine, instr.index, callData));
MOTH_END_INSTR(ConstructPropertyLookup)
MOTH_BEGIN_INSTR(CreateActivationProperty)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, engine->runtime.constructActivationProperty(engine, instr.name, callData));
+ STOREVALUE(instr.result, Runtime::method_constructActivationProperty(engine, instr.name, callData));
MOTH_END_INSTR(CreateActivationProperty)
MOTH_BEGIN_INSTR(ConstructGlobalLookup)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type_Internal;
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, engine->runtime.constructGlobalLookup(engine, instr.index, callData));
+ STOREVALUE(instr.result, Runtime::method_constructGlobalLookup(engine, instr.index, callData));
MOTH_END_INSTR(ConstructGlobalLookup)
MOTH_BEGIN_INSTR(Jump)
@@ -806,7 +806,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(JumpNe)
MOTH_BEGIN_INSTR(UNot)
- STOREVALUE(instr.result, engine->runtime.uNot(VALUE(instr.source)));
+ STOREVALUE(instr.result, Runtime::method_uNot(VALUE(instr.source)));
MOTH_END_INSTR(UNot)
MOTH_BEGIN_INSTR(UNotBool)
@@ -815,15 +815,15 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(UNotBool)
MOTH_BEGIN_INSTR(UPlus)
- STOREVALUE(instr.result, engine->runtime.uPlus(VALUE(instr.source)));
+ STOREVALUE(instr.result, Runtime::method_uPlus(VALUE(instr.source)));
MOTH_END_INSTR(UPlus)
MOTH_BEGIN_INSTR(UMinus)
- STOREVALUE(instr.result, engine->runtime.uMinus(VALUE(instr.source)));
+ STOREVALUE(instr.result, Runtime::method_uMinus(VALUE(instr.source)));
MOTH_END_INSTR(UMinus)
MOTH_BEGIN_INSTR(UCompl)
- STOREVALUE(instr.result, engine->runtime.complement(VALUE(instr.source)));
+ STOREVALUE(instr.result, Runtime::method_complement(VALUE(instr.source)));
MOTH_END_INSTR(UCompl)
MOTH_BEGIN_INSTR(UComplInt)
@@ -831,32 +831,32 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(UComplInt)
MOTH_BEGIN_INSTR(Increment)
- STOREVALUE(instr.result, engine->runtime.increment(VALUE(instr.source)));
+ STOREVALUE(instr.result, Runtime::method_increment(VALUE(instr.source)));
MOTH_END_INSTR(Increment)
MOTH_BEGIN_INSTR(Decrement)
- STOREVALUE(instr.result, engine->runtime.decrement(VALUE(instr.source)));
+ STOREVALUE(instr.result, Runtime::method_decrement(VALUE(instr.source)));
MOTH_END_INSTR(Decrement)
MOTH_BEGIN_INSTR(Binop)
- QV4::Runtime::BinaryOperation op = *reinterpret_cast<QV4::Runtime::BinaryOperation *>(reinterpret_cast<char *>(&engine->runtime) + instr.alu);
+ QV4::Runtime::BinaryOperation op = *reinterpret_cast<QV4::Runtime::BinaryOperation *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu]));
STOREVALUE(instr.result, op(VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(Binop)
MOTH_BEGIN_INSTR(Add)
- STOREVALUE(instr.result, engine->runtime.add(engine, VALUE(instr.lhs), VALUE(instr.rhs)));
+ STOREVALUE(instr.result, Runtime::method_add(engine, VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(Add)
MOTH_BEGIN_INSTR(BitAnd)
- STOREVALUE(instr.result, engine->runtime.bitAnd(VALUE(instr.lhs), VALUE(instr.rhs)));
+ STOREVALUE(instr.result, Runtime::method_bitAnd(VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(BitAnd)
MOTH_BEGIN_INSTR(BitOr)
- STOREVALUE(instr.result, engine->runtime.bitOr(VALUE(instr.lhs), VALUE(instr.rhs)));
+ STOREVALUE(instr.result, Runtime::method_bitOr(VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(BitOr)
MOTH_BEGIN_INSTR(BitXor)
- STOREVALUE(instr.result, engine->runtime.bitXor(VALUE(instr.lhs), VALUE(instr.rhs)));
+ STOREVALUE(instr.result, Runtime::method_bitXor(VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(BitXor)
MOTH_BEGIN_INSTR(Shr)
@@ -891,15 +891,15 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(ShlConst)
MOTH_BEGIN_INSTR(Mul)
- STOREVALUE(instr.result, engine->runtime.mul(VALUE(instr.lhs), VALUE(instr.rhs)));
+ STOREVALUE(instr.result, Runtime::method_mul(VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(Mul)
MOTH_BEGIN_INSTR(Sub)
- STOREVALUE(instr.result, engine->runtime.sub(VALUE(instr.lhs), VALUE(instr.rhs)));
+ STOREVALUE(instr.result, Runtime::method_sub(VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(Sub)
MOTH_BEGIN_INSTR(BinopContext)
- QV4::Runtime::BinaryOperationContext op = *reinterpret_cast<QV4::Runtime::BinaryOperationContext *>(reinterpret_cast<char *>(&engine->runtime) + instr.alu);
+ QV4::Runtime::BinaryOperationContext op = *reinterpret_cast<QV4::Runtime::BinaryOperationContext *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu]));
STOREVALUE(instr.result, op(engine, VALUE(instr.lhs), VALUE(instr.rhs)));
MOTH_END_INSTR(BinopContext)
@@ -930,15 +930,15 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
MOTH_END_INSTR(LoadThis)
MOTH_BEGIN_INSTR(LoadQmlContext)
- VALUE(instr.result) = engine->runtime.getQmlContext(static_cast<QV4::NoThrowEngine*>(engine));
+ VALUE(instr.result) = Runtime::method_getQmlContext(static_cast<QV4::NoThrowEngine*>(engine));
MOTH_END_INSTR(LoadQmlContext)
MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
- VALUE(instr.result) = engine->runtime.getQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine));
+ VALUE(instr.result) = Runtime::method_getQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine));
MOTH_END_INSTR(LoadQmlImportedScripts)
MOTH_BEGIN_INSTR(LoadQmlSingleton)
- VALUE(instr.result) = engine->runtime.getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
+ VALUE(instr.result) = Runtime::method_getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
MOTH_END_INSTR(LoadQmlSingleton)
#ifdef MOTH_THREADED_INTERPRETER
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index a8acab21ea..173c0a3e20 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -160,6 +160,12 @@ struct Q_QML_EXPORT Base {
#endif
};
V4_ASSERT_IS_TRIVIAL(Base)
+// This class needs to consist only of pointer sized members to allow
+// for a size/offset translation when cross-compiling between 32- and
+// 64-bit.
+Q_STATIC_ASSERT(std::is_standard_layout<Base>::value);
+Q_STATIC_ASSERT(offsetof(Base, vt) == 0);
+Q_STATIC_ASSERT(sizeof(Base) == QT_POINTER_SIZE);
template <typename T>
struct Pointer {
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index a829e902fb..27adfcb517 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -113,14 +113,16 @@ struct MemorySegment {
pageReservation = PageReservation::reserve(size, OSAllocator::JSGCHeapPages);
base = reinterpret_cast<Chunk *>((reinterpret_cast<quintptr>(pageReservation.base()) + Chunk::ChunkSize - 1) & ~(Chunk::ChunkSize - 1));
nChunks = NumChunks;
- if (base != pageReservation.base())
+ availableBytes = size - (reinterpret_cast<quintptr>(base) - reinterpret_cast<quintptr>(pageReservation.base()));
+ if (availableBytes < SegmentSize)
--nChunks;
}
MemorySegment(MemorySegment &&other) {
qSwap(pageReservation, other.pageReservation);
qSwap(base, other.base);
- qSwap(nChunks, other.nChunks);
qSwap(allocatedMap, other.allocatedMap);
+ qSwap(availableBytes, other.availableBytes);
+ qSwap(nChunks, other.nChunks);
}
~MemorySegment() {
@@ -150,7 +152,7 @@ struct MemorySegment {
void free(Chunk *chunk, size_t size) {
DEBUG << "freeing chunk" << chunk;
size_t index = static_cast<size_t>(chunk - base);
- size_t end = index + (size - 1)/Chunk::ChunkSize + 1;
+ size_t end = qMin(static_cast<size_t>(NumChunks), index + (size - 1)/Chunk::ChunkSize + 1);
while (index < end) {
Q_ASSERT(testBit(index));
clearBit(index);
@@ -169,11 +171,19 @@ struct MemorySegment {
PageReservation pageReservation;
Chunk *base = 0;
quint64 allocatedMap = 0;
+ size_t availableBytes = 0;
uint nChunks = 0;
};
Chunk *MemorySegment::allocate(size_t size)
{
+ if (!allocatedMap && size >= SegmentSize) {
+ // chunk allocated for one huge allocation
+ Q_ASSERT(availableBytes >= size);
+ pageReservation.commit(base, size);
+ allocatedMap = ~static_cast<quintptr>(0);
+ return base;
+ }
size_t requiredChunks = (size + sizeof(Chunk) - 1)/sizeof(Chunk);
uint sequence = 0;
Chunk *candidate = 0;
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
index 588ae21ee0..db0ffe11a2 100644
--- a/src/qml/memory/qv4mmdefs_p.h
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -51,6 +51,7 @@
//
#include <private/qv4global_p.h>
+#include <private/qv4runtimeapi_p.h>
#include <QtCore/qalgorithms.h>
#include <qdebug.h>
@@ -255,6 +256,33 @@ Q_STATIC_ASSERT(sizeof(HeapItem) == Chunk::SlotSize);
Q_STATIC_ASSERT(QT_POINTER_SIZE*8 == Chunk::Bits);
Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits);
+// Base class for the execution engine
+
+#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
+#pragma pack(push, 1)
+#endif
+struct EngineBase {
+ Heap::ExecutionContext *current = 0;
+
+ Value *jsStackTop = 0;
+ quint32 hasException = false;
+#if QT_POINTER_SIZE == 8
+ quint8 padding[4];
+#endif
+ MemoryManager *memoryManager = 0;
+ Runtime runtime;
+};
+#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
+#pragma pack(pop)
+#endif
+
+Q_STATIC_ASSERT(std::is_standard_layout<EngineBase>::value);
+Q_STATIC_ASSERT(offsetof(EngineBase, current) == 0);
+Q_STATIC_ASSERT(offsetof(EngineBase, jsStackTop) == offsetof(EngineBase, current) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(EngineBase, hasException) == offsetof(EngineBase, jsStackTop) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(EngineBase, memoryManager) == offsetof(EngineBase, hasException) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(EngineBase, runtime) == offsetof(EngineBase, memoryManager) + QT_POINTER_SIZE);
+
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index bd6b9a1599..bb9b69c479 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1971,7 +1971,9 @@ QString QQmlMetaType::prettyTypeName(const QObject *object)
const int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
if (lastSlash != -1)
typeName = typeName.mid(lastSlash + 1);
- } else {
+ }
+
+ if (typeName.isEmpty()) {
typeName = QString::fromUtf8(object->metaObject()->className());
int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
if (marker != -1)
@@ -1982,10 +1984,12 @@ QString QQmlMetaType::prettyTypeName(const QObject *object)
typeName = typeName.leftRef(marker) + QLatin1Char('*');
type = QQmlMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
if (type) {
- typeName = type->qmlTypeName();
- const int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
+ QString qmlTypeName = type->qmlTypeName();
+ const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char('/'));
if (lastSlash != -1)
- typeName = typeName.mid(lastSlash + 1);
+ qmlTypeName = qmlTypeName.mid(lastSlash + 1);
+ if (!qmlTypeName.isEmpty())
+ typeName = qmlTypeName;
}
}
}
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index a2b82101dd..f115d4227c 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -80,10 +80,6 @@
# define NAME_MAX _POSIX_SYMLINK_MAX
#endif
-// LSB has a broken version of qOffsetOf that can't be used at compile time
-// https://lsbbugs.linuxfoundation.org/show_bug.cgi?id=3462
-#undef qOffsetOf
-#define qOffsetOf(TYPE, MEMBER) __builtin_qOffsetOf (TYPE, MEMBER)
#endif
// #define DATABLOB_DEBUG
@@ -1249,20 +1245,20 @@ void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface,
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QByteArray &data)
{
QML_MEMORY_SCOPE_URL(blob->url());
- QQmlDataBlob::Data d;
- d.d = &data;
+ QQmlDataBlob::SourceCodeData d;
+ d.inlineSourceCode = QString::fromUtf8(data);
setData(blob, d);
}
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName)
{
QML_MEMORY_SCOPE_URL(blob->url());
- QQmlDataBlob::Data d;
- d.d = &fileName;
+ QQmlDataBlob::SourceCodeData d;
+ d.fileInfo = QFileInfo(fileName);
setData(blob, d);
}
-void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d)
+void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeData &d)
{
QML_MEMORY_SCOPE_URL(blob->url());
QQmlCompilingProfiler prof(QQmlEnginePrivate::get(engine())->profiler, blob);
@@ -2080,7 +2076,7 @@ bool QQmlTypeData::tryLoadFromDiskCache()
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
{
QString error;
- if (!unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) {
+ if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), v4->iselFactory.data(), &error)) {
qCDebug(DBG_DISK_CACHE) << "Error loading" << url().toString() << "from disk cache:" << error;
return false;
}
@@ -2273,7 +2269,7 @@ void QQmlTypeData::done()
qCDebug(DBG_DISK_CACHE) << "Checksum mismatch for cached version of" << m_compiledData->url().toString();
if (!loadFromSource())
return;
- m_backupSourceCode.clear();
+ m_backupSourceCode = SourceCodeData();
m_compiledData = nullptr;
}
@@ -2380,13 +2376,9 @@ bool QQmlTypeData::loadImplicitImport()
return true;
}
-void QQmlTypeData::dataReceived(const Data &data)
+void QQmlTypeData::dataReceived(const SourceCodeData &data)
{
- QString error;
- m_backupSourceCode = data.readAll(&error, &m_sourceTimeStamp);
- // if we failed to read the source code, process it _after_ we've tried
- // to use the disk cache, in order to support scenarios where the source
- // was removed deliberately.
+ m_backupSourceCode = data;
if (tryLoadFromDiskCache())
return;
@@ -2394,8 +2386,8 @@ void QQmlTypeData::dataReceived(const Data &data)
if (isError())
return;
- if (!error.isEmpty()) {
- setError(error);
+ if (!m_backupSourceCode.exists()) {
+ setError(QQmlTypeLoader::tr("No such file or directory"));
return;
}
@@ -2414,12 +2406,19 @@ void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *un
bool QQmlTypeData::loadFromSource()
{
- QString code = QString::fromUtf8(m_backupSourceCode);
m_document.reset(new QmlIR::Document(isDebugging()));
- m_document->jsModule.sourceTimeStamp = m_sourceTimeStamp;
+ m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp();
QQmlEngine *qmlEngine = typeLoader()->engine();
QmlIR::IRBuilder compiler(QV8Engine::get(qmlEngine)->illegalNames());
- if (!compiler.generateFromQml(code, finalUrlString(), m_document.data())) {
+
+ QString sourceError;
+ const QString source = m_backupSourceCode.readAll(&sourceError);
+ if (!sourceError.isEmpty()) {
+ setError(sourceError);
+ return false;
+ }
+
+ if (!compiler.generateFromQml(source, finalUrlString(), m_document.data())) {
QList<QQmlError> errors;
errors.reserve(compiler.errors.count());
for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) {
@@ -2558,7 +2557,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach
QString errorString;
if (m_compiledData->saveToDisk(url(), &errorString)) {
QString error;
- if (!m_compiledData->loadFromDisk(url(), enginePrivate->v4engine()->iselFactory.data(), &error)) {
+ if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), enginePrivate->v4engine()->iselFactory.data(), &error)) {
// ignore error, keep using the in-memory compilation unit.
}
} else {
@@ -2915,14 +2914,14 @@ struct EmptyCompilationUnit : public QV4::CompiledData::CompilationUnit
void linkBackendToEngine(QV4::ExecutionEngine *) override {}
};
-void QQmlScriptBlob::dataReceived(const Data &data)
+void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine());
if (!disableDiskCache() || forceDiskCache()) {
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
QString error;
- if (unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) {
+ if (unit->loadFromDisk(url(), data.sourceTimeStamp(), v4->iselFactory.data(), &error)) {
initializeFromCompilationUnit(unit);
return;
} else {
@@ -2933,8 +2932,9 @@ void QQmlScriptBlob::dataReceived(const Data &data)
QmlIR::Document irUnit(isDebugging());
+ irUnit.jsModule.sourceTimeStamp = data.sourceTimeStamp();
QString error;
- QString source = QString::fromUtf8(data.readAll(&error, &irUnit.jsModule.sourceTimeStamp));
+ QString source = data.readAll(&error);
if (!error.isEmpty()) {
setError(error);
return;
@@ -3097,10 +3097,10 @@ void QQmlQmldirData::setPriority(int priority)
m_priority = priority;
}
-void QQmlQmldirData::dataReceived(const Data &data)
+void QQmlQmldirData::dataReceived(const SourceCodeData &data)
{
QString error;
- m_content = QString::fromUtf8(data.readAll(&error));
+ m_content = data.readAll(&error);
if (!error.isEmpty()) {
setError(error);
return;
@@ -3112,34 +3112,54 @@ void QQmlQmldirData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *
Q_UNIMPLEMENTED();
}
-QByteArray QQmlDataBlob::Data::readAll(QString *error, qint64 *sourceTimeStamp) const
+QString QQmlDataBlob::SourceCodeData::readAll(QString *error) const
{
- Q_ASSERT(!d.isNull());
error->clear();
- if (d.isT1()) {
- if (sourceTimeStamp)
- *sourceTimeStamp = 0;
- return *d.asT1();
- }
- QFile f(*d.asT2());
+ if (!inlineSourceCode.isEmpty())
+ return inlineSourceCode;
+
+ QFile f(fileInfo.absoluteFilePath());
if (!f.open(QIODevice::ReadOnly)) {
*error = f.errorString();
- return QByteArray();
+ return QString();
}
- if (sourceTimeStamp) {
- QDateTime timeStamp = QFileInfo(f).lastModified();
- // Files from the resource system do not have any time stamps, so fall back to the application
- // executable.
- if (!timeStamp.isValid())
- timeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified();
- *sourceTimeStamp = timeStamp.toMSecsSinceEpoch();
+
+ const qint64 fileSize = fileInfo.size();
+
+ if (uchar *mappedData = f.map(0, fileSize)) {
+ QString source = QString::fromUtf8(reinterpret_cast<const char *>(mappedData), fileSize);
+ f.unmap(mappedData);
+ return source;
}
- QByteArray data(f.size(), Qt::Uninitialized);
+
+ QByteArray data(fileSize, Qt::Uninitialized);
if (f.read(data.data(), data.length()) != data.length()) {
*error = f.errorString();
- return QByteArray();
+ return QString();
}
- return data;
+ return QString::fromUtf8(data);
+}
+
+QDateTime QQmlDataBlob::SourceCodeData::sourceTimeStamp() const
+{
+ if (!inlineSourceCode.isEmpty())
+ return QDateTime();
+
+ QDateTime timeStamp = fileInfo.lastModified();
+ if (timeStamp.isValid())
+ return timeStamp;
+
+ static QDateTime appTimeStamp;
+ if (!appTimeStamp.isValid())
+ appTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified();
+ return appTimeStamp;
+}
+
+bool QQmlDataBlob::SourceCodeData::exists() const
+{
+ if (!inlineSourceCode.isEmpty())
+ return true;
+ return fileInfo.exists();
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 9a69949906..48e7d5cba4 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -54,6 +54,7 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qfileinfo.h>
#if QT_CONFIG(qml_network)
#include <QtNetwork/qnetworkreply.h>
#endif
@@ -130,16 +131,16 @@ public:
QList<QQmlError> errors() const;
- class Data {
+ class SourceCodeData {
public:
- QByteArray readAll(QString *error, qint64 *sourceTimeStamp = 0) const;
+ QString readAll(QString *error) const;
+ QDateTime sourceTimeStamp() const;
+ bool exists() const;
private:
friend class QQmlDataBlob;
friend class QQmlTypeLoader;
- inline Data();
- Data(const Data &);
- Data &operator=(const Data &);
- QBiPointer<const QByteArray, const QString> d;
+ QString inlineSourceCode;
+ QFileInfo fileInfo;
};
protected:
@@ -152,7 +153,7 @@ protected:
void addDependency(QQmlDataBlob *);
// Callbacks made in load thread
- virtual void dataReceived(const Data &) = 0;
+ virtual void dataReceived(const SourceCodeData &) = 0;
virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) = 0;
virtual void done();
#if QT_CONFIG(qml_network)
@@ -339,7 +340,7 @@ private:
void setData(QQmlDataBlob *, const QByteArray &);
void setData(QQmlDataBlob *, const QString &fileName);
- void setData(QQmlDataBlob *, const QQmlDataBlob::Data &);
+ void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &);
void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
template<typename T>
@@ -437,7 +438,7 @@ public:
protected:
void done() override;
void completed() override;
- void dataReceived(const Data &) override;
+ void dataReceived(const SourceCodeData &) override;
void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
void allDependenciesDone() override;
void downloadProgressChanged(qreal) override;
@@ -463,8 +464,7 @@ private:
void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override;
- qint64 m_sourceTimeStamp = 0;
- QByteArray m_backupSourceCode; // used when cache verification fails.
+ SourceCodeData m_backupSourceCode; // used when cache verification fails.
QScopedPointer<QmlIR::Document> m_document;
QV4::CompiledData::TypeReferenceMap m_typeReferences;
@@ -548,7 +548,7 @@ public:
QQmlScriptData *scriptData() const;
protected:
- void dataReceived(const Data &) override;
+ void dataReceived(const SourceCodeData &) override;
void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
void done() override;
@@ -579,7 +579,7 @@ public:
void setPriority(int);
protected:
- void dataReceived(const Data &) override;
+ void dataReceived(const SourceCodeData &) override;
void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) override;
private:
@@ -588,11 +588,6 @@ private:
int m_priority;
};
-QQmlDataBlob::Data::Data()
-{
-}
-
-
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index d359a0f62f..8cc0b32168 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1885,7 +1885,7 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa
ExecutionContext *parentCtx = scope.engine->currentContext;
// The first non-empty source URL in the call stack determines the translation context.
while (!!parentCtx && context.isEmpty()) {
- if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) {
+ if (CompiledData::CompilationUnit *unit = static_cast<CompiledData::CompilationUnit*>(parentCtx->d()->compilationUnit)) {
QString fileName = unit->fileName();
QUrl url(unit->fileName());
if (url.isValid() && url.isRelative()) {
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index b6c45c40a8..f1f82f9e0e 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -193,8 +193,8 @@ Item {
*/
/*!
- \qmlproperty int QtQuick::MouseEvent::x
- \qmlproperty int QtQuick::MouseEvent::y
+ \qmlproperty real QtQuick::MouseEvent::x
+ \qmlproperty real QtQuick::MouseEvent::y
These properties hold the coordinates of the position supplied by the mouse event.
*/
@@ -340,8 +340,8 @@ Item {
*/
/*!
- \qmlproperty int QtQuick::WheelEvent::x
- \qmlproperty int QtQuick::WheelEvent::y
+ \qmlproperty real QtQuick::WheelEvent::x
+ \qmlproperty real QtQuick::WheelEvent::y
These properties hold the coordinates of the position supplied by the wheel event.
*/
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index d97c731157..6a2946bdcc 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -642,8 +642,10 @@ is finished.
\section1 Limitations
- \note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by
- \c id. Use \c parent instead.
+ \note Due to an implementation detail, items placed inside a Flickable
+ cannot anchor to the Flickable. Instead, use \l {Item::}{parent}, which
+ refers to the Flickable's \l contentItem. The size of the content item is
+ determined by \l contentWidth and \l contentHeight.
*/
/*!
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 436d7b33ce..d317c1d19b 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -873,9 +873,11 @@ void QQuickShaderEffectPrivate::updatePolish()
q->m_impl->maybeUpdateShaders();
}
+#if QT_CONFIG(opengl)
bool QQuickShaderEffect::isOpenGLShaderEffect() const
{
return m_glImpl != Q_NULLPTR;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index d269dc5e50..30bd018098 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -117,7 +117,9 @@ public:
bool isComponentComplete() const;
QString parseLog();
+#if QT_CONFIG(opengl)
bool isOpenGLShaderEffect() const;
+#endif
Q_SIGNALS:
void fragmentShaderChanged();
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index 8be82c30f9..f193d3928a 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -135,7 +135,7 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data)
QVERIFY(ds.atEnd());
QVERIFY(type >= QtDebugMsg);
- QVERIFY(type <= QtFatalMsg);
+ QVERIFY(type <= QtInfoMsg);
QVERIFY(timestamp > 0);
LogEntry entry((QtMsgType)type, QString::fromUtf8(message));
diff --git a/tests/manual/v4/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 49f107452a..49f107452a 100644
--- a/tests/manual/v4/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
diff --git a/tests/auto/qml/ecmascripttests/ecmascripttests.pro b/tests/auto/qml/ecmascripttests/ecmascripttests.pro
new file mode 100644
index 0000000000..6d3ee12307
--- /dev/null
+++ b/tests/auto/qml/ecmascripttests/ecmascripttests.pro
@@ -0,0 +1,20 @@
+CONFIG += testcase
+TARGET = tst_ecmascripttests
+QT += testlib
+macos:CONFIG -= app_bundle
+SOURCES += tst_ecmascripttests.cpp
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+
+TESTSCRIPT=$$PWD/test262.py
+isEmpty(V4CMD): V4CMD = qmljs
+
+checkjittarget.target = check-jit
+checkjittarget.commands = python $$TESTSCRIPT --command=$$V4CMD --parallel --with-test-expectations --update-expectations
+checkjittarget.depends = all
+QMAKE_EXTRA_TARGETS += checkjittarget
+
+checkmothtarget.target = check-interpreter
+checkmothtarget.commands = python $$TESTSCRIPT --command=\"$$V4CMD --interpret\" --parallel --with-test-expectations
+checkmothtarget.depends = all
+QMAKE_EXTRA_TARGETS += checkmothtarget
+
diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262
new file mode 160000
+Subproject d60c4ed97e69639bc5bc1db43a98828debf80c8
diff --git a/tests/manual/v4/test262.py b/tests/auto/qml/ecmascripttests/test262.py
index 3b5bfa119a..99f029cffd 100755
--- a/tests/manual/v4/test262.py
+++ b/tests/auto/qml/ecmascripttests/test262.py
@@ -555,6 +555,7 @@ class TestSuite(object):
print
if update_expectations:
self.expectations.update(progress)
+ return progress.failed == 0
def Print(self, tests):
cases = self.EnumerateTests(tests)
@@ -567,6 +568,7 @@ def Main():
# Uncomment the next line for more logging info.
#logging.basicConfig(level=logging.DEBUG)
os.environ["TZ"] = "PST8PDT"
+ os.environ["LANG"] = "en_US.UTF-8"
parser = BuildOptions()
(options, args) = parser.parse_args()
ValidateOptions(options)
@@ -578,18 +580,21 @@ def Main():
test_suite.Validate()
if options.cat:
test_suite.Print(args)
+ return 0
else:
- test_suite.Run(options.command, args,
- options.summary or options.full_summary,
- options.full_summary,
- options.parallel,
- options.update_expectations)
+ if test_suite.Run(options.command, args,
+ options.summary or options.full_summary,
+ options.full_summary,
+ options.parallel,
+ options.update_expectations):
+ return 0
+ else:
+ return 1
if __name__ == '__main__':
try:
- Main()
- sys.exit(0)
+ sys.exit(Main())
except Test262Error, e:
print "Error: %s" % e.message
sys.exit(1)
diff --git a/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
new file mode 100644
index 0000000000..2ce0cfe210
--- /dev/null
+++ b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QProcess>
+#include <QLibraryInfo>
+
+class tst_EcmaScriptTests : public QObject
+{
+ Q_OBJECT
+private slots:
+ void runTests_data();
+ void runTests();
+};
+
+void tst_EcmaScriptTests::runTests_data()
+{
+ QTest::addColumn<QString>("qmljsParameter");
+
+ QTest::newRow("jit") << QStringLiteral("--jit");
+ // Not passing yet: QTest::newRow("interpreter") << QStringLiteral("--interpret");
+}
+
+void tst_EcmaScriptTests::runTests()
+{
+#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86_64)
+ QFETCH(QString, qmljsParameter);
+
+ QProcess process;
+ process.setProcessChannelMode(QProcess::ForwardedChannels);
+ process.setWorkingDirectory(QLatin1String(SRCDIR));
+ process.setProgram("python");
+ process.setArguments(QStringList() << "test262.py" << "--command=" + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs " + qmljsParameter << "--parallel" << "--with-test-expectations");
+
+ qDebug() << "Going to run" << process.program() << process.arguments() << "in" << process.workingDirectory();
+
+ process.start();
+ QVERIFY(process.waitForStarted());
+ const int timeoutInMSecs = 20 * 60 * 1000;
+ QVERIFY2(process.waitForFinished(timeoutInMSecs), "Tests did not terminate in time -- see output above for details");
+ QVERIFY2(process.exitStatus() == QProcess::NormalExit, "Running the test harness failed -- see output above for details");
+ QVERIFY2(process.exitCode() == 0, "Tests failed -- see output above for details");
+#else
+ QSKIP("Currently the ecmascript tests are only run on Linux/x86-64");
+#endif
+}
+
+QTEST_MAIN(tst_EcmaScriptTests)
+
+#include "tst_ecmascripttests.moc"
+
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index b347b603bb..a9b18e9f32 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -62,7 +62,8 @@ PRIVATETESTS += \
qqmlimport \
qqmlobjectmodel \
qmldiskcache \
- qv4mm
+ qv4mm \
+ ecmascripttests
qtHaveModule(widgets) {
PUBLICTESTS += \
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index 9494e3a7fd..3402aeebc1 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -175,7 +175,7 @@ struct TestCompiler
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
- return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), v4->iselFactory.data(), &lastErrorString);
+ return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), v4->iselFactory.data(), &lastErrorString);
}
void closeMapping()
diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
index 90868d2ead..171c2bda8a 100644
--- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp
+++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
@@ -84,6 +84,7 @@ void tst_qmlmin::initTestCase()
excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
excludedDirs << "doc/src/snippets/qtquick1/imports";
excludedDirs << "tests/manual/v4";
+ excludedDirs << "tests/auto/qml/ecmascripttests";
excludedDirs << "tests/auto/qml/qmllint";
// Add invalid files (i.e. files with syntax errors)
diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
index 9fbd719d7b..30e517c8f9 100644
--- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
+++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
@@ -52,6 +52,7 @@ private slots:
void qmlPropertyValueInterceptorCast();
void qmlType();
void invalidQmlTypeName();
+ void prettyTypeName();
void registrationType();
void compositeType();
void externalEnums();
@@ -72,6 +73,16 @@ public:
};
QML_DECLARE_TYPE(TestType);
+class TestType2 : public QObject
+{
+ Q_OBJECT
+};
+
+class TestType3 : public QObject
+{
+ Q_OBJECT
+};
+
class ExternalEnums : public QObject
{
Q_OBJECT
@@ -214,13 +225,28 @@ void tst_qqmlmetatype::invalidQmlTypeName()
{
QStringList currFailures = QQmlMetaType::typeRegistrationFailures();
QCOMPARE(qmlRegisterType<TestType>("TestNamespace", 1, 0, "Test$Type"), -1); // should fail due to invalid QML type name.
+ QCOMPARE(qmlRegisterType<TestType>("Test", 1, 0, "EndingInSlash/"), -1);
QStringList nowFailures = QQmlMetaType::typeRegistrationFailures();
foreach (const QString &f, currFailures)
nowFailures.removeOne(f);
- QCOMPARE(nowFailures.size(), 1);
+ QCOMPARE(nowFailures.size(), 2);
QCOMPARE(nowFailures.at(0), QStringLiteral("Invalid QML element name \"Test$Type\""));
+ QCOMPARE(nowFailures.at(1), QStringLiteral("Invalid QML element name \"EndingInSlash/\""));
+}
+
+void tst_qqmlmetatype::prettyTypeName()
+{
+ TestType2 obj2;
+ QCOMPARE(QQmlMetaType::prettyTypeName(&obj2), QString("TestType2"));
+ QVERIFY(qmlRegisterType<TestType2>("Test", 1, 0, "") >= 0);
+ QCOMPARE(QQmlMetaType::prettyTypeName(&obj2), QString("TestType2"));
+
+ TestType3 obj3;
+ QCOMPARE(QQmlMetaType::prettyTypeName(&obj3), QString("TestType3"));
+ QVERIFY(qmlRegisterType<TestType3>("Test", 1, 0, "OtherName") >= 0);
+ QCOMPARE(QQmlMetaType::prettyTypeName(&obj3), QString("OtherName"));
}
void tst_qqmlmetatype::isList()
diff --git a/tests/auto/qml/v4misc/tst_v4misc.cpp b/tests/auto/qml/v4misc/tst_v4misc.cpp
index 88b6ae92a8..55a1f65608 100644
--- a/tests/auto/qml/v4misc/tst_v4misc.cpp
+++ b/tests/auto/qml/v4misc/tst_v4misc.cpp
@@ -26,6 +26,7 @@
**
****************************************************************************/
+#include <qhashfunctions.h>
#include <qtest.h>
#define V4_AUTOTEST
@@ -46,17 +47,12 @@ private slots:
void moveMapping_2();
};
-QT_BEGIN_NAMESPACE
-// Avoid QHash randomization so that the temp numbering is stable.
-extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; // from qhash.cpp
-QT_END_NAMESPACE
-
using namespace QT_PREPEND_NAMESPACE(QV4::IR);
void tst_v4misc::initTestCase()
{
- qt_qhash_seed.store(0);
- QCOMPARE(qt_qhash_seed.load(), 0);
+ qSetGlobalQHashSeed(0);
+ QCOMPARE(qGlobalQHashSeed(), 0);
}
// split between two ranges
diff --git a/tests/auto/qmltest/BLACKLIST b/tests/auto/qmltest/BLACKLIST
index c38347b42a..d324e9da5d 100644
--- a/tests/auto/qmltest/BLACKLIST
+++ b/tests/auto/qmltest/BLACKLIST
@@ -9,3 +9,4 @@ linux
linux
[ListView::test_listInteractiveCurrentIndexEnforce]
linux
+macos-10.12
diff --git a/tests/auto/toolsupport/tst_toolsupport.cpp b/tests/auto/toolsupport/tst_toolsupport.cpp
index 526ba8f375..6ee1db805a 100644
--- a/tests/auto/toolsupport/tst_toolsupport.cpp
+++ b/tests/auto/toolsupport/tst_toolsupport.cpp
@@ -101,7 +101,7 @@ void tst_toolsupport::offsets_data()
= QTest::newRow("CompiledData::CompilationUnit::data")
<< pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::data);
- data << 8 << 16;
+ data << 12 << 24;
}
{
@@ -109,7 +109,7 @@ void tst_toolsupport::offsets_data()
= QTest::newRow("CompiledData::CompilationUnit::runtimeStrings")
<< pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::runtimeStrings);
- data << 12 << 24;
+ data << 0 << 0;
}
{
diff --git a/tests/benchmarks/qml/holistic/testtypes.h b/tests/benchmarks/qml/holistic/testtypes.h
index 0736982373..a752a8585b 100644
--- a/tests/benchmarks/qml/holistic/testtypes.h
+++ b/tests/benchmarks/qml/holistic/testtypes.h
@@ -43,6 +43,7 @@
#include <QtQml/qjsvalue.h>
#include <QtQml/qqmlscriptstring.h>
#include <QtQml/qqmlcomponent.h>
+#include <QtCore/qregexp.h>
class MyQmlAttachedObject : public QObject
{
diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
index 886cfc6599..6da0799bbc 100644
--- a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
+++ b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
@@ -29,6 +29,7 @@
#include <QtCore/QTimer>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
+#include <QtCore/QHashFunctions>
#include <QtGui/QGuiApplication>
#include <QtGui/QImage>
@@ -134,11 +135,9 @@ private:
};
-Q_CORE_EXPORT extern QBasicAtomicInt qt_qhash_seed;
-
int main(int argc, char *argv[])
{
- qt_qhash_seed = 0;
+ qSetGlobalQHashSeed(0);
QGuiApplication a(argc, argv);
diff --git a/tests/manual/v4/test262 b/tests/manual/v4/test262
deleted file mode 160000
-Subproject 9741ac4655808ac46c127e3d1d8ba3d27ada618
diff --git a/tests/manual/v4/tests.pro b/tests/manual/v4/tests.pro
deleted file mode 100644
index ce4a34f7a0..0000000000
--- a/tests/manual/v4/tests.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-TEMPLATE = aux
-
-TESTSCRIPT=$$PWD/test262.py
-isEmpty(V4CMD): V4CMD = qmljs
-
-checktarget.target = check
-checktarget.commands = python $$TESTSCRIPT --command=$$V4CMD --parallel --with-test-expectations --update-expectations
-checktarget.depends = all
-QMAKE_EXTRA_TARGETS += checktarget
-
-checkmothtarget.target = check-interpreter
-checkmothtarget.commands = python $$TESTSCRIPT --command=\"$$V4CMD --interpret\" --parallel --with-test-expectations
-checkmothtarget.depends = all
-QMAKE_EXTRA_TARGETS += checkmothtarget
-
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index e8a506264c..8af9a1de41 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -567,7 +567,7 @@ int main(int argc, char *argv[])
loadDummyDataFiles(e, dummyDir);
for (const QString &path : qAsConst(files)) {
- QUrl url = QUrl::fromUserInput(path, QDir::currentPath());
+ QUrl url = QUrl::fromUserInput(path, QDir::currentPath(), QUrl::AssumeLocalFile);
if (verboseMode)
printf("qml: loading %s\n", qPrintable(url.toString()));
QByteArray strippedFile;
diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp
index 207f53b79e..f24ec40184 100644
--- a/tools/qmlcachegen/qmlcachegen.cpp
+++ b/tools/qmlcachegen/qmlcachegen.cpp
@@ -32,13 +32,13 @@
#include <QFile>
#include <QFileInfo>
#include <QDateTime>
+#include <QHashFunctions>
#include <private/qqmlirbuilder_p.h>
#include <private/qv4isel_moth_p.h>
#include <private/qqmljsparser_p.h>
QT_BEGIN_NAMESPACE
-extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed;
namespace QV4 { namespace JIT {
Q_QML_EXPORT QV4::EvalISelFactory *createISelForArchitecture(const QString &architecture);
@@ -287,7 +287,7 @@ static bool compileJSFile(const QString &inputFileName, const QString &outputFil
int main(int argc, char **argv)
{
// Produce reliably the same output for the same input by disabling QHash's random seeding.
- qt_qhash_seed.testAndSetRelaxed(-1, 0);
+ qSetGlobalQHashSeed(0);
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName(QStringLiteral("qmlcachegen"));
diff --git a/tools/qmljs/qmljs.cpp b/tools/qmljs/qmljs.cpp
index 4d0f9d278f..14a20731c0 100644
--- a/tools/qmljs/qmljs.cpp
+++ b/tools/qmljs/qmljs.cpp
@@ -159,7 +159,7 @@ int main(int argc, char *argv[])
if (cache && QFile::exists(fn + QLatin1Char('c'))) {
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = iSelFactory->createUnitForLoading();
QString error;
- if (unit->loadFromDisk(QUrl::fromLocalFile(fn), iSelFactory, &error)) {
+ if (unit->loadFromDisk(QUrl::fromLocalFile(fn), QFileInfo(fn).lastModified(), iSelFactory, &error)) {
script.reset(new QV4::Script(&vm, nullptr, unit));
} else {
std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl;
diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp
index 668cb3ce2d..596ad8d47f 100644
--- a/tools/qmlprofiler/qmlprofilerdata.cpp
+++ b/tools/qmlprofiler/qmlprofilerdata.cpp
@@ -33,6 +33,7 @@
#include <QHash>
#include <QFile>
#include <QXmlStreamReader>
+#include <QRegExp>
#include <limits>
diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp
index 1e8d91a95b..7741c4c45b 100644
--- a/tools/qmlscene/main.cpp
+++ b/tools/qmlscene/main.cpp
@@ -33,6 +33,7 @@
#include <QtCore/qpointer.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qtextstream.h>
+#include <QtCore/qregexp.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLFunctions>