aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/v4/qmljs_engine.cpp27
-rw-r--r--src/v4/qmljs_engine.h26
-rw-r--r--tools/v4/main.cpp18
3 files changed, 55 insertions, 16 deletions
diff --git a/src/v4/qmljs_engine.cpp b/src/v4/qmljs_engine.cpp
index 126162e38f..33ac4a2769 100644
--- a/src/v4/qmljs_engine.cpp
+++ b/src/v4/qmljs_engine.cpp
@@ -58,13 +58,14 @@
#include <qv4stringobject.h>
#include <qv4identifier.h>
#include <qv4unwindhelper.h>
+#include "qv4isel_masm_p.h"
+#include "debugging.h"
namespace QQmlJS {
namespace VM {
ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
: memoryManager(new QQmlJS::VM::MemoryManager)
- , iselFactory(factory)
, debugger(0)
, globalObject(Value::nullValue())
, globalCode(0)
@@ -72,6 +73,10 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
{
MemoryManager::GCBlocker gcBlocker(memoryManager);
+ if (!factory)
+ factory = new MASM::ISelFactory;
+ iselFactory.reset(factory);
+
memoryManager->setExecutionEngine(this);
identifierCache = new Identifiers(this);
@@ -453,5 +458,25 @@ void ExecutionEngine::markObjects()
id_eval->mark();
}
+Value ExecutionEngine::run(Function *function, ExecutionContext *ctx)
+{
+ if (!ctx)
+ ctx = rootContext;
+
+ TemporaryAssignment<Function*>(globalCode, function);
+
+ // ### Would be better to have a SavedExecutionState object that
+ // saves this and restores it in the destructor (to survive an exception).
+ ctx->strictMode = function->isStrict;
+ ctx->lookups = function->lookups;
+
+ if (debugger)
+ debugger->aboutToCall(0, ctx);
+ QQmlJS::VM::Value result = function->code(ctx, function->codeData);
+ if (debugger)
+ debugger->justLeft(ctx);
+ return result;
+}
+
} // namespace VM
} // namespace QQmlJS
diff --git a/src/v4/qmljs_engine.h b/src/v4/qmljs_engine.h
index 0d8dd05fc3..1440a6461e 100644
--- a/src/v4/qmljs_engine.h
+++ b/src/v4/qmljs_engine.h
@@ -102,7 +102,7 @@ class RegExp;
struct Q_V4_EXPORT ExecutionEngine
{
MemoryManager *memoryManager;
- EvalISelFactory *iselFactory;
+ QScopedPointer<EvalISelFactory> iselFactory;
ExecutionContext *current;
ExecutionContext *rootContext;
WTF::BumpPointerAllocator bumperPointerAllocator; // Used by Yarr Regex engine.
@@ -182,7 +182,7 @@ struct Q_V4_EXPORT ExecutionEngine
QVector<Function *> functions;
- ExecutionEngine(EvalISelFactory *iselFactory);
+ ExecutionEngine(EvalISelFactory *iselFactory = 0);
~ExecutionEngine();
ExecutionContext *newContext();
@@ -223,6 +223,28 @@ struct Q_V4_EXPORT ExecutionEngine
void requireArgumentsAccessors(int n);
void markObjects();
+
+ Value run(VM::Function *function, ExecutionContext *ctx = 0);
+};
+
+template <typename T>
+struct TemporaryAssignment
+{
+ TemporaryAssignment(T &var, const T& temporaryValue)
+ : variable(var)
+ , savedValue(var)
+ {
+ variable = temporaryValue;
+ }
+ ~TemporaryAssignment()
+ {
+ variable = savedValue;
+ }
+ T &variable;
+ T savedValue;
+private:
+ TemporaryAssignment(const TemporaryAssignment<T>&);
+ TemporaryAssignment operator=(const TemporaryAssignment<T>&);
};
} // namespace VM
diff --git a/tools/v4/main.cpp b/tools/v4/main.cpp
index 89a25973e8..03ba82851c 100644
--- a/tools/v4/main.cpp
+++ b/tools/v4/main.cpp
@@ -337,14 +337,14 @@ int main(int argc, char *argv[])
#endif // QMLJS_WITH_LLVM
case use_masm:
case use_moth: {
- QScopedPointer<QQmlJS::EvalISelFactory> iSelFactory;
+ QQmlJS::EvalISelFactory* iSelFactory = 0;
if (mode == use_moth) {
- iSelFactory.reset(new QQmlJS::Moth::ISelFactory);
+ iSelFactory = new QQmlJS::Moth::ISelFactory;
} else {
- iSelFactory.reset(new QQmlJS::MASM::ISelFactory);
+ iSelFactory = new QQmlJS::MASM::ISelFactory;
}
- QQmlJS::VM::ExecutionEngine vm(iSelFactory.data());
+ QQmlJS::VM::ExecutionEngine vm(iSelFactory);
QScopedPointer<QQmlJS::Debugging::Debugger> debugger;
if (enableDebugging)
@@ -375,15 +375,7 @@ int main(int argc, char *argv[])
/*strictMode =*/ false, /*inheritContext =*/ false);
if (!f)
continue;
- vm.globalCode = f;
-
- ctx->strictMode = f->isStrict;
- ctx->lookups = f->lookups;
- if (debugger)
- debugger->aboutToCall(0, ctx);
- QQmlJS::VM::Value result = f->code(ctx, f->codeData);
- if (debugger)
- debugger->justLeft(ctx);
+ QQmlJS::VM::Value result = vm.run(f);
if (!result.isUndefined()) {
if (! qgetenv("SHOW_EXIT_VALUE").isEmpty())
std::cout << "exit value: " << qPrintable(result.toString(ctx)->toQString()) << std::endl;