diff options
-rw-r--r-- | src/v4/qmljs_engine.cpp | 27 | ||||
-rw-r--r-- | src/v4/qmljs_engine.h | 26 | ||||
-rw-r--r-- | tools/v4/main.cpp | 18 |
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; |