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