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