OLD | NEW |
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 library fletchc.fletch_system; | 5 library dartino_compiler.dartino_system; |
6 | 6 |
7 import 'package:compiler/src/constants/values.dart' show | 7 import 'package:compiler/src/constants/values.dart' show |
8 ConstantValue; | 8 ConstantValue; |
9 | 9 |
10 import 'package:compiler/src/elements/elements.dart' show | 10 import 'package:compiler/src/elements/elements.dart' show |
11 ClassElement, | 11 ClassElement, |
12 ConstructorElement, | 12 ConstructorElement, |
13 Element, | 13 Element, |
14 FieldElement, | 14 FieldElement, |
15 FunctionSignature; | 15 FunctionSignature; |
16 | 16 |
17 import 'package:compiler/src/universe/call_structure.dart' show | 17 import 'package:compiler/src/universe/call_structure.dart' show |
18 CallStructure; | 18 CallStructure; |
19 | 19 |
20 import 'package:persistent/persistent.dart' show | 20 import 'package:persistent/persistent.dart' show |
21 PersistentMap; | 21 PersistentMap; |
22 | 22 |
23 import 'bytecodes.dart'; | 23 import 'bytecodes.dart'; |
24 import 'vm_commands.dart'; | 24 import 'vm_commands.dart'; |
25 | 25 |
26 import 'src/fletch_selector.dart' show | 26 import 'src/dartino_selector.dart' show |
27 FletchSelector; | 27 DartinoSelector; |
28 | 28 |
29 import 'src/fletch_system_printer.dart' show | 29 import 'src/dartino_system_printer.dart' show |
30 FletchSystemPrinter; | 30 DartinoSystemPrinter; |
31 | 31 |
32 enum FletchFunctionKind { | 32 enum DartinoFunctionKind { |
33 NORMAL, | 33 NORMAL, |
34 LAZY_FIELD_INITIALIZER, | 34 LAZY_FIELD_INITIALIZER, |
35 INITIALIZER_LIST, | 35 INITIALIZER_LIST, |
36 PARAMETER_STUB, | 36 PARAMETER_STUB, |
37 ACCESSOR | 37 ACCESSOR |
38 } | 38 } |
39 | 39 |
40 // TODO(ajohnsen): Move to separate file. | 40 // TODO(ajohnsen): Move to separate file. |
41 class FletchConstant { | 41 class DartinoConstant { |
42 final int id; | 42 final int id; |
43 final MapId mapId; | 43 final MapId mapId; |
44 const FletchConstant(this.id, this.mapId); | 44 const DartinoConstant(this.id, this.mapId); |
45 | 45 |
46 String toString() => "FletchConstant($id, $mapId)"; | 46 String toString() => "DartinoConstant($id, $mapId)"; |
47 } | 47 } |
48 | 48 |
49 // TODO(ajohnsen): Move to separate file. | 49 // TODO(ajohnsen): Move to separate file. |
50 class FletchClass { | 50 class DartinoClass { |
51 final int classId; | 51 final int classId; |
52 final String name; | 52 final String name; |
53 final ClassElement element; | 53 final ClassElement element; |
54 final int superclassId; | 54 final int superclassId; |
55 final int superclassFields; | 55 final int superclassFields; |
56 final PersistentMap<int, int> methodTable; | 56 final PersistentMap<int, int> methodTable; |
57 final List<FieldElement> fields; | 57 final List<FieldElement> fields; |
58 | 58 |
59 const FletchClass( | 59 const DartinoClass( |
60 this.classId, | 60 this.classId, |
61 this.name, | 61 this.name, |
62 this.element, | 62 this.element, |
63 this.superclassId, | 63 this.superclassId, |
64 this.superclassFields, | 64 this.superclassFields, |
65 this.methodTable, | 65 this.methodTable, |
66 this.fields); | 66 this.fields); |
67 | 67 |
68 bool get hasSuperclassId => superclassId >= 0; | 68 bool get hasSuperclassId => superclassId >= 0; |
69 | 69 |
70 String toString() => "FletchClass($classId, '$name')"; | 70 String toString() => "DartinoClass($classId, '$name')"; |
71 } | 71 } |
72 | 72 |
73 // TODO(ajohnsen): Move to separate file. | 73 // TODO(ajohnsen): Move to separate file. |
74 abstract class FletchFunctionBase { | 74 abstract class DartinoFunctionBase { |
75 final int functionId; | 75 final int functionId; |
76 final FletchFunctionKind kind; | 76 final DartinoFunctionKind kind; |
77 // TODO(ajohnsen): Merge with function signature? | 77 // TODO(ajohnsen): Merge with function signature? |
78 final int arity; | 78 final int arity; |
79 // TODO(ajohnsen): Remove name? | 79 // TODO(ajohnsen): Remove name? |
80 final String name; | 80 final String name; |
81 final Element element; | 81 final Element element; |
82 | 82 |
83 /** | 83 /** |
84 * The signature of the FletchFunctionBuilder. | 84 * The signature of the DartinoFunctionBuilder. |
85 * | 85 * |
86 * Some compiled functions does not have a signature (for example, generated | 86 * Some compiled functions does not have a signature (for example, generated |
87 * accessors). | 87 * accessors). |
88 */ | 88 */ |
89 final FunctionSignature signature; | 89 final FunctionSignature signature; |
90 final int memberOf; | 90 final int memberOf; |
91 | 91 |
92 const FletchFunctionBase( | 92 const DartinoFunctionBase( |
93 this.functionId, | 93 this.functionId, |
94 this.kind, | 94 this.kind, |
95 this.arity, | 95 this.arity, |
96 this.name, | 96 this.name, |
97 this.element, | 97 this.element, |
98 this.signature, | 98 this.signature, |
99 this.memberOf); | 99 this.memberOf); |
100 | 100 |
101 bool get isInstanceMember => memberOf != null; | 101 bool get isInstanceMember => memberOf != null; |
102 bool get isInternal => element == null; | 102 bool get isInternal => element == null; |
103 | 103 |
104 bool get isLazyFieldInitializer { | 104 bool get isLazyFieldInitializer { |
105 return kind == FletchFunctionKind.LAZY_FIELD_INITIALIZER; | 105 return kind == DartinoFunctionKind.LAZY_FIELD_INITIALIZER; |
106 } | 106 } |
107 | 107 |
108 bool get isInitializerList { | 108 bool get isInitializerList { |
109 return kind == FletchFunctionKind.INITIALIZER_LIST; | 109 return kind == DartinoFunctionKind.INITIALIZER_LIST; |
110 } | 110 } |
111 | 111 |
112 bool get isAccessor { | 112 bool get isAccessor { |
113 return kind == FletchFunctionKind.ACCESSOR; | 113 return kind == DartinoFunctionKind.ACCESSOR; |
114 } | 114 } |
115 | 115 |
116 bool get isParameterStub { | 116 bool get isParameterStub { |
117 return kind == FletchFunctionKind.PARAMETER_STUB; | 117 return kind == DartinoFunctionKind.PARAMETER_STUB; |
118 } | 118 } |
119 | 119 |
120 bool get isConstructor => element != null && element.isConstructor; | 120 bool get isConstructor => element != null && element.isConstructor; |
121 | 121 |
122 String verboseToString(); | 122 String verboseToString(); |
123 } | 123 } |
124 | 124 |
125 // TODO(ajohnsen): Move to separate file. | 125 // TODO(ajohnsen): Move to separate file. |
126 class FletchFunction extends FletchFunctionBase { | 126 class DartinoFunction extends DartinoFunctionBase { |
127 final List<Bytecode> bytecodes; | 127 final List<Bytecode> bytecodes; |
128 final List<FletchConstant> constants; | 128 final List<DartinoConstant> constants; |
129 | 129 |
130 const FletchFunction( | 130 const DartinoFunction( |
131 int functionId, | 131 int functionId, |
132 FletchFunctionKind kind, | 132 DartinoFunctionKind kind, |
133 int arity, | 133 int arity, |
134 String name, | 134 String name, |
135 Element element, | 135 Element element, |
136 FunctionSignature signature, | 136 FunctionSignature signature, |
137 this.bytecodes, | 137 this.bytecodes, |
138 this.constants, | 138 this.constants, |
139 int memberOf) | 139 int memberOf) |
140 : super(functionId, kind, arity, name, element, signature, memberOf); | 140 : super(functionId, kind, arity, name, element, signature, memberOf); |
141 | 141 |
142 FletchFunction withReplacedConstants(List<FletchConstant> constants) { | 142 DartinoFunction withReplacedConstants(List<DartinoConstant> constants) { |
143 return new FletchFunction( | 143 return new DartinoFunction( |
144 functionId, | 144 functionId, |
145 kind, | 145 kind, |
146 arity, | 146 arity, |
147 name, | 147 name, |
148 element, | 148 element, |
149 signature, | 149 signature, |
150 bytecodes, | 150 bytecodes, |
151 constants, | 151 constants, |
152 memberOf); | 152 memberOf); |
153 } | 153 } |
154 | 154 |
155 /// Represents a function we have lost track off, for example, -1 in a | 155 /// Represents a function we have lost track off, for example, -1 in a |
156 /// backtrace from the Fletch VM. | 156 /// backtrace from the Dartino VM. |
157 const FletchFunction.missing() | 157 const DartinoFunction.missing() |
158 : this( | 158 : this( |
159 -1, FletchFunctionKind.NORMAL, 0, "<missing>", null, null, | 159 -1, DartinoFunctionKind.NORMAL, 0, "<missing>", null, null, |
160 const <Bytecode>[], const <FletchConstant>[], null); | 160 const <Bytecode>[], const <DartinoConstant>[], null); |
161 | 161 |
162 String toString() { | 162 String toString() { |
163 StringBuffer buffer = new StringBuffer(); | 163 StringBuffer buffer = new StringBuffer(); |
164 buffer.write("FletchFunction($functionId, '$name'"); | 164 buffer.write("DartinoFunction($functionId, '$name'"); |
165 if (isInstanceMember) { | 165 if (isInstanceMember) { |
166 buffer.write(", memberOf=$memberOf"); | 166 buffer.write(", memberOf=$memberOf"); |
167 } | 167 } |
168 buffer.write(")"); | 168 buffer.write(")"); |
169 return buffer.toString(); | 169 return buffer.toString(); |
170 } | 170 } |
171 | 171 |
172 String verboseToString() { | 172 String verboseToString() { |
173 StringBuffer sb = new StringBuffer(); | 173 StringBuffer sb = new StringBuffer(); |
174 | 174 |
175 sb.writeln("Function $functionId, Arity=$arity"); | 175 sb.writeln("Function $functionId, Arity=$arity"); |
176 sb.writeln("Constants:"); | 176 sb.writeln("Constants:"); |
177 for (int i = 0; i < constants.length; i++) { | 177 for (int i = 0; i < constants.length; i++) { |
178 FletchConstant constant = constants[i]; | 178 DartinoConstant constant = constants[i]; |
179 sb.writeln(" #$i: $constant"); | 179 sb.writeln(" #$i: $constant"); |
180 } | 180 } |
181 | 181 |
182 sb.writeln("Bytecodes:"); | 182 sb.writeln("Bytecodes:"); |
183 Bytecode.prettyPrint(sb, bytecodes); | 183 Bytecode.prettyPrint(sb, bytecodes); |
184 | 184 |
185 return '$sb'; | 185 return '$sb'; |
186 } | 186 } |
187 } | 187 } |
188 | 188 |
189 class ParameterStubSignature { | 189 class ParameterStubSignature { |
190 final int functionId; | 190 final int functionId; |
191 final CallStructure callStructure; | 191 final CallStructure callStructure; |
192 | 192 |
193 const ParameterStubSignature(this.functionId, this.callStructure); | 193 const ParameterStubSignature(this.functionId, this.callStructure); |
194 | 194 |
195 int get hashCode => functionId ^ callStructure.hashCode; | 195 int get hashCode => functionId ^ callStructure.hashCode; |
196 | 196 |
197 bool operator==(other) { | 197 bool operator==(other) { |
198 return other is ParameterStubSignature && | 198 return other is ParameterStubSignature && |
199 other.functionId == functionId && | 199 other.functionId == functionId && |
200 other.callStructure == callStructure; | 200 other.callStructure == callStructure; |
201 } | 201 } |
202 } | 202 } |
203 | 203 |
204 class FletchSystem { | 204 class DartinoSystem { |
205 // functionsByElement is a subset of functionsById: Some functions do not | 205 // functionsByElement is a subset of functionsById: Some functions do not |
206 // have an element reference. | 206 // have an element reference. |
207 final PersistentMap<int, FletchFunction> functionsById; | 207 final PersistentMap<int, DartinoFunction> functionsById; |
208 final PersistentMap<Element, FletchFunction> functionsByElement; | 208 final PersistentMap<Element, DartinoFunction> functionsByElement; |
209 | 209 |
210 final PersistentMap<ConstructorElement, FletchFunction> | 210 final PersistentMap<ConstructorElement, DartinoFunction> |
211 constructorInitializersByElement; | 211 constructorInitializersByElement; |
212 | 212 |
213 final PersistentMap<int, int> tearoffsById; | 213 final PersistentMap<int, int> tearoffsById; |
214 | 214 |
215 // classesByElement is a subset of classesById: Some classes do not | 215 // classesByElement is a subset of classesById: Some classes do not |
216 // have an element reference. | 216 // have an element reference. |
217 final PersistentMap<int, FletchClass> classesById; | 217 final PersistentMap<int, DartinoClass> classesById; |
218 final PersistentMap<ClassElement, FletchClass> classesByElement; | 218 final PersistentMap<ClassElement, DartinoClass> classesByElement; |
219 | 219 |
220 final PersistentMap<int, FletchConstant> constantsById; | 220 final PersistentMap<int, DartinoConstant> constantsById; |
221 final PersistentMap<ConstantValue, FletchConstant> constantsByValue; | 221 final PersistentMap<ConstantValue, DartinoConstant> constantsByValue; |
222 | 222 |
223 final PersistentMap<int, String> symbolByFletchSelectorId; | 223 final PersistentMap<int, String> symbolByDartinoSelectorId; |
224 | 224 |
225 final PersistentMap<int, int> gettersByFieldIndex; | 225 final PersistentMap<int, int> gettersByFieldIndex; |
226 | 226 |
227 final PersistentMap<int, int> settersByFieldIndex; | 227 final PersistentMap<int, int> settersByFieldIndex; |
228 | 228 |
229 final PersistentMap<ParameterStubSignature, FletchFunction> parameterStubs; | 229 final PersistentMap<ParameterStubSignature, DartinoFunction> parameterStubs; |
230 | 230 |
231 const FletchSystem( | 231 const DartinoSystem( |
232 this.functionsById, | 232 this.functionsById, |
233 this.functionsByElement, | 233 this.functionsByElement, |
234 this.constructorInitializersByElement, | 234 this.constructorInitializersByElement, |
235 this.tearoffsById, | 235 this.tearoffsById, |
236 this.classesById, | 236 this.classesById, |
237 this.classesByElement, | 237 this.classesByElement, |
238 this.constantsById, | 238 this.constantsById, |
239 this.constantsByValue, | 239 this.constantsByValue, |
240 this.symbolByFletchSelectorId, | 240 this.symbolByDartinoSelectorId, |
241 this.gettersByFieldIndex, | 241 this.gettersByFieldIndex, |
242 this.settersByFieldIndex, | 242 this.settersByFieldIndex, |
243 this.parameterStubs); | 243 this.parameterStubs); |
244 | 244 |
245 bool get isEmpty => functionsById.isEmpty; | 245 bool get isEmpty => functionsById.isEmpty; |
246 | 246 |
247 String lookupSymbolBySelector(int fletchSelector) { | 247 String lookupSymbolBySelector(int dartinoSelector) { |
248 return symbolByFletchSelectorId[FletchSelector.decodeId(fletchSelector)]; | 248 return symbolByDartinoSelectorId[DartinoSelector.decodeId(dartinoSelector)]; |
249 } | 249 } |
250 | 250 |
251 FletchFunction lookupFunctionById(int functionId) { | 251 DartinoFunction lookupFunctionById(int functionId) { |
252 return functionsById[functionId]; | 252 return functionsById[functionId]; |
253 } | 253 } |
254 | 254 |
255 FletchFunction lookupFunctionByElement(Element element) { | 255 DartinoFunction lookupFunctionByElement(Element element) { |
256 return functionsByElement[element]; | 256 return functionsByElement[element]; |
257 } | 257 } |
258 | 258 |
259 Iterable<FletchFunction> functionsWhere(bool f(FletchFunction function)) { | 259 Iterable<DartinoFunction> functionsWhere(bool f(DartinoFunction function)) { |
260 return functionsById.values.where(f); | 260 return functionsById.values.where(f); |
261 } | 261 } |
262 | 262 |
263 FletchConstant lookupConstantById(int constantId) { | 263 DartinoConstant lookupConstantById(int constantId) { |
264 return constantsById[constantId]; | 264 return constantsById[constantId]; |
265 } | 265 } |
266 | 266 |
267 FletchConstant lookupConstantByValue(ConstantValue value) { | 267 DartinoConstant lookupConstantByValue(ConstantValue value) { |
268 return constantsByValue[value]; | 268 return constantsByValue[value]; |
269 } | 269 } |
270 | 270 |
271 FletchFunction lookupConstructorInitializerByElement( | 271 DartinoFunction lookupConstructorInitializerByElement( |
272 ConstructorElement element) { | 272 ConstructorElement element) { |
273 return constructorInitializersByElement[element]; | 273 return constructorInitializersByElement[element]; |
274 } | 274 } |
275 | 275 |
276 /// Map from the ID of a [FletchFunction] to the ID of its corresponding | 276 /// Map from the ID of a [DartinoFunction] to the ID of its corresponding |
277 /// tear-off [FletchFunction]. | 277 /// tear-off [DartinoFunction]. |
278 /// | 278 /// |
279 /// To obtain the tear-off corresponding to an [Element], look up the | 279 /// To obtain the tear-off corresponding to an [Element], look up the |
280 /// function in [functionsByElement]. | 280 /// function in [functionsByElement]. |
281 int lookupTearOffById(int functionId) => tearoffsById[functionId]; | 281 int lookupTearOffById(int functionId) => tearoffsById[functionId]; |
282 | 282 |
283 /// Instance field getters can be reused between classes. This method returns | 283 /// Instance field getters can be reused between classes. This method returns |
284 /// a getter that gets the field at [fieldIndex]. Returns `null` if no such | 284 /// a getter that gets the field at [fieldIndex]. Returns `null` if no such |
285 /// getter exists. | 285 /// getter exists. |
286 int lookupGetterByFieldIndex(int fieldIndex) { | 286 int lookupGetterByFieldIndex(int fieldIndex) { |
287 return gettersByFieldIndex[fieldIndex]; | 287 return gettersByFieldIndex[fieldIndex]; |
288 } | 288 } |
289 | 289 |
290 /// Instance field setters can be reused between classes. This method returns | 290 /// Instance field setters can be reused between classes. This method returns |
291 /// a setter that sets the field at [fieldIndex]. Returns `null` if no such | 291 /// a setter that sets the field at [fieldIndex]. Returns `null` if no such |
292 /// setter exists. | 292 /// setter exists. |
293 int lookupSetterByFieldIndex(int fieldIndex) { | 293 int lookupSetterByFieldIndex(int fieldIndex) { |
294 return settersByFieldIndex[fieldIndex]; | 294 return settersByFieldIndex[fieldIndex]; |
295 } | 295 } |
296 | 296 |
297 FletchClass lookupClassById(int classId) { | 297 DartinoClass lookupClassById(int classId) { |
298 return classesById[classId]; | 298 return classesById[classId]; |
299 } | 299 } |
300 | 300 |
301 FletchClass lookupClassByElement(ClassElement element) { | 301 DartinoClass lookupClassByElement(ClassElement element) { |
302 return classesByElement[element]; | 302 return classesByElement[element]; |
303 } | 303 } |
304 | 304 |
305 FletchFunction lookupParameterStub(ParameterStubSignature signature) { | 305 DartinoFunction lookupParameterStub(ParameterStubSignature signature) { |
306 return parameterStubs[signature]; | 306 return parameterStubs[signature]; |
307 } | 307 } |
308 | 308 |
309 int computeMaxFunctionId() { | 309 int computeMaxFunctionId() { |
310 return functionsById.keys.fold(-1, (x, y) => x > y ? x : y); | 310 return functionsById.keys.fold(-1, (x, y) => x > y ? x : y); |
311 } | 311 } |
312 | 312 |
313 int computeMaxClassId() { | 313 int computeMaxClassId() { |
314 return classesById.keys.fold(-1, (x, y) => x > y ? x : y); | 314 return classesById.keys.fold(-1, (x, y) => x > y ? x : y); |
315 } | 315 } |
316 | 316 |
317 String toDebugString(Uri base) { | 317 String toDebugString(Uri base) { |
318 return new FletchSystemPrinter(this, base).generateDebugString(); | 318 return new DartinoSystemPrinter(this, base).generateDebugString(); |
319 } | 319 } |
320 } | 320 } |
321 | 321 |
322 class FletchDelta { | 322 class DartinoDelta { |
323 final FletchSystem system; | 323 final DartinoSystem system; |
324 final FletchSystem predecessorSystem; | 324 final DartinoSystem predecessorSystem; |
325 final List<VmCommand> commands; | 325 final List<VmCommand> commands; |
326 | 326 |
327 const FletchDelta(this.system, this.predecessorSystem, this.commands); | 327 const DartinoDelta(this.system, this.predecessorSystem, this.commands); |
328 } | 328 } |
OLD | NEW |