Mercurial > projects > ddmd
annotate dmd/SynchronizedStatement.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
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 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
40 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
41 |
0 | 42 class SynchronizedStatement : Statement |
43 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
44 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
45 |
0 | 46 Expression exp; |
47 Statement body_; | |
48 | |
49 this(Loc loc, Expression exp, Statement body_) | |
50 { | |
178 | 51 register(); |
0 | 52 super(loc); |
53 | |
54 this.exp = exp; | |
55 this.body_ = body_; | |
56 this.esync = null; | |
57 } | |
58 | |
72 | 59 override Statement syntaxCopy() |
0 | 60 { |
61 assert(false); | |
62 } | |
63 | |
72 | 64 override Statement semantic(Scope sc) |
0 | 65 { |
66 if (exp) | |
67 { | |
68 exp = exp.semantic(sc); | |
69 exp = resolveProperties(sc, exp); | |
70 ClassDeclaration cd = exp.type.isClassHandle(); | |
71 if (!cd) | |
72 error("can only synchronize on class objects, not '%s'", exp.type.toChars()); | |
73 else if (cd.isInterfaceDeclaration()) | |
74 { | |
75 /* Cast the interface to an object, as the object has the monitor, | |
76 * not the interface. | |
77 */ | |
78 Type t = new TypeIdentifier(Loc(0), Id.Object_); | |
79 | |
80 t = t.semantic(Loc(0), sc); | |
81 exp = new CastExp(loc, exp, t); | |
82 exp = exp.semantic(sc); | |
83 } | |
84 | |
85 static if (true) { | |
86 /* Rewrite as: | |
87 * auto tmp = exp; | |
88 * _d_monitorenter(tmp); | |
89 * try { body } finally { _d_monitorexit(tmp); } | |
90 */ | |
91 Identifier id = Lexer.uniqueId("__sync"); | |
92 ExpInitializer ie = new ExpInitializer(loc, exp); | |
93 VarDeclaration tmp = new VarDeclaration(loc, exp.type, id, ie); | |
94 | |
95 Statements cs = new Statements(); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
96 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp))); |
0 | 97 |
98 FuncDeclaration fdenter = FuncDeclaration.genCfunc(Type.tvoid, Id.monitorenter); | |
99 Expression e = new CallExp(loc, new VarExp(loc, fdenter), new VarExp(loc, tmp)); | |
100 e.type = Type.tvoid; // do not run semantic on e | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
101 cs.push(new ExpStatement(loc, e)); |
0 | 102 |
103 FuncDeclaration fdexit = FuncDeclaration.genCfunc(Type.tvoid, Id.monitorexit); | |
104 e = new CallExp(loc, new VarExp(loc, fdexit), new VarExp(loc, tmp)); | |
105 e.type = Type.tvoid; // do not run semantic on e | |
106 Statement s = new ExpStatement(loc, e); | |
107 s = new TryFinallyStatement(loc, body_, s); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
108 cs.push(s); |
0 | 109 |
110 s = new CompoundStatement(loc, cs); | |
111 return s.semantic(sc); | |
112 } | |
113 } | |
114 /// static if (true) { | |
115 else | |
116 { | |
117 /* Generate our own critical section, then rewrite as: | |
118 * __gshared byte[CriticalSection.sizeof] critsec; | |
119 * _d_criticalenter(critsec.ptr); | |
120 * try { body } finally { _d_criticalexit(critsec.ptr); } | |
121 */ | |
122 Identifier id = Lexer.uniqueId("__critsec"); | |
123 Type t = new TypeSArray(Type.tint8, new IntegerExp(PTRSIZE + os_critsecsize())); | |
124 VarDeclaration tmp = new VarDeclaration(loc, t, id, null); | |
125 tmp.storage_class |= STCgshared | STCstatic; | |
126 | |
127 Statements cs = new Statements(); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
128 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp))); |
0 | 129 |
130 FuncDeclaration fdenter = FuncDeclaration.genCfunc(Type.tvoid, Id.criticalenter); | |
131 Expression e = new DotIdExp(loc, new VarExp(loc, tmp), Id.ptr); | |
132 e = e.semantic(sc); | |
133 e = new CallExp(loc, new VarExp(loc, fdenter), e); | |
134 e.type = Type.tvoid; // do not run semantic on e | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
135 cs.push(new ExpStatement(loc, e)); |
0 | 136 |
137 FuncDeclaration fdexit = FuncDeclaration.genCfunc(Type.tvoid, Id.criticalexit); | |
138 e = new DotIdExp(loc, new VarExp(loc, tmp), Id.ptr); | |
139 e = e.semantic(sc); | |
140 e = new CallExp(loc, new VarExp(loc, fdexit), e); | |
141 e.type = Type.tvoid; // do not run semantic on e | |
142 Statement s = new ExpStatement(loc, e); | |
143 s = new TryFinallyStatement(loc, body_, s); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
144 cs.push(s); |
0 | 145 |
146 s = new CompoundStatement(loc, cs); | |
147 return s.semantic(sc); | |
148 } | |
149 /// } | |
150 if (body_) | |
151 body_ = body_.semantic(sc); | |
152 | |
153 return this; | |
154 } | |
155 | |
72 | 156 override bool hasBreak() |
0 | 157 { |
158 assert(false); | |
159 } | |
160 | |
72 | 161 override bool hasContinue() |
0 | 162 { |
163 assert(false); | |
164 } | |
165 | |
72 | 166 override bool usesEH() |
0 | 167 { |
168 assert(false); | |
169 } | |
170 | |
72 | 171 override BE blockExit() |
0 | 172 { |
173 assert(false); | |
174 } | |
175 | |
72 | 176 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 177 { |
178 assert(false); | |
179 } | |
180 | |
72 | 181 override Statement inlineScan(InlineScanState* iss) |
0 | 182 { |
183 assert(false); | |
184 } | |
185 | |
186 // Back end | |
187 elem* esync; | |
188 | |
189 this(Loc loc, elem *esync, Statement body_) | |
190 { | |
178 | 191 register(); |
0 | 192 assert(false); |
193 super(loc); | |
194 } | |
195 | |
72 | 196 override void toIR(IRState* irs) |
0 | 197 { |
198 assert(false); | |
199 } | |
72 | 200 } |