diff options
author | Lars Knoll <[email protected]> | 2013-10-23 14:03:09 +0200 |
---|---|---|
committer | The Qt Project <[email protected]> | 2013-10-29 10:38:50 +0100 |
commit | 4f8df70107d17922303bb21db5a2cf92aa1aff99 (patch) | |
tree | e59fc784bf25c29f667d8f83fdddc156dffe1339 /src/qml/jsruntime | |
parent | 34bf0139c75de861c948391737af3c8c2a42703c (diff) |
Implement new exception handling for moth
Add the required instructions and check for
exceptions in the engine before storing any
results.
Change-Id: Ibfaf904d659859e8012920270825211ba202c63d
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 50 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth_p.h | 2 |
2 files changed, 44 insertions, 8 deletions
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 04a07093c1..730b9d29a7 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -216,15 +216,25 @@ static inline QV4::Value *getValueRef(QV4::ExecutionContext *context, # define VALUE(param) (*getValueRef(context, stack, param, stackSize)) # define VALUEPTR(param) getValueRef(context, stack, param, stackSize) #endif -#define STOREVALUE(param, value) VALUE(param) = QV4::Value::fromReturnedValue((value)) +#define STOREVALUE(param, value) { \ + QV4::ReturnedValue tmp = (value); \ + if (context->engine->hasException) \ + goto catchException; \ + VALUE(param) = tmp; \ + } +#define CHECK_EXCEPTION \ + if (context->engine->hasException) \ + goto catchException -QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code, +QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code, QV4::SafeValue *stack, unsigned stackSize #ifdef MOTH_THREADED_INTERPRETER , void ***storeJumpTable #endif ) { + const uchar *exceptionHandler = 0; + #ifdef DO_TRACE_INSTR qDebug("Starting VME with context=%p and code=%p", context, code); #endif // DO_TRACE_INSTR @@ -244,12 +254,12 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code, QV4::SafeString * const runtimeStrings = context->compilationUnit->runtimeStrings; context->interpreterInstructionPointer = &code; -#ifdef MOTH_THREADED_INTERPRETER - const Instr *genericInstr = reinterpret_cast<const Instr *>(code); - goto *genericInstr->common.code; -#else + for (;;) { const Instr *genericInstr = reinterpret_cast<const Instr *>(code); +#ifdef MOTH_THREADED_INTERPRETER + goto *genericInstr->common.code; +#else switch (genericInstr->common.instructionType) { #endif @@ -288,6 +298,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code, MOTH_BEGIN_INSTR(StoreName) TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData()); __qmljs_set_activation_property(context, runtimeStrings[instr.name], VALUEPTR(instr.source)); + CHECK_EXCEPTION; MOTH_END_INSTR(StoreName) MOTH_BEGIN_INSTR(LoadElement) @@ -296,6 +307,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code, MOTH_BEGIN_INSTR(StoreElement) __qmljs_set_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index), VALUEPTR(instr.source)); + CHECK_EXCEPTION; MOTH_END_INSTR(StoreElement) MOTH_BEGIN_INSTR(LoadProperty) @@ -304,6 +316,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code, MOTH_BEGIN_INSTR(StoreProperty) __qmljs_set_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name], VALUEPTR(instr.source)); + CHECK_EXCEPTION; MOTH_END_INSTR(StoreProperty) MOTH_BEGIN_INSTR(Push) @@ -361,10 +374,23 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code, STOREVALUE(instr.result, __qmljs_call_activation_property(context, runtimeStrings[instr.name], callData)); MOTH_END_INSTR(CallActivationProperty) + MOTH_BEGIN_INSTR(SetExceptionHandler) + exceptionHandler = instr.offset ? ((uchar *)&instr.offset) + instr.offset : 0; + MOTH_END_INSTR(SetExceptionHandler) + MOTH_BEGIN_INSTR(CallBuiltinThrow) __qmljs_throw(context, VALUEPTR(instr.arg)); + CHECK_EXCEPTION; MOTH_END_INSTR(CallBuiltinThrow) + MOTH_BEGIN_INSTR(CallBuiltinUnwindException) + STOREVALUE(instr.result, __qmljs_builtin_unwind_exception(context)); + MOTH_END_INSTR(CallBuiltinUnwindException) + + MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope) + context = __qmljs_builtin_push_catch_scope(context, runtimeStrings[instr.name]); + MOTH_END_INSTR(CallBuiltinPushCatchScope) + MOTH_BEGIN_INSTR(CallBuiltinPushScope) context = __qmljs_builtin_push_with_scope(VALUEPTR(instr.arg), context); MOTH_END_INSTR(CallBuiltinPushScope) @@ -524,9 +550,19 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code, qFatal("QQmlJS::Moth::VME: Internal error - unknown instruction %d", genericInstr->common.instructionType); break; } - } #endif + Q_ASSERT(false); + catchException: + Q_ASSERT(context->engine->hasException); + if (!exceptionHandler) { + context->engine->stackPop(stackSize); + return QV4::Encode::undefined(); + } + code = exceptionHandler; + } + + } #ifdef MOTH_THREADED_INTERPRETER diff --git a/src/qml/jsruntime/qv4vme_moth_p.h b/src/qml/jsruntime/qv4vme_moth_p.h index 68d8086f52..974dfdd615 100644 --- a/src/qml/jsruntime/qv4vme_moth_p.h +++ b/src/qml/jsruntime/qv4vme_moth_p.h @@ -60,7 +60,7 @@ public: #endif private: - QV4::ReturnedValue run(QV4::ExecutionContext *, const uchar *&code, + QV4::ReturnedValue run(QV4::ExecutionContext *, const uchar *code, QV4::SafeValue *stack = 0, unsigned stackSize = 0 #ifdef MOTH_THREADED_INTERPRETER , void ***storeJumpTable = 0 |