From 117455638a555629e82e415312908128280ad72d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 6 Mar 2013 20:04:36 +0100 Subject: [PATCH] Get rid of the builtin_get_exception call in the IR Instead allocate a temp to hold the exception to rethrow and pass the address of that to the TRY statement. Then it can be set in the run-time. Change-Id: Ic15869e8e5ab5119b26f98fc45dbdb1a2ad9d21e Reviewed-by: Lars Knoll --- src/v4/moth/qv4instr_moth_p.h | 7 +------ src/v4/moth/qv4isel_moth.cpp | 8 +------- src/v4/moth/qv4isel_moth_p.h | 1 - src/v4/moth/qv4vme_moth.cpp | 6 ++---- src/v4/qv4codegen.cpp | 10 ++++++---- src/v4/qv4isel_llvm.cpp | 13 ------------- src/v4/qv4isel_llvm_p.h | 1 - src/v4/qv4isel_masm.cpp | 11 ++++------- src/v4/qv4isel_masm_p.h | 1 - src/v4/qv4isel_p.cpp | 4 ---- src/v4/qv4isel_p.h | 1 - src/v4/qv4jsir.cpp | 10 +++++----- src/v4/qv4jsir_p.h | 7 ++++--- 13 files changed, 23 insertions(+), 57 deletions(-) diff --git a/src/v4/moth/qv4instr_moth_p.h b/src/v4/moth/qv4instr_moth_p.h index ec0fe27..d2c0a70 100644 --- a/src/v4/moth/qv4instr_moth_p.h +++ b/src/v4/moth/qv4instr_moth_p.h @@ -23,7 +23,6 @@ F(CallActivationProperty, callActivationProperty) \ F(CallBuiltinThrow, callBuiltinThrow) \ F(CallBuiltinFinishTry, callBuiltinFinishTry) \ - F(CallBuiltinGetException, callBuiltinGetException) \ F(CallBuiltinPushScope, callBuiltinPushScope) \ F(CallBuiltinPopScope, callBuiltinPopScope) \ F(CallBuiltinForeachIteratorObject, callBuiltinForeachIteratorObject) \ @@ -214,6 +213,7 @@ union Instr ptrdiff_t tryOffset; ptrdiff_t catchOffset; VM::String *exceptionVarName; + Param exceptionVar; }; struct instr_callValue { MOTH_INSTR_HEADER @@ -252,10 +252,6 @@ union Instr struct instr_callBuiltinFinishTry { MOTH_INSTR_HEADER }; - struct instr_callBuiltinGetException { - MOTH_INSTR_HEADER - Param result; - }; struct instr_callBuiltinPushScope { MOTH_INSTR_HEADER Param arg; @@ -468,7 +464,6 @@ union Instr instr_callActivationProperty callActivationProperty; instr_callBuiltinThrow callBuiltinThrow; instr_callBuiltinFinishTry callBuiltinFinishTry; - instr_callBuiltinGetException callBuiltinGetException; instr_callBuiltinPushScope callBuiltinPushScope; instr_callBuiltinPopScope callBuiltinPopScope; instr_callBuiltinForeachIteratorObject callBuiltinForeachIteratorObject; diff --git a/src/v4/moth/qv4isel_moth.cpp b/src/v4/moth/qv4isel_moth.cpp index b45b4c0..5260579 100644 --- a/src/v4/moth/qv4isel_moth.cpp +++ b/src/v4/moth/qv4isel_moth.cpp @@ -683,6 +683,7 @@ void InstructionSelection::visitTry(IR::Try *t) enterTry.tryOffset = 0; enterTry.catchOffset = 0; enterTry.exceptionVarName = identifier(t->exceptionVarName); + enterTry.exceptionVar = getParam(t->exceptionVar); ptrdiff_t enterTryLoc = addInstruction(enterTry); ptrdiff_t tryLoc = enterTryLoc + (((const char *)&enterTry.tryOffset) - ((const char *)&enterTry)); @@ -850,13 +851,6 @@ void InstructionSelection::callBuiltinFinishTry() addInstruction(call); } -void InstructionSelection::callBuiltinGetException(IR::Temp *result) -{ - Instruction::CallBuiltinGetException call; - call.result = getResultParam(result); - addInstruction(call); -} - void InstructionSelection::callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result) { Instruction::CallBuiltinForeachIteratorObject call; diff --git a/src/v4/moth/qv4isel_moth_p.h b/src/v4/moth/qv4isel_moth_p.h index 39dc92d..2d5dec4 100644 --- a/src/v4/moth/qv4isel_moth_p.h +++ b/src/v4/moth/qv4isel_moth_p.h @@ -45,7 +45,6 @@ protected: virtual void callBuiltinPostIncrementValue(IR::Temp *value, IR::Temp *result); virtual void callBuiltinThrow(IR::Temp *arg); virtual void callBuiltinFinishTry(); - virtual void callBuiltinGetException(IR::Temp *result); virtual void callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinForeachNextPropertyname(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinPushWithScope(IR::Temp *arg); diff --git a/src/v4/moth/qv4vme_moth.cpp b/src/v4/moth/qv4vme_moth.cpp index 401752f..a20fdbf 100644 --- a/src/v4/moth/qv4vme_moth.cpp +++ b/src/v4/moth/qv4vme_moth.cpp @@ -266,6 +266,7 @@ VM::Value VME::run(QQmlJS::VM::ExecutionContext *context, const uchar *&code, code = tryCode; } catch (VM::Exception &ex) { ex.accept(context); + __qmljs_get_exception(context, VALUEPTR(instr.exceptionVar)); try { VM::ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(instr.exceptionVarName, context); const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset; @@ -274,6 +275,7 @@ VM::Value VME::run(QQmlJS::VM::ExecutionContext *context, const uchar *&code, context = __qmljs_builtin_pop_scope(catchContext); } catch (VM::Exception &ex) { ex.accept(context); + __qmljs_get_exception(context, VALUEPTR(instr.exceptionVar)); const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset; run(context, catchCode, stack, stackSize); code = catchCode; @@ -285,10 +287,6 @@ VM::Value VME::run(QQmlJS::VM::ExecutionContext *context, const uchar *&code, return VM::Value(); MOTH_END_INSTR(CallBuiltinFinishTry) - MOTH_BEGIN_INSTR(CallBuiltinGetException) - __qmljs_get_exception(context, VALUEPTR(instr.result)); - MOTH_END_INSTR(CallBuiltinGetException) - MOTH_BEGIN_INSTR(CallBuiltinPushScope) context = __qmljs_builtin_push_with_scope(VALUE(instr.arg), context); MOTH_END_INSTR(CallBuiltinPushScope) diff --git a/src/v4/qv4codegen.cpp b/src/v4/qv4codegen.cpp index 76f5b90..e6071db 100644 --- a/src/v4/qv4codegen.cpp +++ b/src/v4/qv4codegen.cpp @@ -111,7 +111,7 @@ struct ComputeUseDef: IR::StmtVisitor, IR::ExprVisitor virtual void visitJump(IR::Jump *) {} virtual void visitCJump(IR::CJump *s) { s->cond->accept(this); } virtual void visitRet(IR::Ret *s) { s->expr->accept(this); } - virtual void visitTry(IR::Try *) {} + virtual void visitTry(IR::Try *t) { t->exceptionVar->accept(this); } virtual void visitTemp(IR::Temp *e) { if (e->index < 0 || e->scope != 0) @@ -2475,7 +2475,11 @@ bool Codegen::visit(TryStatement *ast) ScopeAndFinally tcf(_scopeAndFinally, ast->finallyExpression, finishTryArgs); _scopeAndFinally = &tcf; - _block->TRY(tryBody, catchBody, ast->catchExpression ? ast->catchExpression->name.toString() : QString()); + int exception_to_rethrow = _block->newTemp(); + + _block->TRY(tryBody, catchBody, + ast->catchExpression ? ast->catchExpression->name.toString() : QString(), + _block->TEMP(exception_to_rethrow)); _block = tryBody; statement(ast->statement); @@ -2513,8 +2517,6 @@ bool Codegen::visit(TryStatement *ast) IR::BasicBlock *after = _function->newBasicBlock(); _block = finallyBody; - int exception_to_rethrow = _block->newTemp(); - move(_block->TEMP(exception_to_rethrow), _block->CALL(_block->NAME(IR::Name::builtin_get_exception, 0, 0), 0)); _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_finish_try, 0, 0), finishTryArgs)); if (ast->finallyExpression && ast->finallyExpression->statement) diff --git a/src/v4/qv4isel_llvm.cpp b/src/v4/qv4isel_llvm.cpp index b79001c..58db884 100644 --- a/src/v4/qv4isel_llvm.cpp +++ b/src/v4/qv4isel_llvm.cpp @@ -441,13 +441,6 @@ void InstructionSelection::callBuiltinFinishTry() Q_UNREACHABLE(); } -void InstructionSelection::callBuiltinGetException(IR::Temp *result) -{ - // TODO - assert(!"TODO!"); - Q_UNREACHABLE(); -} - void InstructionSelection::callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result) { // TODO @@ -1144,12 +1137,6 @@ void InstructionSelection::genCallName(IR::Call *e, llvm::Value *result) // ### FIXME. return; - case IR::Name::builtin_get_exception: - CreateCall2(getRuntimeFunction("__qmljs_llvm_get_exception"), - _llvmFunction->arg_begin(), result); - _llvmValue = CreateLoad(result); - return; - case IR::Name::builtin_foreach_iterator_object: CreateCall3(getRuntimeFunction("__qmljs_llvm_foreach_iterator_object"), _llvmFunction->arg_begin(), result, getLLVMTempReference(e->args->expr)); diff --git a/src/v4/qv4isel_llvm_p.h b/src/v4/qv4isel_llvm_p.h index cf9aaed..4284fa3 100644 --- a/src/v4/qv4isel_llvm_p.h +++ b/src/v4/qv4isel_llvm_p.h @@ -90,7 +90,6 @@ public: // methods from InstructionSelection: virtual void callBuiltinThrow(IR::Temp *arg); virtual void callBuiltinCreateExceptionHandler(IR::Temp *result); virtual void callBuiltinFinishTry(); - virtual void callBuiltinGetException(IR::Temp *result); virtual void callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinForeachNextPropertyname(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinPushWithScope(IR::Temp *arg); diff --git a/src/v4/qv4isel_masm.cpp b/src/v4/qv4isel_masm.cpp index 28a5c7b..aa58086 100644 --- a/src/v4/qv4isel_masm.cpp +++ b/src/v4/qv4isel_masm.cpp @@ -678,18 +678,20 @@ void InstructionSelection::callBuiltinThrow(IR::Temp *arg) typedef void *(*MiddleOfFunctionEntryPoint(ExecutionContext *, void *localsPtr)); static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunctionEntryPoint tryBody, MiddleOfFunctionEntryPoint catchBody, - VM::String *exceptionVarName) + VM::String *exceptionVarName, Value *exceptionVar) { void *addressToContinueAt = 0; try { addressToContinueAt = tryBody(context, localsPtr); } catch (Exception& ex) { ex.accept(context); + __qmljs_get_exception(context, exceptionVar); try { ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(exceptionVarName, context); addressToContinueAt = catchBody(catchContext, localsPtr); context = __qmljs_builtin_pop_scope(catchContext); } catch (Exception& ex) { + __qmljs_get_exception(context, exceptionVar); ex.accept(context); addressToContinueAt = catchBody(context, localsPtr); } @@ -710,7 +712,7 @@ void InstructionSelection::visitTry(IR::Try *t) generateFunctionCall(Assembler::ReturnValueRegister, tryWrapper, Assembler::ContextRegister, Assembler::LocalsRegister, Assembler::ReentryBlock(t->tryBlock), Assembler::ReentryBlock(t->catchBlock), - identifier(t->exceptionVarName)); + identifier(t->exceptionVarName), Assembler::PointerToValue(t->exceptionVar)); _as->jump(Assembler::ReturnValueRegister); } @@ -724,11 +726,6 @@ void InstructionSelection::callBuiltinFinishTry() _as->addPatch(continuation, _as->label()); } -void InstructionSelection::callBuiltinGetException(IR::Temp *result) -{ - generateFunctionCall(Assembler::Void, __qmljs_get_exception, Assembler::ContextRegister, Assembler::PointerToValue(result)); -} - void InstructionSelection::callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result) { generateFunctionCall(Assembler::Void, __qmljs_foreach_iterator_object, Assembler::ContextRegister, Assembler::PointerToValue(result), Assembler::Reference(arg), Assembler::ContextRegister); diff --git a/src/v4/qv4isel_masm_p.h b/src/v4/qv4isel_masm_p.h index 8143020..b34b6b6 100644 --- a/src/v4/qv4isel_masm_p.h +++ b/src/v4/qv4isel_masm_p.h @@ -788,7 +788,6 @@ protected: virtual void callBuiltinPostIncrementValue(IR::Temp *value, IR::Temp *result); virtual void callBuiltinThrow(IR::Temp *arg); virtual void callBuiltinFinishTry(); - virtual void callBuiltinGetException(IR::Temp *result); virtual void callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinForeachNextPropertyname(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinPushWithScope(IR::Temp *arg); diff --git a/src/v4/qv4isel_p.cpp b/src/v4/qv4isel_p.cpp index 1651555..eaa3445 100644 --- a/src/v4/qv4isel_p.cpp +++ b/src/v4/qv4isel_p.cpp @@ -314,10 +314,6 @@ void InstructionSelection::callBuiltin(IR::Call *call, IR::Temp *result) callBuiltinFinishTry(); return; - case IR::Name::builtin_get_exception: - callBuiltinGetException(result); - return; - case IR::Name::builtin_foreach_iterator_object: { IR::Temp *arg = call->args->expr->asTemp(); assert(arg != 0); diff --git a/src/v4/qv4isel_p.h b/src/v4/qv4isel_p.h index ae99bf6..4e7d588 100644 --- a/src/v4/qv4isel_p.h +++ b/src/v4/qv4isel_p.h @@ -104,7 +104,6 @@ public: // to implement by subclasses: virtual void callBuiltinPostIncrementValue(IR::Temp *value, IR::Temp *result) = 0; virtual void callBuiltinThrow(IR::Temp *arg) = 0; virtual void callBuiltinFinishTry() = 0; - virtual void callBuiltinGetException(IR::Temp *result) = 0; virtual void callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result) = 0; virtual void callBuiltinForeachNextPropertyname(IR::Temp *arg, IR::Temp *result) = 0; virtual void callBuiltinPushWithScope(IR::Temp *arg) = 0; diff --git a/src/v4/qv4jsir.cpp b/src/v4/qv4jsir.cpp index b5de42e..908643b 100644 --- a/src/v4/qv4jsir.cpp +++ b/src/v4/qv4jsir.cpp @@ -358,8 +358,6 @@ static const char *builtin_to_string(Name::Builtin b) return "builtin_throw"; case Name::builtin_finish_try: return "builtin_finish_try"; - case Name::builtin_get_exception: - return "builtin_get_exception"; case IR::Name::builtin_foreach_iterator_object: return "builtin_foreach_iterator_object"; case IR::Name::builtin_foreach_next_property_name: @@ -524,7 +522,9 @@ void Ret::dump(QTextStream &out, Mode) void Try::dump(QTextStream &out, Stmt::Mode mode) { - out << "try L" << tryBlock->index << "; catch exception as " << exceptionVarName << " and go to L" << catchBlock->index << ';'; + out << "try L" << tryBlock->index << "; catch exception in "; + exceptionVar->dump(out); + out << " with the name " << exceptionVarName << " and go to L" << catchBlock->index << ';'; } Function *Module::newFunction(const QString &name, Function *outer) @@ -791,13 +791,13 @@ Stmt *BasicBlock::RET(Temp *expr) return s; } -Stmt *BasicBlock::TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName) +Stmt *BasicBlock::TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName, Temp *exceptionVar) { if (isTerminated()) return 0; Try *t = function->New(); - t->init(tryBlock, catchBlock, exceptionVarName); + t->init(tryBlock, catchBlock, exceptionVarName, exceptionVar); statements.append(t); assert(! out.contains(tryBlock)); diff --git a/src/v4/qv4jsir_p.h b/src/v4/qv4jsir_p.h index e4d8e1e..86247dd 100644 --- a/src/v4/qv4jsir_p.h +++ b/src/v4/qv4jsir_p.h @@ -292,7 +292,6 @@ struct Name: Expr { builtin_postdecrement, builtin_throw, builtin_finish_try, - builtin_get_exception, builtin_foreach_iterator_object, builtin_foreach_next_property_name, builtin_push_with_scope, @@ -608,12 +607,14 @@ struct Try: Stmt { BasicBlock *tryBlock; BasicBlock *catchBlock; QString exceptionVarName; + Temp *exceptionVar; // place to store the caught exception, for use when re-throwing - void init(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName) + void init(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName, Temp *exceptionVar) { this->tryBlock = tryBlock; this->catchBlock = catchBlock; this->exceptionVarName = exceptionVarName; + this->exceptionVar = exceptionVar; } virtual Stmt *asTerminator() { return this; } @@ -750,7 +751,7 @@ struct BasicBlock { Stmt *JUMP(BasicBlock *target); Stmt *CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse); Stmt *RET(Temp *expr); - Stmt *TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName); + Stmt *TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName, Temp *exceptionVar); void dump(QTextStream &out, Stmt::Mode mode = Stmt::HIR); }; -- 2.7.4