annotate ir/irlandingpad.cpp @ 1651:cb960b882ca3 default tip

bindings were moved to dsource.org/projects/bindings/
author Moritz Warning <moritzwarning@web.de>
date Thu, 20 May 2010 20:05:03 +0200
parents 40bd4a0d4870
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
1 #include "gen/llvm.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
2 #include "gen/tollvm.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
3 #include "gen/irstate.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
4 #include "gen/runtime.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
5 #include "gen/logger.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
6 #include "gen/classes.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
7 #include "gen/llvmhelpers.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
8 #include "ir/irlandingpad.h"
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
9
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
10 IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
11 : finallyBody(NULL)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
12 {
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
13 target = llvm::BasicBlock::Create(gIR->context(), "catch", gIR->topfunc(), end);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
14 gIR->scope() = IRScope(target,end);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
15
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
16 // assign storage to catch var
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
17 if(catchstmt->var) {
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
18 // use the same storage for all exceptions that are not accessed in
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
19 // nested functions
758
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
20 #if DMDV2
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
21 if(!catchstmt->var->nestedrefs.dim) {
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
22 #else
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
23 if(!catchstmt->var->nestedref) {
758
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
24 #endif
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
25 assert(!catchstmt->var->ir.irLocal);
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
26 catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
27 LLValue* catch_var = gIR->func()->gen->landingPadInfo.getExceptionStorage();
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
28 catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
29 }
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
30
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
31 // this will alloca if we haven't already and take care of nested refs
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
32 DtoDeclarationExp(catchstmt->var);
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
33
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
34 // the exception will only be stored in catch_var. copy it over if necessary
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
35 if(catchstmt->var->ir.irLocal->value != gIR->func()->gen->landingPadInfo.getExceptionStorage()) {
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
36 LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->gen->landingPadInfo.getExceptionStorage()), DtoType(catchstmt->var->type));
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
37 DtoStore(exc, catchstmt->var->ir.irLocal->value);
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
38 }
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
39 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
40
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
41 // emit handler, if there is one
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
42 // handler is zero for instance for 'catch { debug foo(); }'
332
d7e6ace5cca4 [svn r353] Fix typo. (fixes empty catch handlers, like catch_02.d)
ChristianK
parents: 320
diff changeset
43 if(catchstmt->handler)
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
44 catchstmt->handler->toIR(gIR);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
45
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
46 if (!gIR->scopereturned())
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
47 gIR->ir->CreateBr(end);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
48
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
49 assert(catchstmt->type);
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
50 catchType = catchstmt->type->toBasetype()->isClassHandle();
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
51 assert(catchType);
1148
3d1b16dabd25 Eliminated the need for resolve, declare, const-init and define lists to drive code generation.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents: 758
diff changeset
52 catchType->codegen(Type::sir);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
53 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
54
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
55 IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
56 : target(NULL), finallyBody(finallystmt), catchType(NULL)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
57 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
58
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
59 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
60
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
61
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
62 void IRLandingPad::addCatch(Catch* catchstmt, llvm::BasicBlock* end)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
63 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
64 unpushed_infos.push_front(IRLandingPadInfo(catchstmt, end));
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
65 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
66
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
67 void IRLandingPad::addFinally(Statement* finallystmt)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
68 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
69 unpushed_infos.push_front(IRLandingPadInfo(finallystmt));
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
70 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
71
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
72 void IRLandingPad::push(llvm::BasicBlock* inBB)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
73 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
74 // store infos such that matches are right to left
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
75 nInfos.push(infos.size());
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
76 infos.insert(infos.end(), unpushed_infos.begin(), unpushed_infos.end());
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
77 unpushed_infos.clear();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
78
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
79 constructLandingPad(inBB);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
80
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
81 // store as invoke target
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
82 padBBs.push(inBB);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
83 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
84
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
85 void IRLandingPad::pop()
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
86 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
87 padBBs.pop();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
88
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
89 size_t n = nInfos.top();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
90 infos.resize(n);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
91 nInfos.pop();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
92 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
93
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
94 llvm::BasicBlock* IRLandingPad::get()
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
95 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
96 if(padBBs.size() == 0)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
97 return NULL;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
98 else
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
99 return padBBs.top();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
100 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
101
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
102 void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
103 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
104 // save and rewrite scope
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
105 IRScope savedscope = gIR->scope();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
106 gIR->scope() = IRScope(inBB,savedscope.end);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
107
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
108 // eh_ptr = llvm.eh.exception();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
109 llvm::Function* eh_exception_fn = GET_INTRINSIC_DECL(eh_exception);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
110 LLValue* eh_ptr = gIR->ir->CreateCall(eh_exception_fn);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
111
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
112 // build selector arguments
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
113 LLSmallVector<LLValue*, 6> selectorargs;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
114
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
115 // put in classinfos in the right order
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
116 bool hasFinally = false;
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
117 std::deque<IRLandingPadInfo>::iterator it = infos.begin(), end = infos.end();
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
118 for(; it != end; ++it)
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
119 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
120 if(it->finallyBody)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
121 hasFinally = true;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
122 else
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
123 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
124 if(catchToInt.find(it->catchType) == catchToInt.end())
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
125 {
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
126 int newval = 1 + catchToInt.size();
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
127 catchToInt[it->catchType] = newval;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
128 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
129 assert(it->catchType);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
130 assert(it->catchType->ir.irStruct);
1228
79758fd2f48a Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents: 1148
diff changeset
131 selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol());
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
132 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
133 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
134 // if there's a finally, the eh table has to have a 0 action
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
135 if(hasFinally)
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
136 selectorargs.push_back(DtoConstUint(0));
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
137
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
138 // personality fn
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
139 llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality");
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
140 LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context())));
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
141 selectorargs.insert(selectorargs.begin(), personality_fn_arg);
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
142
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
143 // eh storage target
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
144 selectorargs.insert(selectorargs.begin(), eh_ptr);
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
145
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
146 // if there is a catch and some catch allocated storage, store exception object
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
147 if(catchToInt.size() && catch_var)
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
148 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
149 const LLType* objectTy = DtoType(ClassDeclaration::object->type);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
150 gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
151 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
152
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
153 // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>);
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
154 llvm::Function* eh_selector_fn = GET_INTRINSIC_DECL(eh_selector);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
155 LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end());
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
156
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
157 // emit finallys and switches that branch to catches until there are no more catches
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
158 // then simply branch to the finally chain
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
159 llvm::SwitchInst* switchinst = NULL;
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
160 std::deque<IRLandingPadInfo>::reverse_iterator rit, rend = infos.rend();
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
161 for(rit = infos.rbegin(); rit != rend; ++rit)
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
162 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
163 // if it's a finally, emit its code
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
164 if(rit->finallyBody)
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
165 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
166 if(switchinst)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
167 switchinst = NULL;
355
d8357f7004ca [svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents: 349
diff changeset
168
d8357f7004ca [svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents: 349
diff changeset
169 // since this may be emitted multiple times
d8357f7004ca [svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents: 349
diff changeset
170 // give the labels a new scope
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
171 gIR->func()->gen->pushUniqueLabelScope("finally");
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
172 rit->finallyBody->toIR(gIR);
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
173 gIR->func()->gen->popLabelScope();
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
174 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
175 // otherwise it's a catch and we'll add a switch case
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
176 else
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
177 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
178 if(!switchinst)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
179 {
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
180 switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create(gIR->context(), "switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size());
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
181 gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend());
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
182 }
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
183 // dubious comment
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
184 // catches matched first get the largest switchval, so do size - unique int
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
185 llvm::ConstantInt* switchval = DtoConstUint(catchToInt[rit->catchType]);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
186 // and make sure we don't add the same switchval twice, may happen with nested trys
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
187 if(!switchinst->findCaseValue(switchval))
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
188 switchinst->addCase(switchval, rit->target);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
189 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
190 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
191
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
192 // no catch matched and all finallys executed - resume unwind
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
193 llvm::Function* unwind_resume_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_resume_unwind");
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
194 gIR->ir->CreateCall(unwind_resume_fn, eh_ptr);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
195 gIR->ir->CreateUnreachable();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
196
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
197 gIR->scope() = savedscope;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
198 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
199
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
200 LLValue* IRLandingPad::getExceptionStorage()
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
201 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
202 if(!catch_var)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
203 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
204 Logger::println("Making new catch var");
1350
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1228
diff changeset
205 catch_var = DtoAlloca(ClassDeclaration::object->type, "catchvar");
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
206 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
207 return catch_var;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
208 }