Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import '../closure.dart'; | |
| 6 import '../common.dart'; | |
| 7 import '../common/codegen.dart' show CodegenRegistry; | |
| 5 import '../compiler.dart'; | 8 import '../compiler.dart'; |
| 9 import '../dart_types.dart'; | |
| 6 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| 7 import '../io/source_information.dart'; | 11 import '../io/source_information.dart'; |
| 8 import '../js_backend/js_backend.dart'; | 12 import '../js_backend/js_backend.dart'; |
| 9 import '../resolution/tree_elements.dart'; | 13 import '../resolution/tree_elements.dart'; |
| 10 import '../tree/tree.dart' as ast; | 14 import '../tree/tree.dart' as ast; |
| 11 import '../types/types.dart'; | 15 import '../types/types.dart'; |
| 16 import '../universe/call_structure.dart' show CallStructure; | |
| 17 import '../universe/use.dart' show TypeUse; | |
| 18 import '../world.dart' show ClosedWorld; | |
| 12 import 'jump_handler.dart'; | 19 import 'jump_handler.dart'; |
| 13 import 'locals_handler.dart'; | 20 import 'locals_handler.dart'; |
| 14 import 'nodes.dart'; | 21 import 'nodes.dart'; |
| 15 import 'ssa_branch_builder.dart'; | 22 import 'ssa_branch_builder.dart'; |
| 23 import 'type_verifier.dart'; | |
| 16 | 24 |
| 17 /// Base class for objects that build up an SSA graph. | 25 /// Base class for objects that build up an SSA graph. |
| 18 /// | 26 /// |
| 19 /// This contains helpers for building the graph and tracking information about | 27 /// This contains helpers for building the graph and tracking information about |
| 20 /// the current state of the graph being built. | 28 /// the current state of the graph being built. |
| 21 abstract class GraphBuilder { | 29 abstract class GraphBuilder { |
| 22 /// Holds the resulting SSA graph. | 30 /// Holds the resulting SSA graph. |
| 23 final HGraph graph = new HGraph(); | 31 final HGraph graph = new HGraph(); |
| 24 | 32 |
| 25 // TODO(het): remove this | 33 // TODO(het): remove this |
| 26 /// A reference to the compiler. | 34 /// A reference to the compiler. |
| 27 Compiler compiler; | 35 Compiler compiler; |
| 28 | 36 |
| 29 /// The JavaScript backend we are targeting in this compilation. | 37 /// The JavaScript backend we are targeting in this compilation. |
| 30 JavaScriptBackend get backend; | 38 JavaScriptBackend get backend; |
| 31 | 39 |
| 32 /// The tree elements for the element being built into an SSA graph. | 40 /// The tree elements for the element being built into an SSA graph. |
| 33 TreeElements get elements; | 41 TreeElements get elements; |
| 34 | 42 |
| 43 CodegenRegistry get registry; | |
| 44 | |
| 35 /// Used to track the locals while building the graph. | 45 /// Used to track the locals while building the graph. |
| 36 LocalsHandler localsHandler; | 46 LocalsHandler localsHandler; |
| 37 | 47 |
| 38 /// A stack of instructions. | 48 /// A stack of instructions. |
| 39 /// | 49 /// |
| 40 /// We build the SSA graph by simulating a stack machine. | 50 /// We build the SSA graph by simulating a stack machine. |
| 41 List<HInstruction> stack = <HInstruction>[]; | 51 List<HInstruction> stack = <HInstruction>[]; |
| 42 | 52 |
| 43 /// The count of nested loops we are currently building. | 53 /// The count of nested loops we are currently building. |
| 44 /// | 54 /// |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 | 185 |
| 176 HSubGraphBlockInformation wrapStatementGraph(SubGraph statements) { | 186 HSubGraphBlockInformation wrapStatementGraph(SubGraph statements) { |
| 177 if (statements == null) return null; | 187 if (statements == null) return null; |
| 178 return new HSubGraphBlockInformation(statements); | 188 return new HSubGraphBlockInformation(statements); |
| 179 } | 189 } |
| 180 | 190 |
| 181 HSubExpressionBlockInformation wrapExpressionGraph(SubExpression expression) { | 191 HSubExpressionBlockInformation wrapExpressionGraph(SubExpression expression) { |
| 182 if (expression == null) return null; | 192 if (expression == null) return null; |
| 183 return new HSubExpressionBlockInformation(expression); | 193 return new HSubExpressionBlockInformation(expression); |
| 184 } | 194 } |
| 195 | |
| 196 HInstruction buildFunctionType(FunctionType type) { | |
| 197 type.accept(new TypeBuilder(compiler.closedWorld), this); | |
| 198 return pop(); | |
| 199 } | |
| 200 | |
| 201 HInstruction buildFunctionTypeConversion(HInstruction original, | |
| 202 DartType type, int kind); | |
| 203 | |
| 204 /// Returns the current source element. | |
| 205 /// | |
| 206 /// The returned element is a declaration element. | |
| 207 Element get sourceElement; | |
| 208 | |
| 209 // TODO(karlklose): this is needed to avoid a bug where the resolved type is | |
| 210 // not stored on a type annotation in the closure translator. Remove when | |
| 211 // fixed. | |
| 212 bool hasDirectLocal(Local local) { | |
| 213 return !localsHandler.isAccessedDirectly(local) || | |
| 214 localsHandler.directLocals[local] != null; | |
| 215 } | |
| 216 | |
| 217 /// The element for which this SSA builder is being used. | |
| 218 Element get targetElement; | |
| 219 TypeVerifier get typeVerifier; | |
| 185 } | 220 } |
| 221 | |
| 222 class TypeBuilder implements DartTypeVisitor<dynamic, GraphBuilder> { | |
|
sra1
2016/11/12 00:31:19
There is a lot of duplication here. Is it necessar
Emily Fortuna
2016/11/14 17:47:56
sorry I hadn't cut the code from builder.dart. the
| |
| 223 final ClosedWorld closedWorld; | |
| 224 | |
| 225 TypeBuilder(this.closedWorld); | |
| 226 | |
| 227 void visit(DartType type, GraphBuilder builder) => type.accept(this, builder); | |
| 228 | |
| 229 void visitVoidType(VoidType type, GraphBuilder builder) { | |
| 230 ClassElement cls = builder.backend.helpers.VoidRuntimeType; | |
| 231 builder.push(new HVoidType(type, new TypeMask.exact(cls, closedWorld))); | |
| 232 } | |
| 233 | |
| 234 void visitTypeVariableType(TypeVariableType type, GraphBuilder builder) { | |
| 235 ClassElement cls = builder.backend.helpers.RuntimeType; | |
| 236 TypeMask instructionType = new TypeMask.subclass(cls, closedWorld); | |
| 237 if (!builder.sourceElement.enclosingElement.isClosure && | |
| 238 builder.sourceElement.isInstanceMember) { | |
| 239 HInstruction receiver = builder.localsHandler.readThis(); | |
| 240 builder.push(new HReadTypeVariable(type, receiver, instructionType)); | |
| 241 } else { | |
| 242 builder.push(new HReadTypeVariable.noReceiver( | |
| 243 type, builder.typeVerifier.addTypeVariableReference( | |
| 244 type, builder.sourceElement), | |
| 245 instructionType)); | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 void visitFunctionType(FunctionType type, GraphBuilder builder) { | |
| 250 type.returnType.accept(this, builder); | |
| 251 HInstruction returnType = builder.pop(); | |
| 252 List<HInstruction> inputs = <HInstruction>[returnType]; | |
| 253 | |
| 254 for (DartType parameter in type.parameterTypes) { | |
| 255 parameter.accept(this, builder); | |
| 256 inputs.add(builder.pop()); | |
| 257 } | |
| 258 | |
| 259 for (DartType parameter in type.optionalParameterTypes) { | |
| 260 parameter.accept(this, builder); | |
| 261 inputs.add(builder.pop()); | |
| 262 } | |
| 263 | |
| 264 List<DartType> namedParameterTypes = type.namedParameterTypes; | |
| 265 List<String> names = type.namedParameters; | |
| 266 for (int index = 0; index < names.length; index++) { | |
| 267 ast.DartString dartString = new ast.DartString.literal(names[index]); | |
| 268 inputs.add(builder.graph.addConstantString(dartString, builder.compiler)); | |
| 269 namedParameterTypes[index].accept(this, builder); | |
| 270 inputs.add(builder.pop()); | |
| 271 } | |
| 272 | |
| 273 ClassElement cls = builder.backend.helpers.RuntimeFunctionType; | |
| 274 builder.push( | |
| 275 new HFunctionType(inputs, type, new TypeMask.exact(cls, closedWorld))); | |
| 276 } | |
| 277 | |
| 278 void visitMalformedType(MalformedType type, GraphBuilder builder) { | |
| 279 visitDynamicType(const DynamicType(), builder); | |
| 280 } | |
| 281 | |
| 282 void visitStatementType(StatementType type, GraphBuilder builder) { | |
| 283 throw 'not implemented visitStatementType($type)'; | |
| 284 } | |
| 285 | |
| 286 void visitInterfaceType(InterfaceType type, GraphBuilder builder) { | |
| 287 List<HInstruction> inputs = <HInstruction>[]; | |
| 288 for (DartType typeArgument in type.typeArguments) { | |
| 289 typeArgument.accept(this, builder); | |
| 290 inputs.add(builder.pop()); | |
| 291 } | |
| 292 ClassElement cls; | |
| 293 if (type.typeArguments.isEmpty) { | |
| 294 cls = builder.backend.helpers.RuntimeTypePlain; | |
| 295 } else { | |
| 296 cls = builder.backend.helpers.RuntimeTypeGeneric; | |
| 297 } | |
| 298 builder.push( | |
| 299 new HInterfaceType(inputs, type, new TypeMask.exact(cls, closedWorld))); | |
| 300 } | |
| 301 | |
| 302 void visitTypedefType(TypedefType type, GraphBuilder builder) { | |
| 303 DartType unaliased = type.unaliased; | |
| 304 if (unaliased is TypedefType) throw 'unable to unalias $type'; | |
| 305 unaliased.accept(this, builder); | |
| 306 } | |
| 307 | |
| 308 void visitDynamicType(DynamicType type, GraphBuilder builder) { | |
| 309 JavaScriptBackend backend = builder.compiler.backend; | |
| 310 ClassElement cls = backend.helpers.DynamicRuntimeType; | |
| 311 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); | |
| 312 } | |
| 313 } | |
| OLD | NEW |