Mercurial > projects > ddmd
comparison dmd/TryFinallyStatement.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 2e2a5c3f943a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
1 module dmd.TryFinallyStatement; | |
2 | |
3 import dmd.Statement; | |
4 import dmd.Loc; | |
5 import dmd.OutBuffer; | |
6 import dmd.HdrGenState; | |
7 import dmd.Scope; | |
8 import dmd.InlineScanState; | |
9 import dmd.CompoundStatement; | |
10 import dmd.IRState; | |
11 import dmd.BE; | |
12 | |
13 import dmd.backend.block; | |
14 import dmd.backend.Blockx; | |
15 import dmd.backend.BC; | |
16 import dmd.backend.Util; | |
17 | |
18 import dmd.codegen.Util; | |
19 | |
20 class TryFinallyStatement : Statement | |
21 { | |
22 Statement body_; | |
23 Statement finalbody; | |
24 | |
25 this(Loc loc, Statement body_, Statement finalbody) | |
26 { | |
27 super(loc); | |
28 this.body_ = body_; | |
29 this.finalbody = finalbody; | |
30 } | |
31 | |
32 Statement syntaxCopy() | |
33 { | |
34 assert(false); | |
35 } | |
36 | |
37 void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
38 { | |
39 assert(false); | |
40 } | |
41 | |
42 Statement semantic(Scope sc) | |
43 { | |
44 //printf("TryFinallyStatement::semantic()\n"); | |
45 body_ = body_.semantic(sc); | |
46 sc = sc.push(); | |
47 sc.tf = this; | |
48 sc.sbreak = null; | |
49 sc.scontinue = null; // no break or continue out of finally block | |
50 finalbody = finalbody.semantic(sc); | |
51 sc.pop(); | |
52 if (!body_) | |
53 return finalbody; | |
54 if (!finalbody) | |
55 return body_; | |
56 if (body_.blockExit() == BE.BEfallthru) | |
57 { | |
58 Statement s = new CompoundStatement(loc, body_, finalbody); | |
59 return s; | |
60 } | |
61 return this; | |
62 } | |
63 | |
64 bool hasBreak() | |
65 { | |
66 assert(false); | |
67 } | |
68 | |
69 bool hasContinue() | |
70 { | |
71 assert(false); | |
72 } | |
73 | |
74 bool usesEH() | |
75 { | |
76 assert(false); | |
77 } | |
78 | |
79 BE blockExit() | |
80 { | |
81 if (body_) | |
82 return body_.blockExit(); | |
83 return BE.BEfallthru; | |
84 } | |
85 | |
86 Statement inlineScan(InlineScanState* iss) | |
87 { | |
88 if (body_) | |
89 body_ = body_.inlineScan(iss); | |
90 if (finalbody) | |
91 finalbody = finalbody.inlineScan(iss); | |
92 return this; | |
93 } | |
94 | |
95 /**************************************** | |
96 * A try-finally statement. | |
97 * Builds the following: | |
98 * _try | |
99 * block | |
100 * _finally | |
101 * finalbody | |
102 * _ret | |
103 */ | |
104 void toIR(IRState* irs) | |
105 { | |
106 //printf("TryFinallyStatement.toIR()\n"); | |
107 Blockx* blx = irs.blx; | |
108 | |
109 version (SEH) { | |
110 nteh_declarvars(blx); | |
111 } | |
112 | |
113 block* tryblock = block_goto(blx, BCgoto, null); | |
114 | |
115 int previndex = blx.scope_index; | |
116 tryblock.Blast_index = previndex; | |
117 tryblock.Bscope_index = blx.next_index++; | |
118 blx.scope_index = tryblock.Bscope_index; | |
119 | |
120 // Current scope index | |
121 setScopeIndex(blx,tryblock,tryblock.Bscope_index); | |
122 | |
123 blx.tryblock = tryblock; | |
124 block_goto(blx,BC_try,null); | |
125 | |
126 IRState bodyirs = IRState(irs, this); | |
127 block* breakblock = block_calloc(blx); | |
128 block* contblock = block_calloc(blx); | |
129 | |
130 if (body_) | |
131 body_.toIR(&bodyirs); | |
132 blx.tryblock = tryblock.Btry; // back to previous tryblock | |
133 | |
134 setScopeIndex(blx,blx.curblock,previndex); | |
135 blx.scope_index = previndex; | |
136 | |
137 block_goto(blx,BCgoto, breakblock); | |
138 block* finallyblock = block_goto(blx,BCgoto,contblock); | |
139 | |
140 list_append(&tryblock.Bsucc,finallyblock); | |
141 | |
142 block_goto(blx,BC_finally,null); | |
143 | |
144 IRState finallyState = IRState(irs, this); | |
145 breakblock = block_calloc(blx); | |
146 contblock = block_calloc(blx); | |
147 | |
148 setScopeIndex(blx, blx.curblock, previndex); | |
149 if (finalbody) | |
150 finalbody.toIR(&finallyState); | |
151 block_goto(blx, BCgoto, contblock); | |
152 block_goto(blx, BCgoto, breakblock); | |
153 | |
154 block* retblock = blx.curblock; | |
155 block_next(blx,BC_ret,null); | |
156 | |
157 list_append(&finallyblock.Bsucc, blx.curblock); | |
158 list_append(&retblock.Bsucc, blx.curblock); | |
159 } | |
160 } |