OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE.md file. | |
4 | |
5 library fletchc.fletch_context; | |
6 | |
7 import 'package:compiler/src/tree/tree.dart' show | |
8 Node; | |
9 | |
10 import 'package:compiler/src/elements/elements.dart' show | |
11 ClassElement, | |
12 Element, | |
13 FieldElement, | |
14 FunctionElement, | |
15 FunctionSignature, | |
16 LibraryElement, | |
17 ParameterElement, | |
18 Name; | |
19 | |
20 import 'package:compiler/src/resolution/tree_elements.dart' show | |
21 TreeElements; | |
22 | |
23 import 'package:compiler/src/universe/selector.dart' show | |
24 Selector; | |
25 | |
26 import 'package:compiler/src/constants/expressions.dart' show | |
27 ConstantExpression; | |
28 | |
29 import 'package:compiler/src/constants/values.dart' show | |
30 ConstantValue, | |
31 ConstructedConstantValue, | |
32 FunctionConstantValue; | |
33 | |
34 import 'fletch_compiler_implementation.dart' show | |
35 FletchCompilerImplementation; | |
36 | |
37 export 'fletch_compiler_implementation.dart' show | |
38 FletchCompilerImplementation; | |
39 | |
40 import 'fletch_backend.dart' show | |
41 FletchBackend; | |
42 | |
43 export 'fletch_backend.dart' show | |
44 FletchBackend; | |
45 | |
46 export 'bytecode_assembler.dart' show | |
47 BytecodeAssembler, | |
48 BytecodeLabel; | |
49 | |
50 import 'fletch_native_descriptor.dart' show | |
51 FletchNativeDescriptor; | |
52 | |
53 import 'fletch_selector.dart' show | |
54 FletchSelector, | |
55 SelectorKind; | |
56 | |
57 export 'fletch_native_descriptor.dart' show | |
58 FletchNativeDescriptor; | |
59 | |
60 import 'fletch_registry.dart' show | |
61 FletchRegistry; | |
62 | |
63 class FletchContext { | |
64 final FletchCompilerImplementation compiler; | |
65 | |
66 Map<String, FletchNativeDescriptor> nativeDescriptors; | |
67 | |
68 Set<String> names = new Set<String>(); | |
69 | |
70 Map<FieldElement, int> staticIndices = <FieldElement, int>{}; | |
71 | |
72 Map<LibraryElement, String> libraryTag = <LibraryElement, String>{}; | |
73 List<String> symbols = <String>[]; | |
74 Map<String, int> symbolIds = <String, int>{}; | |
75 Map<Name, String> nameToSymbol = <Name, String>{}; | |
76 Map<Selector, String> selectorToSymbol = <Selector, String>{}; | |
77 | |
78 FletchContext(this.compiler); | |
79 | |
80 FletchBackend get backend => compiler.backend; | |
81 | |
82 bool get enableBigint { | |
83 String enableBigintConstant = compiler.environment['fletch.enable-bigint']; | |
84 return enableBigintConstant != "false"; | |
85 } | |
86 | |
87 void setNames(Map<String, String> names) { | |
88 // Generate symbols of the values. | |
89 for (String name in names.values) { | |
90 this.names.add(name); | |
91 getSymbolId(name); | |
92 } | |
93 } | |
94 | |
95 String mangleName(Name name) { | |
96 if (!name.isPrivate) return name.text; | |
97 if (name.library.isPlatformLibrary && names.contains(name.text)) { | |
98 return name.text; | |
99 } | |
100 return name.text + getLibraryTag(name.library); | |
101 } | |
102 | |
103 String getLibraryTag(LibraryElement library) { | |
104 return libraryTag.putIfAbsent(library, () { | |
105 // Give the core library the unique mangling of the empty string. That | |
106 // will make the VM able to create selector into core (used for e.g. | |
107 // _noSuchMethodTrampoline). | |
108 if (library == compiler.coreLibrary) return ""; | |
109 return "%${libraryTag.length}"; | |
110 }); | |
111 } | |
112 | |
113 int getStaticFieldIndex(FieldElement element, Element referrer) { | |
114 return staticIndices.putIfAbsent(element, () => staticIndices.length); | |
115 } | |
116 | |
117 String getSymbolFromSelector(Selector selector) { | |
118 return selectorToSymbol.putIfAbsent(selector, () { | |
119 StringBuffer buffer = new StringBuffer(); | |
120 buffer.write(mangleName(selector.memberName)); | |
121 for (String namedArgument in selector.namedArguments) { | |
122 buffer.write(":"); | |
123 buffer.write(namedArgument); | |
124 } | |
125 return buffer.toString(); | |
126 }); | |
127 } | |
128 | |
129 void writeNamedArguments(StringBuffer buffer, FunctionSignature signature) { | |
130 signature.orderedForEachParameter((ParameterElement parameter) { | |
131 if (parameter.isNamed) { | |
132 buffer.write(":"); | |
133 buffer.write(parameter.name); | |
134 } | |
135 }); | |
136 } | |
137 | |
138 String getSymbolForFunction( | |
139 String name, | |
140 FunctionSignature signature, | |
141 LibraryElement library) { | |
142 StringBuffer buffer = new StringBuffer(); | |
143 buffer.write(mangleName(new Name(name, library))); | |
144 writeNamedArguments(buffer, signature); | |
145 return buffer.toString(); | |
146 } | |
147 | |
148 String getCallSymbol(FunctionSignature signature) { | |
149 return getSymbolForFunction('call', signature, null); | |
150 } | |
151 | |
152 int getSymbolId(String symbol) { | |
153 return symbolIds.putIfAbsent(symbol, () { | |
154 int id = symbols.length; | |
155 assert(id == symbolIds.length); | |
156 symbols.add(symbol); | |
157 backend.systemBuilder.registerSymbol(symbol, id); | |
158 return id; | |
159 }); | |
160 } | |
161 | |
162 void forEachStatic(f(FieldElement element, int index)) { | |
163 staticIndices.forEach(f); | |
164 } | |
165 | |
166 int toFletchSelector(Selector selector) { | |
167 String symbol = getSymbolFromSelector(selector); | |
168 int id = getSymbolId(symbol); | |
169 SelectorKind kind = getFletchSelectorKind(selector); | |
170 return FletchSelector.encode(id, kind, selector.argumentCount); | |
171 } | |
172 | |
173 int toFletchIsSelector(ClassElement classElement, [int arity]) { | |
174 LibraryElement library = classElement.library; | |
175 StringBuffer buffer = new StringBuffer(); | |
176 buffer.write("?is?"); | |
177 buffer.write(classElement.name); | |
178 buffer.write("?"); | |
179 buffer.write(getLibraryTag(library)); | |
180 int id = getSymbolId(buffer.toString()); | |
181 if (arity == null) return FletchSelector.encodeGetter(id); | |
182 return FletchSelector.encodeMethod(id, arity); | |
183 } | |
184 | |
185 int toFletchTearoffIsSelector( | |
186 String functionName, | |
187 ClassElement classElement) { | |
188 LibraryElement library = classElement.library; | |
189 StringBuffer buffer = new StringBuffer(); | |
190 buffer.write("?is?"); | |
191 buffer.write(functionName); | |
192 buffer.write("?"); | |
193 buffer.write(classElement.name); | |
194 buffer.write("?"); | |
195 buffer.write(getLibraryTag(library)); | |
196 int id = getSymbolId(buffer.toString()); | |
197 return FletchSelector.encodeMethod(id, 0); | |
198 } | |
199 | |
200 SelectorKind getFletchSelectorKind(Selector selector) { | |
201 if (selector.isGetter) return SelectorKind.Getter; | |
202 if (selector.isSetter) return SelectorKind.Setter; | |
203 return SelectorKind.Method; | |
204 } | |
205 | |
206 void registerConstructedConstantValue(ConstructedConstantValue value) { | |
207 ClassElement classElement = value.type.element; | |
208 backend.registerClassElement(classElement); | |
209 // TODO(ahe): This should not be required. Also, instantiate type, | |
210 // not class. | |
211 FletchRegistry registry = new FletchRegistry(compiler); | |
212 registry.registerInstantiatedClass(classElement); | |
213 } | |
214 | |
215 void registerFunctionConstantValue(FunctionConstantValue value) { | |
216 backend.markFunctionConstantAsUsed(value); | |
217 } | |
218 | |
219 // TODO(zarah): Remove this and use the FletchSystemBuilder | |
220 void markConstantUsed(ConstantValue constant) { | |
221 backend.systemBuilder.registerConstant(constant, this); | |
222 } | |
223 | |
224 // TODO(zarah): Remove this and use the FletchSystemBuilder | |
225 int lookupConstantIdByValue(ConstantValue value) => | |
226 backend.systemBuilder.lookupConstantIdByValue(value); | |
227 | |
228 /// If [isConst] is true, a compile-time error is reported. | |
229 ConstantExpression compileConstant( | |
230 Node node, | |
231 TreeElements elements, | |
232 {bool isConst}) { | |
233 ConstantExpression expression = | |
234 inspectConstant(node, elements, isConst: isConst); | |
235 if (expression == null) return null; | |
236 ConstantValue value = getConstantValue(expression); | |
237 markConstantUsed(value); | |
238 return expression; | |
239 } | |
240 | |
241 ConstantExpression inspectConstant( | |
242 Node node, | |
243 TreeElements elements, | |
244 {bool isConst}) { | |
245 assert(isConst != null); | |
246 // TODO(johnniwinther): Should be handled in resolution. | |
247 ConstantExpression expression = | |
248 compiler.resolver.constantCompiler.compileNode( | |
249 node, elements, enforceConst: isConst); | |
250 return expression; | |
251 } | |
252 | |
253 ConstantValue getConstantValue(ConstantExpression expression) { | |
254 return compiler.constants.getConstantValue(expression); | |
255 } | |
256 } | |
OLD | NEW |