From: Simon Hausmann Date: Wed, 6 Mar 2013 19:04:31 +0000 (+0100) Subject: Cleanup: Get rid of calls to builtin_{push,pop}_catch_scope in the IR X-Git-Tag: upstream/5.2.1~669^2~659^2~151 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=48943d74d70fb84d7ad8ce7590e608ff8b78b670;p=platform%2Fupstream%2Fqtdeclarative.git Cleanup: Get rid of calls to builtin_{push,pop}_catch_scope in the IR These calls aren't needed anymore and can easily be done on the run-time level instead right before and after calling the catch block. Change-Id: I445361688782d12269764578e83ebb21ae184190 Reviewed-by: Lars Knoll --- diff --git a/src/v4/moth/qv4instr_moth_p.h b/src/v4/moth/qv4instr_moth_p.h index 7a9b59c..ec0fe27 100644 --- a/src/v4/moth/qv4instr_moth_p.h +++ b/src/v4/moth/qv4instr_moth_p.h @@ -25,7 +25,6 @@ F(CallBuiltinFinishTry, callBuiltinFinishTry) \ F(CallBuiltinGetException, callBuiltinGetException) \ F(CallBuiltinPushScope, callBuiltinPushScope) \ - F(CallBuiltinPushCatchScope, callBuiltinPushCatchScope) \ F(CallBuiltinPopScope, callBuiltinPopScope) \ F(CallBuiltinForeachIteratorObject, callBuiltinForeachIteratorObject) \ F(CallBuiltinForeachNextPropertyName, callBuiltinForeachNextPropertyName) \ @@ -214,6 +213,7 @@ union Instr MOTH_INSTR_HEADER ptrdiff_t tryOffset; ptrdiff_t catchOffset; + VM::String *exceptionVarName; }; struct instr_callValue { MOTH_INSTR_HEADER @@ -260,10 +260,6 @@ union Instr MOTH_INSTR_HEADER Param arg; }; - struct instr_callBuiltinPushCatchScope { - MOTH_INSTR_HEADER - VM::String *varName; - }; struct instr_callBuiltinPopScope { MOTH_INSTR_HEADER }; @@ -474,7 +470,6 @@ union Instr instr_callBuiltinFinishTry callBuiltinFinishTry; instr_callBuiltinGetException callBuiltinGetException; instr_callBuiltinPushScope callBuiltinPushScope; - instr_callBuiltinPushCatchScope callBuiltinPushCatchScope; instr_callBuiltinPopScope callBuiltinPopScope; instr_callBuiltinForeachIteratorObject callBuiltinForeachIteratorObject; instr_callBuiltinForeachNextPropertyName callBuiltinForeachNextPropertyName; diff --git a/src/v4/moth/qv4isel_moth.cpp b/src/v4/moth/qv4isel_moth.cpp index 46a40d0..b45b4c0 100644 --- a/src/v4/moth/qv4isel_moth.cpp +++ b/src/v4/moth/qv4isel_moth.cpp @@ -682,6 +682,7 @@ void InstructionSelection::visitTry(IR::Try *t) Instruction::EnterTry enterTry; enterTry.tryOffset = 0; enterTry.catchOffset = 0; + enterTry.exceptionVarName = identifier(t->exceptionVarName); ptrdiff_t enterTryLoc = addInstruction(enterTry); ptrdiff_t tryLoc = enterTryLoc + (((const char *)&enterTry.tryOffset) - ((const char *)&enterTry)); @@ -879,13 +880,6 @@ void InstructionSelection::callBuiltinPushWithScope(IR::Temp *arg) addInstruction(call); } -void InstructionSelection::callBuiltinPushCatchScope(const QString &exceptionVarName) -{ - Instruction::CallBuiltinPushCatchScope call; - call.varName = identifier(exceptionVarName); - addInstruction(call); -} - void InstructionSelection::callBuiltinPopScope() { Instruction::CallBuiltinPopScope call; diff --git a/src/v4/moth/qv4isel_moth_p.h b/src/v4/moth/qv4isel_moth_p.h index 04bb72d..39dc92d 100644 --- a/src/v4/moth/qv4isel_moth_p.h +++ b/src/v4/moth/qv4isel_moth_p.h @@ -49,7 +49,6 @@ protected: virtual void callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinForeachNextPropertyname(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinPushWithScope(IR::Temp *arg); - virtual void callBuiltinPushCatchScope(const QString &exceptionVarName); virtual void callBuiltinPopScope(); virtual void callBuiltinDeclareVar(bool deletable, const QString &name); virtual void callBuiltinDefineGetterSetter(IR::Temp *object, const QString &name, IR::Temp *getter, IR::Temp *setter); diff --git a/src/v4/moth/qv4vme_moth.cpp b/src/v4/moth/qv4vme_moth.cpp index e47dae2..401752f 100644 --- a/src/v4/moth/qv4vme_moth.cpp +++ b/src/v4/moth/qv4vme_moth.cpp @@ -267,9 +267,11 @@ VM::Value VME::run(QQmlJS::VM::ExecutionContext *context, const uchar *&code, } catch (VM::Exception &ex) { ex.accept(context); try { + VM::ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(instr.exceptionVarName, context); const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset; - run(context, catchCode, stack, stackSize); + run(catchContext, catchCode, stack, stackSize); code = catchCode; + context = __qmljs_builtin_pop_scope(catchContext); } catch (VM::Exception &ex) { ex.accept(context); const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset; @@ -291,10 +293,6 @@ VM::Value VME::run(QQmlJS::VM::ExecutionContext *context, const uchar *&code, context = __qmljs_builtin_push_with_scope(VALUE(instr.arg), context); MOTH_END_INSTR(CallBuiltinPushScope) - MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope) - context = __qmljs_builtin_push_catch_scope(instr.varName, context); - MOTH_END_INSTR(CallBuiltinPushCatchScope) - MOTH_BEGIN_INSTR(CallBuiltinPopScope) context = __qmljs_builtin_pop_scope(context); MOTH_END_INSTR(CallBuiltinPopScope) diff --git a/src/v4/qv4codegen.cpp b/src/v4/qv4codegen.cpp index 8946041..76f5b90 100644 --- a/src/v4/qv4codegen.cpp +++ b/src/v4/qv4codegen.cpp @@ -2475,7 +2475,7 @@ bool Codegen::visit(TryStatement *ast) ScopeAndFinally tcf(_scopeAndFinally, ast->finallyExpression, finishTryArgs); _scopeAndFinally = &tcf; - _block->TRY(tryBody, catchBody); + _block->TRY(tryBody, catchBody, ast->catchExpression ? ast->catchExpression->name.toString() : QString()); _block = tryBody; statement(ast->statement); @@ -2494,21 +2494,15 @@ bool Codegen::visit(TryStatement *ast) move(_block->TEMP(hasException), _block->CONST(IR::BoolType, true)); if (ast->catchExpression) { - IR::ExprList *catchScopeArgs = _function->New(); - catchScopeArgs->init(_block->NAME(ast->catchExpression->name.toString(), ast->catchExpression->identifierToken.startLine, ast->catchExpression->identifierToken.startColumn)); - _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_push_catch_scope, 0, 0), catchScopeArgs)); - ++_function->insideWithOrCatch; { - ScopeAndFinally scope(_scopeAndFinally); + ScopeAndFinally scope(_scopeAndFinally, ScopeAndFinally::CatchScope); _scopeAndFinally = &scope; statement(ast->catchExpression->statement); _scopeAndFinally = scope.parent; } --_function->insideWithOrCatch; - move(_block->TEMP(hasException), _block->CONST(IR::BoolType, false)); - _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_pop_scope, 0, 0))); } _block->JUMP(finallyBody); @@ -2543,16 +2537,22 @@ void Codegen::unwindException(Codegen::ScopeAndFinally *outest) ScopeAndFinally *scopeAndFinally = _scopeAndFinally; qSwap(_scopeAndFinally, scopeAndFinally); while (_scopeAndFinally != outest) { - if (_scopeAndFinally->popScope) { + switch (_scopeAndFinally->type) { + case ScopeAndFinally::WithScope: _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_pop_scope, 0, 0))); + // fall through + case ScopeAndFinally::CatchScope: _scopeAndFinally = _scopeAndFinally->parent; --_function->insideWithOrCatch; - } else { + break; + case ScopeAndFinally::TryScope: { _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_finish_try, 0, 0), _scopeAndFinally->finishTryArgs)); ScopeAndFinally *tc = _scopeAndFinally; _scopeAndFinally = tc->parent; if (tc->finally && tc->finally->statement) statement(tc->finally->statement); + break; + } } } qSwap(_scopeAndFinally, scopeAndFinally); diff --git a/src/v4/qv4codegen_p.h b/src/v4/qv4codegen_p.h index 283e282..1825396 100644 --- a/src/v4/qv4codegen_p.h +++ b/src/v4/qv4codegen_p.h @@ -215,14 +215,20 @@ protected: }; struct ScopeAndFinally { + enum ScopeType { + WithScope, + TryScope, + CatchScope + }; + ScopeAndFinally *parent; AST::Finally *finally; IR::ExprList *finishTryArgs; - bool popScope; + ScopeType type; - ScopeAndFinally(ScopeAndFinally *parent) : parent(parent), finally(0), finishTryArgs(0), popScope(true) {} + ScopeAndFinally(ScopeAndFinally *parent, ScopeType t = WithScope) : parent(parent), finally(0), finishTryArgs(0), type(t) {} ScopeAndFinally(ScopeAndFinally *parent, AST::Finally *finally, IR::ExprList *finishTryArgs) - : parent(parent), finally(finally), finishTryArgs(finishTryArgs), popScope(false) + : parent(parent), finally(finally), finishTryArgs(finishTryArgs), type(TryScope) {} }; diff --git a/src/v4/qv4isel_llvm_p.h b/src/v4/qv4isel_llvm_p.h index 0f34547..cf9aaed 100644 --- a/src/v4/qv4isel_llvm_p.h +++ b/src/v4/qv4isel_llvm_p.h @@ -94,7 +94,6 @@ public: // methods from InstructionSelection: virtual void callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinForeachNextPropertyname(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinPushWithScope(IR::Temp *arg); - virtual void callBuiltinPushCatchScope(const QString &exceptionVarName){} virtual void callBuiltinPopScope(); virtual void callBuiltinDeclareVar(bool deletable, const QString &name); virtual void callBuiltinDefineGetterSetter(IR::Temp *object, const QString &name, IR::Temp *getter, IR::Temp *setter); diff --git a/src/v4/qv4isel_masm.cpp b/src/v4/qv4isel_masm.cpp index 69e6d21..28a5c7b 100644 --- a/src/v4/qv4isel_masm.cpp +++ b/src/v4/qv4isel_masm.cpp @@ -677,7 +677,8 @@ void InstructionSelection::callBuiltinThrow(IR::Temp *arg) } typedef void *(*MiddleOfFunctionEntryPoint(ExecutionContext *, void *localsPtr)); -static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunctionEntryPoint tryBody, MiddleOfFunctionEntryPoint catchBody) +static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunctionEntryPoint tryBody, MiddleOfFunctionEntryPoint catchBody, + VM::String *exceptionVarName) { void *addressToContinueAt = 0; try { @@ -685,7 +686,9 @@ static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunc } catch (Exception& ex) { ex.accept(context); try { - addressToContinueAt = catchBody(context, localsPtr); + ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(exceptionVarName, context); + addressToContinueAt = catchBody(catchContext, localsPtr); + context = __qmljs_builtin_pop_scope(catchContext); } catch (Exception& ex) { ex.accept(context); addressToContinueAt = catchBody(context, localsPtr); @@ -706,7 +709,8 @@ void InstructionSelection::visitTry(IR::Try *t) _reentryBlocks.insert(t->catchBlock); generateFunctionCall(Assembler::ReturnValueRegister, tryWrapper, Assembler::ContextRegister, Assembler::LocalsRegister, - Assembler::ReentryBlock(t->tryBlock), Assembler::ReentryBlock(t->catchBlock)); + Assembler::ReentryBlock(t->tryBlock), Assembler::ReentryBlock(t->catchBlock), + identifier(t->exceptionVarName)); _as->jump(Assembler::ReturnValueRegister); } @@ -740,11 +744,6 @@ void InstructionSelection::callBuiltinPushWithScope(IR::Temp *arg) generateFunctionCall(Assembler::ContextRegister, __qmljs_builtin_push_with_scope, Assembler::Reference(arg), Assembler::ContextRegister); } -void InstructionSelection::callBuiltinPushCatchScope(const QString &exceptionVarName) -{ - generateFunctionCall(Assembler::ContextRegister, __qmljs_builtin_push_catch_scope, identifier(exceptionVarName), Assembler::ContextRegister); -} - void InstructionSelection::callBuiltinPopScope() { generateFunctionCall(Assembler::ContextRegister, __qmljs_builtin_pop_scope, Assembler::ContextRegister); diff --git a/src/v4/qv4isel_masm_p.h b/src/v4/qv4isel_masm_p.h index 92b30ab..8143020 100644 --- a/src/v4/qv4isel_masm_p.h +++ b/src/v4/qv4isel_masm_p.h @@ -792,7 +792,6 @@ protected: virtual void callBuiltinForeachIteratorObject(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinForeachNextPropertyname(IR::Temp *arg, IR::Temp *result); virtual void callBuiltinPushWithScope(IR::Temp *arg); - virtual void callBuiltinPushCatchScope(const QString &exceptionVarName); virtual void callBuiltinPopScope(); virtual void callBuiltinDeclareVar(bool deletable, const QString &name); virtual void callBuiltinDefineGetterSetter(IR::Temp *object, const QString &name, IR::Temp *getter, IR::Temp *setter); diff --git a/src/v4/qv4isel_p.cpp b/src/v4/qv4isel_p.cpp index 85758df..1651555 100644 --- a/src/v4/qv4isel_p.cpp +++ b/src/v4/qv4isel_p.cpp @@ -335,12 +335,6 @@ void InstructionSelection::callBuiltin(IR::Call *call, IR::Temp *result) callBuiltinPushWithScope(arg); } return; - case IR::Name::builtin_push_catch_scope: { - IR::Name *arg = call->args->expr->asName(); - assert(arg != 0); - callBuiltinPushCatchScope(*arg->id); - } return; - case IR::Name::builtin_pop_scope: callBuiltinPopScope(); return; diff --git a/src/v4/qv4isel_p.h b/src/v4/qv4isel_p.h index 9226f06..ae99bf6 100644 --- a/src/v4/qv4isel_p.h +++ b/src/v4/qv4isel_p.h @@ -108,7 +108,6 @@ public: // to implement by subclasses: 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; - virtual void callBuiltinPushCatchScope(const QString &exceptionVarName) = 0; virtual void callBuiltinPopScope() = 0; virtual void callBuiltinDeclareVar(bool deletable, const QString &name) = 0; virtual void callBuiltinDefineGetterSetter(IR::Temp *object, const QString &name, IR::Temp *getter, IR::Temp *setter) = 0; diff --git a/src/v4/qv4jsir.cpp b/src/v4/qv4jsir.cpp index c4953a8..b5de42e 100644 --- a/src/v4/qv4jsir.cpp +++ b/src/v4/qv4jsir.cpp @@ -366,8 +366,6 @@ static const char *builtin_to_string(Name::Builtin b) return "builtin_foreach_next_property_name"; case IR::Name::builtin_push_with_scope: return "builtin_push_with_scope"; - case IR::Name::builtin_push_catch_scope: - return "builtin_push_catch_scope"; case IR::Name::builtin_pop_scope: return "builtin_pop_scope"; case IR::Name::builtin_declare_vars: @@ -526,7 +524,7 @@ void Ret::dump(QTextStream &out, Mode) void Try::dump(QTextStream &out, Stmt::Mode mode) { - out << "try L" << tryBlock->index << "; catch L" << catchBlock->index << ';'; + out << "try L" << tryBlock->index << "; catch exception as " << exceptionVarName << " and go to L" << catchBlock->index << ';'; } Function *Module::newFunction(const QString &name, Function *outer) @@ -793,13 +791,13 @@ Stmt *BasicBlock::RET(Temp *expr) return s; } -Stmt *BasicBlock::TRY(BasicBlock *tryBlock, BasicBlock *catchBlock) +Stmt *BasicBlock::TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName) { if (isTerminated()) return 0; Try *t = function->New(); - t->init(tryBlock, catchBlock); + t->init(tryBlock, catchBlock, exceptionVarName); statements.append(t); assert(! out.contains(tryBlock)); diff --git a/src/v4/qv4jsir_p.h b/src/v4/qv4jsir_p.h index 570b0db..e4d8e1e 100644 --- a/src/v4/qv4jsir_p.h +++ b/src/v4/qv4jsir_p.h @@ -296,7 +296,6 @@ struct Name: Expr { builtin_foreach_iterator_object, builtin_foreach_next_property_name, builtin_push_with_scope, - builtin_push_catch_scope, builtin_pop_scope, builtin_declare_vars, builtin_define_property, @@ -608,11 +607,13 @@ struct Ret: Stmt { struct Try: Stmt { BasicBlock *tryBlock; BasicBlock *catchBlock; + QString exceptionVarName; - void init(BasicBlock *tryBlock, BasicBlock *catchBlock) + void init(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName) { this->tryBlock = tryBlock; this->catchBlock = catchBlock; + this->exceptionVarName = exceptionVarName; } virtual Stmt *asTerminator() { return this; } @@ -749,7 +750,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); + Stmt *TRY(BasicBlock *tryBlock, BasicBlock *catchBlock, const QString &exceptionVarName); void dump(QTextStream &out, Stmt::Mode mode = Stmt::HIR); };