Mercurial > projects > ddmd
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 } |