Mercurial > projects > ddmd
annotate dmd/SynchronizedStatement.d @ 122:c77e9f4f1793
Statements -> Vector
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 02 Sep 2010 23:37:49 +0100 |
parents | e28b18c23469 |
children | e3afd1303184 |
rev | line source |
---|---|
0 | 1 module dmd.SynchronizedStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Statement; |
5 import dmd.IntegerExp; | |
6 import dmd.TypeSArray; | |
7 import dmd.CompoundStatement; | |
8 import dmd.Loc; | |
9 import dmd.Scope; | |
10 import dmd.Expression; | |
11 import dmd.ClassDeclaration; | |
12 import dmd.Id; | |
13 import dmd.TypeIdentifier; | |
14 import dmd.Type; | |
15 import dmd.OutBuffer; | |
16 import dmd.HdrGenState; | |
17 import dmd.InlineScanState; | |
18 import dmd.IRState; | |
19 import dmd.CastExp; | |
20 import dmd.TryFinallyStatement; | |
21 import dmd.ExpStatement; | |
22 import dmd.CallExp; | |
23 import dmd.DeclarationExp; | |
24 import dmd.VarExp; | |
25 import dmd.DeclarationStatement; | |
26 import dmd.ArrayTypes; | |
27 import dmd.Statement; | |
28 import dmd.VarDeclaration; | |
29 import dmd.ExpInitializer; | |
30 import dmd.Lexer; | |
31 import dmd.Identifier; | |
32 import dmd.FuncDeclaration; | |
33 import dmd.BE; | |
34 import dmd.STC; | |
35 import dmd.DotIdExp; | |
36 | |
37 import dmd.backend.elem; | |
38 import dmd.backend.Util; | |
39 | |
40 class SynchronizedStatement : Statement | |
41 { | |
42 Expression exp; | |
43 Statement body_; | |
44 | |
45 this(Loc loc, Expression exp, Statement body_) | |
46 { | |
47 super(loc); | |
48 | |
49 this.exp = exp; | |
50 this.body_ = body_; | |
51 this.esync = null; | |
52 } | |
53 | |
72 | 54 override Statement syntaxCopy() |
0 | 55 { |
56 assert(false); | |
57 } | |
58 | |
72 | 59 override Statement semantic(Scope sc) |
0 | 60 { |
61 if (exp) | |
62 { | |
63 exp = exp.semantic(sc); | |
64 exp = resolveProperties(sc, exp); | |
65 ClassDeclaration cd = exp.type.isClassHandle(); | |
66 if (!cd) | |
67 error("can only synchronize on class objects, not '%s'", exp.type.toChars()); | |
68 else if (cd.isInterfaceDeclaration()) | |
69 { | |
70 /* Cast the interface to an object, as the object has the monitor, | |
71 * not the interface. | |
72 */ | |
73 Type t = new TypeIdentifier(Loc(0), Id.Object_); | |
74 | |
75 t = t.semantic(Loc(0), sc); | |
76 exp = new CastExp(loc, exp, t); | |
77 exp = exp.semantic(sc); | |
78 } | |
79 | |
80 static if (true) { | |
81 /* Rewrite as: | |
82 * auto tmp = exp; | |
83 * _d_monitorenter(tmp); | |
84 * try { body } finally { _d_monitorexit(tmp); } | |
85 */ | |
86 Identifier id = Lexer.uniqueId("__sync"); | |
87 ExpInitializer ie = new ExpInitializer(loc, exp); | |
88 VarDeclaration tmp = new VarDeclaration(loc, exp.type, id, ie); | |
89 | |
90 Statements cs = new Statements(); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
91 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp))); |
0 | 92 |
93 FuncDeclaration fdenter = FuncDeclaration.genCfunc(Type.tvoid, Id.monitorenter); | |
94 Expression e = new CallExp(loc, new VarExp(loc, fdenter), new VarExp(loc, tmp)); | |
95 e.type = Type.tvoid; // do not run semantic on e | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
96 cs.push(new ExpStatement(loc, e)); |
0 | 97 |
98 FuncDeclaration fdexit = FuncDeclaration.genCfunc(Type.tvoid, Id.monitorexit); | |
99 e = new CallExp(loc, new VarExp(loc, fdexit), new VarExp(loc, tmp)); | |
100 e.type = Type.tvoid; // do not run semantic on e | |
101 Statement s = new ExpStatement(loc, e); | |
102 s = new TryFinallyStatement(loc, body_, s); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
103 cs.push(s); |
0 | 104 |
105 s = new CompoundStatement(loc, cs); | |
106 return s.semantic(sc); | |
107 } | |
108 } | |
109 /// static if (true) { | |
110 else | |
111 { | |
112 /* Generate our own critical section, then rewrite as: | |
113 * __gshared byte[CriticalSection.sizeof] critsec; | |
114 * _d_criticalenter(critsec.ptr); | |
115 * try { body } finally { _d_criticalexit(critsec.ptr); } | |
116 */ | |
117 Identifier id = Lexer.uniqueId("__critsec"); | |
118 Type t = new TypeSArray(Type.tint8, new IntegerExp(PTRSIZE + os_critsecsize())); | |
119 VarDeclaration tmp = new VarDeclaration(loc, t, id, null); | |
120 tmp.storage_class |= STCgshared | STCstatic; | |
121 | |
122 Statements cs = new Statements(); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
123 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp))); |
0 | 124 |
125 FuncDeclaration fdenter = FuncDeclaration.genCfunc(Type.tvoid, Id.criticalenter); | |
126 Expression e = new DotIdExp(loc, new VarExp(loc, tmp), Id.ptr); | |
127 e = e.semantic(sc); | |
128 e = new CallExp(loc, new VarExp(loc, fdenter), e); | |
129 e.type = Type.tvoid; // do not run semantic on e | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
130 cs.push(new ExpStatement(loc, e)); |
0 | 131 |
132 FuncDeclaration fdexit = FuncDeclaration.genCfunc(Type.tvoid, Id.criticalexit); | |
133 e = new DotIdExp(loc, new VarExp(loc, tmp), Id.ptr); | |
134 e = e.semantic(sc); | |
135 e = new CallExp(loc, new VarExp(loc, fdexit), e); | |
136 e.type = Type.tvoid; // do not run semantic on e | |
137 Statement s = new ExpStatement(loc, e); | |
138 s = new TryFinallyStatement(loc, body_, s); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
139 cs.push(s); |
0 | 140 |
141 s = new CompoundStatement(loc, cs); | |
142 return s.semantic(sc); | |
143 } | |
144 /// } | |
145 if (body_) | |
146 body_ = body_.semantic(sc); | |
147 | |
148 return this; | |
149 } | |
150 | |
72 | 151 override bool hasBreak() |
0 | 152 { |
153 assert(false); | |
154 } | |
155 | |
72 | 156 override bool hasContinue() |
0 | 157 { |
158 assert(false); | |
159 } | |
160 | |
72 | 161 override bool usesEH() |
0 | 162 { |
163 assert(false); | |
164 } | |
165 | |
72 | 166 override BE blockExit() |
0 | 167 { |
168 assert(false); | |
169 } | |
170 | |
72 | 171 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 172 { |
173 assert(false); | |
174 } | |
175 | |
72 | 176 override Statement inlineScan(InlineScanState* iss) |
0 | 177 { |
178 assert(false); | |
179 } | |
180 | |
181 // Back end | |
182 elem* esync; | |
183 | |
184 this(Loc loc, elem *esync, Statement body_) | |
185 { | |
186 assert(false); | |
187 super(loc); | |
188 } | |
189 | |
72 | 190 override void toIR(IRState* irs) |
0 | 191 { |
192 assert(false); | |
193 } | |
72 | 194 } |