| 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 |