Mercurial > projects > ldc
annotate ir/irlandingpad.cpp @ 1351:8d501abecd24
Initial (but disabled) fix for ticket #294 , the actual part that fixes the bug is in a #if 0 block as I'm afraid it will cause regressions. I'm most likely not going to be around tonight, and maybe not tomorrow as well, so I'm pushing it in case someone wants to run some serious testing/investigate the problem noted in llvmhelpers.cpp : realignOffset .
author | Tomas Lindquist Olsen <tomas.l.olsen gmail com> |
---|---|
date | Thu, 14 May 2009 17:20:17 +0200 |
parents | 15e9762bb620 |
children | 3f5ea912149d |
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 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
13 target = llvm::BasicBlock::Create("catch", gIR->topfunc(), end); |
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); |
5761d7e6f628
Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents:
612
diff
changeset
|
27 LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage(); |
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 |
5761d7e6f628
Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents:
612
diff
changeset
|
35 if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPad.getExceptionStorage()) { |
5761d7e6f628
Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents:
612
diff
changeset
|
36 LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPad.getExceptionStorage()), 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
|
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) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
136 selectorargs.push_back(llvm::ConstantInt::get(LLType::Int32Ty, 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"); |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
140 LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::Int8Ty)); |
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 |
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
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>); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
154 llvm::Function* eh_selector_fn; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
155 if (global.params.is64bit) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
156 eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i64); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
157 else |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
158 eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i32); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
159 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
|
160 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
161 // 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
|
162 // then simply branch to the finally chain |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
163 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
|
164 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
|
165 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
|
166 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
167 // 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
|
168 if(rit->finallyBody) |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
169 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
170 if(switchinst) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
171 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
|
172 |
d8357f7004ca
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents:
349
diff
changeset
|
173 // 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
|
174 // give the labels a new scope |
d8357f7004ca
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents:
349
diff
changeset
|
175 gIR->func()->pushUniqueLabelScope("finally"); |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
176 rit->finallyBody->toIR(gIR); |
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
|
177 gIR->func()->popLabelScope(); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
178 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
179 // 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
|
180 else |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
181 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
182 if(!switchinst) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
183 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
184 switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create("switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size()); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
185 gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend()); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
186 } |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
187 // dubious comment |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
188 // catches matched first get the largest switchval, so do size - unique int |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
189 llvm::ConstantInt* switchval = llvm::ConstantInt::get(DtoSize_t(), catchToInt[rit->catchType]); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
190 // 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
|
191 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
|
192 switchinst->addCase(switchval, rit->target); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
193 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
194 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
195 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
196 // 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
|
197 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
|
198 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
|
199 gIR->ir->CreateUnreachable(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
200 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
201 gIR->scope() = savedscope; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
202 } |
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 LLValue* IRLandingPad::getExceptionStorage() |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
205 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
206 if(!catch_var) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
207 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
208 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
|
209 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
|
210 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
211 return catch_var; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
212 } |