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 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
6 | 6 |
7 import '../closure.dart'; | 7 import '../closure.dart'; |
8 import '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/codegen.dart' show CodegenRegistry; | 9 import '../common/codegen.dart' show CodegenRegistry; |
10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
11 import '../common_elements.dart'; | 11 import '../common_elements.dart'; |
12 import '../compiler.dart'; | 12 import '../compiler.dart'; |
13 import '../constants/values.dart' | 13 import '../constants/values.dart' |
14 show | 14 show |
15 ConstantValue, | 15 ConstantValue, |
16 InterceptorConstantValue, | 16 InterceptorConstantValue, |
17 StringConstantValue, | 17 StringConstantValue, |
18 TypeConstantValue; | 18 TypeConstantValue; |
19 import '../elements/elements.dart'; | 19 import '../elements/elements.dart' show ErroneousElement; |
20 import '../elements/entities.dart'; | 20 import '../elements/entities.dart'; |
21 import '../elements/jumps.dart'; | 21 import '../elements/jumps.dart'; |
22 import '../elements/resolution_types.dart'; | 22 import '../elements/resolution_types.dart' |
| 23 show MalformedType, MethodTypeVariableType; |
23 import '../elements/types.dart'; | 24 import '../elements/types.dart'; |
24 import '../io/source_information.dart'; | 25 import '../io/source_information.dart'; |
25 import '../js/js.dart' as js; | 26 import '../js/js.dart' as js; |
26 import '../js_backend/backend.dart' show JavaScriptBackend; | 27 import '../js_backend/backend.dart' show JavaScriptBackend; |
27 import '../kernel/element_map.dart'; | 28 import '../kernel/element_map.dart'; |
28 import '../native/native.dart' as native; | 29 import '../native/native.dart' as native; |
29 import '../resolution/tree_elements.dart'; | 30 import '../resolution/tree_elements.dart'; |
30 import '../tree/nodes.dart' show Node; | 31 import '../tree/nodes.dart' show Node; |
31 import '../types/masks.dart'; | 32 import '../types/masks.dart'; |
32 import '../universe/selector.dart'; | 33 import '../universe/selector.dart'; |
33 import '../universe/side_effects.dart' show SideEffects; | 34 import '../universe/side_effects.dart' show SideEffects; |
34 import '../universe/use.dart' show DynamicUse; | 35 import '../universe/use.dart' show DynamicUse; |
35 import '../universe/world_builder.dart' show CodegenWorldBuilder; | 36 import '../universe/world_builder.dart' show CodegenWorldBuilder; |
36 import '../world.dart'; | 37 import '../world.dart'; |
37 import 'graph_builder.dart'; | 38 import 'graph_builder.dart'; |
38 import 'jump_handler.dart'; | 39 import 'jump_handler.dart'; |
39 import 'kernel_ast_adapter.dart'; | 40 import 'kernel_ast_adapter.dart'; |
40 import 'kernel_string_builder.dart'; | 41 import 'kernel_string_builder.dart'; |
41 import 'locals_handler.dart'; | 42 import 'locals_handler.dart'; |
42 import 'loop_handler.dart'; | 43 import 'loop_handler.dart'; |
43 import 'nodes.dart'; | 44 import 'nodes.dart'; |
44 import 'ssa.dart'; | 45 import 'ssa.dart'; |
45 import 'ssa_branch_builder.dart'; | 46 import 'ssa_branch_builder.dart'; |
46 import 'switch_continue_analysis.dart'; | 47 import 'switch_continue_analysis.dart'; |
47 import 'type_builder.dart'; | 48 import 'type_builder.dart'; |
48 | 49 |
49 class KernelSsaGraphBuilder extends ir.Visitor | 50 class KernelSsaGraphBuilder extends ir.Visitor |
50 with GraphBuilder, SsaBuilderFieldMixin { | 51 with GraphBuilder, SsaBuilderFieldMixin { |
51 final ir.Node target; | 52 final ir.Node target; |
52 final bool _targetIsConstructorBody; | |
53 final MemberEntity targetElement; | 53 final MemberEntity targetElement; |
54 | 54 |
55 /// The root node of [targetElement]. This is used as the key into the | 55 /// The root node of [targetElement]. This is used as the key into the |
56 /// [startFunction] of the locals handler. | 56 /// [startFunction] of the locals handler. |
57 // TODO(johnniwinther,efortuna): Avoid the need for AST nodes in the locals | 57 // TODO(johnniwinther,efortuna): Avoid the need for AST nodes in the locals |
58 // handler. | 58 // handler. |
59 final Node functionNode; | 59 final Node functionNode; |
60 final ClosedWorld closedWorld; | 60 final ClosedWorld closedWorld; |
61 final CodegenWorldBuilder _worldBuilder; | 61 final CodegenWorldBuilder _worldBuilder; |
62 final CodegenRegistry registry; | 62 final CodegenRegistry registry; |
(...skipping 14 matching lines...) Expand all Loading... |
77 final List<InterfaceType> currentImplicitInstantiations = <InterfaceType>[]; | 77 final List<InterfaceType> currentImplicitInstantiations = <InterfaceType>[]; |
78 | 78 |
79 HInstruction rethrowableException; | 79 HInstruction rethrowableException; |
80 | 80 |
81 final Compiler compiler; | 81 final Compiler compiler; |
82 | 82 |
83 @override | 83 @override |
84 JavaScriptBackend get backend => compiler.backend; | 84 JavaScriptBackend get backend => compiler.backend; |
85 | 85 |
86 @override | 86 @override |
87 TreeElements get elements => astAdapter.elements; | 87 TreeElements get elements => |
| 88 throw new UnsupportedError('KernelSsaGraphBuilder.elements'); |
88 | 89 |
89 SourceInformationBuilder sourceInformationBuilder; | 90 SourceInformationBuilder sourceInformationBuilder; |
90 final KernelToElementMapForBuilding _elementMap; | 91 final KernelToElementMapForBuilding _elementMap; |
91 final KernelToTypeInferenceMap _typeInferenceMap; | 92 final KernelToTypeInferenceMap _typeInferenceMap; |
92 final KernelToLocalsMap localsMap; | 93 final KernelToLocalsMap localsMap; |
93 LoopHandler<ir.Node> loopHandler; | 94 LoopHandler<ir.Node> loopHandler; |
94 TypeBuilder typeBuilder; | 95 TypeBuilder typeBuilder; |
95 | 96 |
96 final Map<ir.VariableDeclaration, HInstruction> letBindings = | 97 final Map<ir.VariableDeclaration, HInstruction> letBindings = |
97 <ir.VariableDeclaration, HInstruction>{}; | 98 <ir.VariableDeclaration, HInstruction>{}; |
98 | 99 |
99 /// True if we are visiting the expression of a throw statement; we assume | 100 /// True if we are visiting the expression of a throw statement; we assume |
100 /// this is a slow path. | 101 /// this is a slow path. |
101 bool _inExpressionOfThrow = false; | 102 bool _inExpressionOfThrow = false; |
102 | 103 |
103 KernelSsaGraphBuilder( | 104 KernelSsaGraphBuilder( |
104 this.targetElement, | 105 this.targetElement, |
105 ClassEntity contextClass, | 106 ClassEntity contextClass, |
106 this.target, | 107 this.target, |
107 this.compiler, | 108 this.compiler, |
108 this._elementMap, | 109 this._elementMap, |
109 this._typeInferenceMap, | 110 this._typeInferenceMap, |
110 this.localsMap, | 111 this.localsMap, |
111 this.closedWorld, | 112 this.closedWorld, |
112 this._worldBuilder, | 113 this._worldBuilder, |
113 this.registry, | 114 this.registry, |
114 this.closureDataLookup, | 115 this.closureDataLookup, |
115 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? | 116 // TODO(het): Should sourceInformationBuilder be in GraphBuilder? |
116 this.sourceInformationBuilder, | 117 this.sourceInformationBuilder, |
117 this.functionNode, | 118 this.functionNode) { |
118 {bool targetIsConstructorBody: false}) | |
119 : this._targetIsConstructorBody = targetIsConstructorBody { | |
120 this.loopHandler = new KernelLoopHandler(this); | 119 this.loopHandler = new KernelLoopHandler(this); |
121 typeBuilder = new TypeBuilder(this); | 120 typeBuilder = new TypeBuilder(this); |
122 graph.element = targetElement; | 121 graph.element = targetElement; |
123 graph.sourceInformation = | 122 graph.sourceInformation = |
124 sourceInformationBuilder.buildVariableDeclaration(); | 123 sourceInformationBuilder.buildVariableDeclaration(); |
125 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, | 124 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, |
126 contextClass, null, nativeData, interceptorData); | 125 contextClass, null, nativeData, interceptorData); |
127 _targetStack.add(targetElement); | 126 _targetStack.add(targetElement); |
128 } | 127 } |
129 | 128 |
130 @deprecated // Use [_elementMap] instead. | |
131 KernelAstAdapter get astAdapter => _elementMap; | |
132 | |
133 CommonElements get _commonElements => _elementMap.commonElements; | 129 CommonElements get _commonElements => _elementMap.commonElements; |
134 | 130 |
135 HGraph build() { | 131 HGraph build() { |
136 return reporter.withCurrentElement(localsMap.currentMember, () { | 132 return reporter.withCurrentElement(localsMap.currentMember, () { |
137 // TODO(het): no reason to do this here... | 133 // TODO(het): no reason to do this here... |
138 HInstruction.idCounter = 0; | 134 HInstruction.idCounter = 0; |
139 if (target is ir.Procedure) { | 135 if (target is ir.Procedure) { |
140 _targetFunction = (target as ir.Procedure).function; | 136 _targetFunction = (target as ir.Procedure).function; |
141 buildFunctionNode(_targetFunction); | 137 buildFunctionNode(_targetFunction); |
142 } else if (target is ir.Field) { | 138 } else if (target is ir.Field) { |
143 if (handleConstantField(targetElement, registry, closedWorld)) { | 139 if (handleConstantField(targetElement, registry, closedWorld)) { |
144 // No code is generated for `targetElement`: All references inline the | 140 // No code is generated for `targetElement`: All references inline the |
145 // constant value. | 141 // constant value. |
146 return null; | 142 return null; |
147 } else if (targetElement.isStatic || targetElement.isTopLevel) { | 143 } else if (targetElement.isStatic || targetElement.isTopLevel) { |
148 backend.constants.registerLazyStatic(targetElement); | 144 backend.constants.registerLazyStatic(targetElement); |
149 } | 145 } |
150 buildField(target); | 146 buildField(target); |
151 } else if (target is ir.Constructor) { | 147 } else if (target is ir.Constructor) { |
152 if (_targetIsConstructorBody) { | 148 if (targetElement is ConstructorBodyEntity) { |
153 buildConstructorBody(target); | 149 buildConstructorBody(target); |
154 } else { | 150 } else { |
155 buildConstructor(target); | 151 buildConstructor(target); |
156 } | 152 } |
157 } else if (target is ir.FunctionExpression) { | 153 } else if (target is ir.FunctionExpression) { |
158 _targetFunction = (target as ir.FunctionExpression).function; | 154 _targetFunction = (target as ir.FunctionExpression).function; |
159 buildFunctionNode(_targetFunction); | 155 buildFunctionNode(_targetFunction); |
160 } else if (target is ir.FunctionDeclaration) { | 156 } else if (target is ir.FunctionDeclaration) { |
161 _targetFunction = (target as ir.FunctionDeclaration).function; | 157 _targetFunction = (target as ir.FunctionDeclaration).function; |
162 buildFunctionNode(_targetFunction); | 158 buildFunctionNode(_targetFunction); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 return _elementMap.getDartType(type); | 192 return _elementMap.getDartType(type); |
197 } | 193 } |
198 | 194 |
199 /// Pops the most recent instruction from the stack and 'boolifies' it. | 195 /// Pops the most recent instruction from the stack and 'boolifies' it. |
200 /// | 196 /// |
201 /// Boolification is checking if the value is '=== true'. | 197 /// Boolification is checking if the value is '=== true'. |
202 @override | 198 @override |
203 HInstruction popBoolified() { | 199 HInstruction popBoolified() { |
204 HInstruction value = pop(); | 200 HInstruction value = pop(); |
205 if (typeBuilder.checkOrTrustTypes) { | 201 if (typeBuilder.checkOrTrustTypes) { |
206 ResolutionInterfaceType type = commonElements.boolType; | 202 InterfaceType type = commonElements.boolType; |
207 return typeBuilder.potentiallyCheckOrTrustType(value, type, | 203 return typeBuilder.potentiallyCheckOrTrustType(value, type, |
208 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 204 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
209 } | 205 } |
210 HInstruction result = new HBoolify(value, commonMasks.boolType); | 206 HInstruction result = new HBoolify(value, commonMasks.boolType); |
211 add(result); | 207 add(result); |
212 return result; | 208 return result; |
213 } | 209 } |
214 | 210 |
215 /// Extend current method parameters with parameters for the class type | 211 /// Extend current method parameters with parameters for the class type |
216 /// parameters. If the class has type parameters but does not need them, bind | 212 /// parameters. If the class has type parameters but does not need them, bind |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 319 |
324 for (ir.Constructor body in constructorChain.reversed) { | 320 for (ir.Constructor body in constructorChain.reversed) { |
325 if (_isEmptyStatement(body.function.body)) continue; | 321 if (_isEmptyStatement(body.function.body)) continue; |
326 | 322 |
327 List<HInstruction> bodyCallInputs = <HInstruction>[]; | 323 List<HInstruction> bodyCallInputs = <HInstruction>[]; |
328 bodyCallInputs.add(newObject); | 324 bodyCallInputs.add(newObject); |
329 | 325 |
330 // Pass uncaptured arguments first, captured arguments in a box, then type | 326 // Pass uncaptured arguments first, captured arguments in a box, then type |
331 // arguments. | 327 // arguments. |
332 | 328 |
333 ConstructorElement constructorElement = _elementMap.getConstructor(body); | 329 ConstructorEntity constructorElement = _elementMap.getConstructor(body); |
334 | 330 |
335 void handleParameter(ir.VariableDeclaration node) { | 331 void handleParameter(ir.VariableDeclaration node) { |
336 Local parameter = localsMap.getLocal(node); | 332 Local parameter = localsMap.getLocal(node); |
337 // If [parameter] is boxed, it will be a field in the box passed as the | 333 // If [parameter] is boxed, it will be a field in the box passed as the |
338 // last parameter. So no need to directly pass it. | 334 // last parameter. So no need to directly pass it. |
339 if (!localsHandler.isBoxed(parameter)) { | 335 if (!localsHandler.isBoxed(parameter)) { |
340 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 336 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
341 } | 337 } |
342 } | 338 } |
343 | 339 |
(...skipping 10 matching lines...) Expand all Loading... |
354 if (scopeData.requiresContextBox) { | 350 if (scopeData.requiresContextBox) { |
355 bodyCallInputs.add(localsHandler.readLocal(scopeData.context)); | 351 bodyCallInputs.add(localsHandler.readLocal(scopeData.context)); |
356 } | 352 } |
357 | 353 |
358 // Pass type arguments. | 354 // Pass type arguments. |
359 ir.Class currentClass = body.enclosingClass; | 355 ir.Class currentClass = body.enclosingClass; |
360 if (closedWorld.rtiNeed | 356 if (closedWorld.rtiNeed |
361 .classNeedsRti(_elementMap.getClass(currentClass))) { | 357 .classNeedsRti(_elementMap.getClass(currentClass))) { |
362 for (ir.DartType typeParameter in currentClass.thisType.typeArguments) { | 358 for (ir.DartType typeParameter in currentClass.thisType.typeArguments) { |
363 HInstruction argument = localsHandler.readLocal(localsHandler | 359 HInstruction argument = localsHandler.readLocal(localsHandler |
364 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter) | 360 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter))); |
365 as ResolutionTypeVariableType)); | |
366 bodyCallInputs.add(argument); | 361 bodyCallInputs.add(argument); |
367 } | 362 } |
368 } | 363 } |
369 | 364 |
370 _invokeConstructorBody(body, bodyCallInputs); | 365 _invokeConstructorBody(body, bodyCallInputs); |
371 } | 366 } |
372 | 367 |
373 closeAndGotoExit(new HReturn(newObject, null)); | 368 closeAndGotoExit(new HReturn(newObject, null)); |
374 closeFunction(); | 369 closeFunction(); |
375 } | 370 } |
376 | 371 |
377 static bool _isEmptyStatement(ir.Statement body) { | 372 static bool _isEmptyStatement(ir.Statement body) { |
378 if (body is ir.EmptyStatement) return true; | 373 if (body is ir.EmptyStatement) return true; |
379 if (body is ir.Block) return body.statements.every(_isEmptyStatement); | 374 if (body is ir.Block) return body.statements.every(_isEmptyStatement); |
380 return false; | 375 return false; |
381 } | 376 } |
382 | 377 |
383 void _invokeConstructorBody( | 378 void _invokeConstructorBody( |
384 ir.Constructor constructor, List<HInstruction> inputs) { | 379 ir.Constructor constructor, List<HInstruction> inputs) { |
385 // TODO(sra): Inline the constructor body. | 380 // TODO(sra): Inline the constructor body. |
386 MemberEntity constructorBody = | 381 MemberEntity constructorBody = _elementMap.getConstructorBody(constructor); |
387 astAdapter.getConstructorBodyEntity(constructor); | |
388 HInvokeConstructorBody invoke = new HInvokeConstructorBody( | 382 HInvokeConstructorBody invoke = new HInvokeConstructorBody( |
389 constructorBody, inputs, commonMasks.nonNullType); | 383 constructorBody, inputs, commonMasks.nonNullType); |
390 add(invoke); | 384 add(invoke); |
391 } | 385 } |
392 | 386 |
393 /// Sets context for generating code that is the result of inlining | 387 /// Sets context for generating code that is the result of inlining |
394 /// [inlinedTarget]. | 388 /// [inlinedTarget]. |
395 inlinedFrom(MemberEntity inlinedTarget, f()) { | 389 inlinedFrom(MemberEntity inlinedTarget, f()) { |
396 reporter.withCurrentElement(inlinedTarget, () { | 390 reporter.withCurrentElement(inlinedTarget, () { |
397 SourceInformationBuilder oldSourceInformationBuilder = | 391 SourceInformationBuilder oldSourceInformationBuilder = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 } | 425 } |
432 | 426 |
433 return fieldValues; | 427 return fieldValues; |
434 } | 428 } |
435 | 429 |
436 /// Collects field initializers all the way up the inheritance chain. | 430 /// Collects field initializers all the way up the inheritance chain. |
437 void _buildInitializers( | 431 void _buildInitializers( |
438 ir.Constructor constructor, | 432 ir.Constructor constructor, |
439 List<ir.Constructor> constructorChain, | 433 List<ir.Constructor> constructorChain, |
440 Map<FieldEntity, HInstruction> fieldValues) { | 434 Map<FieldEntity, HInstruction> fieldValues) { |
441 assert(_elementMap.getConstructor(constructor) == localsMap.currentMember); | 435 assert( |
| 436 _elementMap.getConstructor(constructor) == localsMap.currentMember, |
| 437 failedAt( |
| 438 localsMap.currentMember, |
| 439 'Expected ${localsMap.currentMember} ' |
| 440 'but found ${_elementMap.getConstructor(constructor)}.')); |
442 constructorChain.add(constructor); | 441 constructorChain.add(constructor); |
443 | 442 |
444 var foundSuperOrRedirectCall = false; | 443 var foundSuperOrRedirectCall = false; |
445 for (var initializer in constructor.initializers) { | 444 for (var initializer in constructor.initializers) { |
446 if (initializer is ir.FieldInitializer) { | 445 if (initializer is ir.FieldInitializer) { |
447 initializer.value.accept(this); | 446 initializer.value.accept(this); |
448 fieldValues[_elementMap.getField(initializer.field)] = pop(); | 447 fieldValues[_elementMap.getField(initializer.field)] = pop(); |
449 } else if (initializer is ir.SuperInitializer) { | 448 } else if (initializer is ir.SuperInitializer) { |
450 assert(!foundSuperOrRedirectCall); | 449 assert(!foundSuperOrRedirectCall); |
451 foundSuperOrRedirectCall = true; | 450 foundSuperOrRedirectCall = true; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 parameters[parameter] = argument; | 597 parameters[parameter] = argument; |
599 localsHandler.updateLocal(parameter, argument); | 598 localsHandler.updateLocal(parameter, argument); |
600 } | 599 } |
601 | 600 |
602 constructor.function.positionalParameters.forEach(handleParameter); | 601 constructor.function.positionalParameters.forEach(handleParameter); |
603 constructor.function.namedParameters.toList() | 602 constructor.function.namedParameters.toList() |
604 ..sort(namedOrdering) | 603 ..sort(namedOrdering) |
605 ..forEach(handleParameter); | 604 ..forEach(handleParameter); |
606 | 605 |
607 // Set the locals handler state as if we were inlining the constructor. | 606 // Set the locals handler state as if we were inlining the constructor. |
608 ConstructorEntity astElement = _elementMap.getConstructor(constructor); | 607 ConstructorEntity element = _elementMap.getConstructor(constructor); |
609 ClosureRepresentationInfo oldScopeInfo = localsHandler.scopeInfo; | 608 ClosureRepresentationInfo oldScopeInfo = localsHandler.scopeInfo; |
610 ClosureRepresentationInfo newScopeInfo = | 609 ClosureRepresentationInfo newScopeInfo = |
611 closureDataLookup.getScopeInfo(astElement); | 610 closureDataLookup.getScopeInfo(element); |
612 if (astElement is ConstructorElement) { | 611 localsHandler.scopeInfo = newScopeInfo; |
613 // TODO(redemption): Support constructor (body) entities. | 612 localsHandler.enterScope(closureDataLookup.getClosureScope(element)); |
614 ResolvedAst resolvedAst = astElement.resolvedAst; | 613 inlinedFrom(element, () { |
615 localsHandler.scopeInfo = newScopeInfo; | |
616 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | |
617 localsHandler.enterScope(closureDataLookup.getClosureScope(astElement), | |
618 forGenerativeConstructorBody: | |
619 astElement.isGenerativeConstructorBody); | |
620 } | |
621 } | |
622 inlinedFrom(astElement, () { | |
623 _buildInitializers(constructor, constructorChain, fieldValues); | 614 _buildInitializers(constructor, constructorChain, fieldValues); |
624 }); | 615 }); |
625 localsHandler.scopeInfo = oldScopeInfo; | 616 localsHandler.scopeInfo = oldScopeInfo; |
626 } | 617 } |
627 | 618 |
628 /// Builds generative constructor body. | 619 /// Builds generative constructor body. |
629 void buildConstructorBody(ir.Constructor constructor) { | 620 void buildConstructorBody(ir.Constructor constructor) { |
630 openFunction(constructor.function); | 621 openFunction(constructor.function); |
631 _addClassTypeVariablesIfNeeded(constructor); | 622 _addClassTypeVariablesIfNeeded(constructor); |
632 constructor.function.body.accept(this); | 623 constructor.function.body.accept(this); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 } | 692 } |
702 | 693 |
703 HBasicBlock block = graph.addNewBlock(); | 694 HBasicBlock block = graph.addNewBlock(); |
704 open(graph.entry); | 695 open(graph.entry); |
705 | 696 |
706 localsHandler.startFunction( | 697 localsHandler.startFunction( |
707 targetElement, | 698 targetElement, |
708 closureDataLookup.getScopeInfo(targetElement), | 699 closureDataLookup.getScopeInfo(targetElement), |
709 closureDataLookup.getClosureScope(targetElement), | 700 closureDataLookup.getClosureScope(targetElement), |
710 parameterMap, | 701 parameterMap, |
711 isGenerativeConstructorBody: _targetIsConstructorBody); | 702 isGenerativeConstructorBody: targetElement is ConstructorBodyEntity); |
712 close(new HGoto()).addSuccessor(block); | 703 close(new HGoto()).addSuccessor(block); |
713 | 704 |
714 open(block); | 705 open(block); |
715 } | 706 } |
716 | 707 |
717 void closeFunction() { | 708 void closeFunction() { |
718 if (!isAborted()) closeAndGotoExit(new HGoto()); | 709 if (!isAborted()) closeAndGotoExit(new HGoto()); |
719 graph.finalize(); | 710 graph.finalize(); |
720 } | 711 } |
721 | 712 |
(...skipping 20 matching lines...) Expand all Loading... |
742 push(trap); | 733 push(trap); |
743 } | 734 } |
744 | 735 |
745 /// Returns the current source element. This is used by the type builder. | 736 /// Returns the current source element. This is used by the type builder. |
746 /// | 737 /// |
747 /// The returned element is a declaration element. | 738 /// The returned element is a declaration element. |
748 // TODO(efortuna): Update this when we implement inlining. | 739 // TODO(efortuna): Update this when we implement inlining. |
749 // TODO(sra): Re-implement type builder using Kernel types and the | 740 // TODO(sra): Re-implement type builder using Kernel types and the |
750 // `target` for context. | 741 // `target` for context. |
751 @override | 742 @override |
752 MemberElement get sourceElement => _targetStack.last; | 743 MemberEntity get sourceElement => _targetStack.last; |
753 | 744 |
754 List<MemberEntity> _targetStack = <MemberEntity>[]; | 745 List<MemberEntity> _targetStack = <MemberEntity>[]; |
755 | 746 |
756 @override | 747 @override |
757 void visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded checkLoad) { | 748 void visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded checkLoad) { |
758 HInstruction prefixConstant = | 749 HInstruction prefixConstant = |
759 graph.addConstantString(checkLoad.import.name, closedWorld); | 750 graph.addConstantString(checkLoad.import.name, closedWorld); |
760 PrefixElement prefixElement = astAdapter.getElement(checkLoad.import); | 751 String uri = _elementMap.getDeferredUri(checkLoad.import); |
761 HInstruction uriConstant = graph.addConstantString( | 752 HInstruction uriConstant = graph.addConstantString(uri, closedWorld); |
762 prefixElement.deferredImport.uri.toString(), closedWorld); | |
763 _pushStaticInvocation( | 753 _pushStaticInvocation( |
764 _commonElements.checkDeferredIsLoaded, | 754 _commonElements.checkDeferredIsLoaded, |
765 [prefixConstant, uriConstant], | 755 [prefixConstant, uriConstant], |
766 _typeInferenceMap | 756 _typeInferenceMap |
767 .getReturnTypeOf(_commonElements.checkDeferredIsLoaded)); | 757 .getReturnTypeOf(_commonElements.checkDeferredIsLoaded)); |
768 } | 758 } |
769 | 759 |
770 @override | 760 @override |
771 void visitLoadLibrary(ir.LoadLibrary loadLibrary) { | 761 void visitLoadLibrary(ir.LoadLibrary loadLibrary) { |
772 // TODO(efortuna): Source information! | 762 // TODO(efortuna): Source information! |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 void visitAsExpression(ir.AsExpression asExpression) { | 1347 void visitAsExpression(ir.AsExpression asExpression) { |
1358 asExpression.operand.accept(this); | 1348 asExpression.operand.accept(this); |
1359 HInstruction expressionInstruction = pop(); | 1349 HInstruction expressionInstruction = pop(); |
1360 | 1350 |
1361 if (asExpression.type is ir.InvalidType) { | 1351 if (asExpression.type is ir.InvalidType) { |
1362 generateTypeError(asExpression, 'invalid type'); | 1352 generateTypeError(asExpression, 'invalid type'); |
1363 stack.add(expressionInstruction); | 1353 stack.add(expressionInstruction); |
1364 return; | 1354 return; |
1365 } | 1355 } |
1366 | 1356 |
1367 ResolutionDartType type = _elementMap.getDartType(asExpression.type); | 1357 DartType type = _elementMap.getDartType(asExpression.type); |
1368 if (type.isMalformed) { | 1358 if (type.isMalformed) { |
1369 if (type is MalformedType) { | 1359 if (type is MalformedType) { |
1370 ErroneousElement element = type.element; | 1360 ErroneousElement element = type.element; |
1371 generateTypeError(asExpression, element.message); | 1361 generateTypeError(asExpression, element.message); |
1372 } else { | 1362 } else { |
1373 assert(type is MethodTypeVariableType); | 1363 assert(type is MethodTypeVariableType); |
1374 stack.add(expressionInstruction); | 1364 stack.add(expressionInstruction); |
1375 } | 1365 } |
1376 } else { | 1366 } else { |
1377 HInstruction converted = typeBuilder.buildTypeConversion( | 1367 HInstruction converted = typeBuilder.buildTypeConversion( |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2088 ir.DartType type = typeLiteral.type; | 2078 ir.DartType type = typeLiteral.type; |
2089 if (type is ir.InterfaceType || type is ir.DynamicType) { | 2079 if (type is ir.InterfaceType || type is ir.DynamicType) { |
2090 ConstantValue constant = _elementMap.getConstantValue(typeLiteral); | 2080 ConstantValue constant = _elementMap.getConstantValue(typeLiteral); |
2091 stack.add(graph.addConstant(constant, closedWorld)); | 2081 stack.add(graph.addConstant(constant, closedWorld)); |
2092 return; | 2082 return; |
2093 } | 2083 } |
2094 // For other types (e.g. TypeParameterType, function types from expanded | 2084 // For other types (e.g. TypeParameterType, function types from expanded |
2095 // typedefs), look-up or construct a reified type representation and convert | 2085 // typedefs), look-up or construct a reified type representation and convert |
2096 // to a RuntimeType. | 2086 // to a RuntimeType. |
2097 | 2087 |
2098 // TODO(sra): Convert the type logic here to use ir.DartType. | 2088 DartType dartType = _elementMap.getDartType(type); |
2099 ResolutionDartType dartType = _elementMap.getDartType(type); | |
2100 dartType = localsHandler.substInContext(dartType); | 2089 dartType = localsHandler.substInContext(dartType); |
2101 HInstruction value = typeBuilder | 2090 HInstruction value = typeBuilder |
2102 .analyzeTypeArgument(dartType, sourceElement, sourceInformation: null); | 2091 .analyzeTypeArgument(dartType, sourceElement, sourceInformation: null); |
2103 _pushStaticInvocation(_commonElements.runtimeTypeToString, | 2092 _pushStaticInvocation(_commonElements.runtimeTypeToString, |
2104 <HInstruction>[value], commonMasks.stringType); | 2093 <HInstruction>[value], commonMasks.stringType); |
2105 _pushStaticInvocation( | 2094 _pushStaticInvocation( |
2106 _commonElements.createRuntimeType, | 2095 _commonElements.createRuntimeType, |
2107 <HInstruction>[pop()], | 2096 <HInstruction>[pop()], |
2108 _typeInferenceMap.getReturnTypeOf(_commonElements.createRuntimeType)); | 2097 _typeInferenceMap.getReturnTypeOf(_commonElements.createRuntimeType)); |
2109 } | 2098 } |
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3433 void pushCondition(ir.Catch catchBlock) { | 3422 void pushCondition(ir.Catch catchBlock) { |
3434 // `guard` is often `dynamic`, which generates `true`. | 3423 // `guard` is often `dynamic`, which generates `true`. |
3435 kernelBuilder.pushIsTest( | 3424 kernelBuilder.pushIsTest( |
3436 catchBlock.exception, catchBlock.guard, unwrappedException); | 3425 catchBlock.exception, catchBlock.guard, unwrappedException); |
3437 } | 3426 } |
3438 | 3427 |
3439 void visitThen() { | 3428 void visitThen() { |
3440 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; | 3429 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; |
3441 catchesIndex++; | 3430 catchesIndex++; |
3442 if (catchBlock.exception != null) { | 3431 if (catchBlock.exception != null) { |
3443 LocalVariableElement exceptionVariable = | 3432 Local exceptionVariable = |
3444 kernelBuilder.localsMap.getLocal(catchBlock.exception); | 3433 kernelBuilder.localsMap.getLocal(catchBlock.exception); |
3445 kernelBuilder.localsHandler | 3434 kernelBuilder.localsHandler |
3446 .updateLocal(exceptionVariable, unwrappedException); | 3435 .updateLocal(exceptionVariable, unwrappedException); |
3447 } | 3436 } |
3448 if (catchBlock.stackTrace != null) { | 3437 if (catchBlock.stackTrace != null) { |
3449 kernelBuilder._pushStaticInvocation( | 3438 kernelBuilder._pushStaticInvocation( |
3450 kernelBuilder._commonElements.traceFromException, | 3439 kernelBuilder._commonElements.traceFromException, |
3451 [exception], | 3440 [exception], |
3452 kernelBuilder._typeInferenceMap.getReturnTypeOf( | 3441 kernelBuilder._typeInferenceMap.getReturnTypeOf( |
3453 kernelBuilder._commonElements.traceFromException)); | 3442 kernelBuilder._commonElements.traceFromException)); |
3454 HInstruction traceInstruction = kernelBuilder.pop(); | 3443 HInstruction traceInstruction = kernelBuilder.pop(); |
3455 LocalVariableElement traceVariable = | 3444 Local traceVariable = |
3456 kernelBuilder.localsMap.getLocal(catchBlock.stackTrace); | 3445 kernelBuilder.localsMap.getLocal(catchBlock.stackTrace); |
3457 kernelBuilder.localsHandler | 3446 kernelBuilder.localsHandler |
3458 .updateLocal(traceVariable, traceInstruction); | 3447 .updateLocal(traceVariable, traceInstruction); |
3459 } | 3448 } |
3460 catchBlock.body.accept(kernelBuilder); | 3449 catchBlock.body.accept(kernelBuilder); |
3461 } | 3450 } |
3462 | 3451 |
3463 void visitElse() { | 3452 void visitElse() { |
3464 if (catchesIndex >= tryCatch.catches.length) { | 3453 if (catchesIndex >= tryCatch.catches.length) { |
3465 kernelBuilder.closeAndGotoExit(new HThrow( | 3454 kernelBuilder.closeAndGotoExit(new HThrow( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3506 enterBlock.setBlockFlow( | 3495 enterBlock.setBlockFlow( |
3507 new HTryBlockInformation( | 3496 new HTryBlockInformation( |
3508 kernelBuilder.wrapStatementGraph(bodyGraph), | 3497 kernelBuilder.wrapStatementGraph(bodyGraph), |
3509 exception, | 3498 exception, |
3510 kernelBuilder.wrapStatementGraph(catchGraph), | 3499 kernelBuilder.wrapStatementGraph(catchGraph), |
3511 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3500 kernelBuilder.wrapStatementGraph(finallyGraph)), |
3512 exitBlock); | 3501 exitBlock); |
3513 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3502 kernelBuilder.inTryStatement = previouslyInTryStatement; |
3514 } | 3503 } |
3515 } | 3504 } |
OLD | NEW |