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 |
344 // Provide the parameters to the generative constructor body. | 340 // Provide the parameters to the generative constructor body. |
345 body.function.positionalParameters.forEach(handleParameter); | 341 body.function.positionalParameters.forEach(handleParameter); |
346 body.function.namedParameters.toList() | 342 body.function.namedParameters.toList() |
347 ..sort(namedOrdering) | 343 ..sort(namedOrdering) |
348 ..forEach(handleParameter); | 344 ..forEach(handleParameter); |
349 | 345 |
350 // If there are locals that escape (i.e. mutated in closures), we pass the | 346 // If there are locals that escape (i.e. mutated in closures), we pass the |
351 // box to the constructor. | 347 // box to the constructor. |
352 ClosureScope scopeData = | 348 ClosureScope scopeData = |
353 closureDataLookup.getClosureScope(constructorElement); | 349 closureDataLookup.getClosureScope(constructorElement); |
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 (backend.rtiNeed.classNeedsRti(_elementMap.getClass(currentClass))) { | 356 if (backend.rtiNeed.classNeedsRti(_elementMap.getClass(currentClass))) { |
361 for (ir.DartType typeParameter in currentClass.thisType.typeArguments) { | 357 for (ir.DartType typeParameter in currentClass.thisType.typeArguments) { |
362 HInstruction argument = localsHandler.readLocal(localsHandler | 358 HInstruction argument = localsHandler.readLocal(localsHandler |
363 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter) | 359 .getTypeVariableAsLocal(_elementMap.getDartType(typeParameter))); |
364 as ResolutionTypeVariableType)); | |
365 bodyCallInputs.add(argument); | 360 bodyCallInputs.add(argument); |
366 } | 361 } |
367 } | 362 } |
368 | 363 |
369 _invokeConstructorBody(body, bodyCallInputs); | 364 _invokeConstructorBody(body, bodyCallInputs); |
370 } | 365 } |
371 | 366 |
372 closeAndGotoExit(new HReturn(newObject, null)); | 367 closeAndGotoExit(new HReturn(newObject, null)); |
373 closeFunction(); | 368 closeFunction(); |
374 } | 369 } |
375 | 370 |
376 static bool _isEmptyStatement(ir.Statement body) { | 371 static bool _isEmptyStatement(ir.Statement body) { |
377 if (body is ir.EmptyStatement) return true; | 372 if (body is ir.EmptyStatement) return true; |
378 if (body is ir.Block) return body.statements.every(_isEmptyStatement); | 373 if (body is ir.Block) return body.statements.every(_isEmptyStatement); |
379 return false; | 374 return false; |
380 } | 375 } |
381 | 376 |
382 void _invokeConstructorBody( | 377 void _invokeConstructorBody( |
383 ir.Constructor constructor, List<HInstruction> inputs) { | 378 ir.Constructor constructor, List<HInstruction> inputs) { |
384 // TODO(sra): Inline the constructor body. | 379 // TODO(sra): Inline the constructor body. |
385 MemberEntity constructorBody = | 380 MemberEntity constructorBody = _elementMap.getConstructorBody(constructor); |
386 astAdapter.getConstructorBodyEntity(constructor); | |
387 HInvokeConstructorBody invoke = new HInvokeConstructorBody( | 381 HInvokeConstructorBody invoke = new HInvokeConstructorBody( |
388 constructorBody, inputs, commonMasks.nonNullType); | 382 constructorBody, inputs, commonMasks.nonNullType); |
389 add(invoke); | 383 add(invoke); |
390 } | 384 } |
391 | 385 |
392 /// Sets context for generating code that is the result of inlining | 386 /// Sets context for generating code that is the result of inlining |
393 /// [inlinedTarget]. | 387 /// [inlinedTarget]. |
394 inlinedFrom(MemberEntity inlinedTarget, f()) { | 388 inlinedFrom(MemberEntity inlinedTarget, f()) { |
395 reporter.withCurrentElement(inlinedTarget, () { | 389 reporter.withCurrentElement(inlinedTarget, () { |
396 SourceInformationBuilder oldSourceInformationBuilder = | 390 SourceInformationBuilder oldSourceInformationBuilder = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 } | 424 } |
431 | 425 |
432 return fieldValues; | 426 return fieldValues; |
433 } | 427 } |
434 | 428 |
435 /// Collects field initializers all the way up the inheritance chain. | 429 /// Collects field initializers all the way up the inheritance chain. |
436 void _buildInitializers( | 430 void _buildInitializers( |
437 ir.Constructor constructor, | 431 ir.Constructor constructor, |
438 List<ir.Constructor> constructorChain, | 432 List<ir.Constructor> constructorChain, |
439 Map<FieldEntity, HInstruction> fieldValues) { | 433 Map<FieldEntity, HInstruction> fieldValues) { |
440 assert(_elementMap.getConstructor(constructor) == localsMap.currentMember); | 434 assert( |
435 _elementMap.getConstructor(constructor) == localsMap.currentMember, | |
436 failedAt( | |
437 localsMap.currentMember, | |
438 'Expected ${localsMap.currentMember} ' | |
439 'but found ${_elementMap.getConstructor(constructor)}.')); | |
441 constructorChain.add(constructor); | 440 constructorChain.add(constructor); |
442 | 441 |
443 var foundSuperOrRedirectCall = false; | 442 var foundSuperOrRedirectCall = false; |
444 for (var initializer in constructor.initializers) { | 443 for (var initializer in constructor.initializers) { |
445 if (initializer is ir.FieldInitializer) { | 444 if (initializer is ir.FieldInitializer) { |
446 initializer.value.accept(this); | 445 initializer.value.accept(this); |
447 fieldValues[_elementMap.getField(initializer.field)] = pop(); | 446 fieldValues[_elementMap.getField(initializer.field)] = pop(); |
448 } else if (initializer is ir.SuperInitializer) { | 447 } else if (initializer is ir.SuperInitializer) { |
449 assert(!foundSuperOrRedirectCall); | 448 assert(!foundSuperOrRedirectCall); |
450 foundSuperOrRedirectCall = true; | 449 foundSuperOrRedirectCall = true; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
597 parameters[parameter] = argument; | 596 parameters[parameter] = argument; |
598 localsHandler.updateLocal(parameter, argument); | 597 localsHandler.updateLocal(parameter, argument); |
599 } | 598 } |
600 | 599 |
601 constructor.function.positionalParameters.forEach(handleParameter); | 600 constructor.function.positionalParameters.forEach(handleParameter); |
602 constructor.function.namedParameters.toList() | 601 constructor.function.namedParameters.toList() |
603 ..sort(namedOrdering) | 602 ..sort(namedOrdering) |
604 ..forEach(handleParameter); | 603 ..forEach(handleParameter); |
605 | 604 |
606 // Set the locals handler state as if we were inlining the constructor. | 605 // Set the locals handler state as if we were inlining the constructor. |
607 ConstructorEntity astElement = _elementMap.getConstructor(constructor); | 606 ConstructorEntity element = _elementMap.getConstructor(constructor); |
608 ClosureRepresentationInfo oldScopeInfo = localsHandler.scopeInfo; | 607 ClosureRepresentationInfo oldScopeInfo = localsHandler.scopeInfo; |
609 ClosureRepresentationInfo newScopeInfo = | 608 ClosureRepresentationInfo newScopeInfo = |
610 closureDataLookup.getScopeInfo(astElement); | 609 closureDataLookup.getScopeInfo(element); |
611 if (astElement is ConstructorElement) { | 610 localsHandler.scopeInfo = newScopeInfo; |
612 // TODO(redemption): Support constructor (body) entities. | 611 localsHandler.enterScope(closureDataLookup.getClosureScope(element)); |
613 ResolvedAst resolvedAst = astElement.resolvedAst; | 612 inlinedFrom(element, () { |
614 localsHandler.scopeInfo = newScopeInfo; | |
615 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | |
616 localsHandler.enterScope(closureDataLookup.getClosureScope(astElement), | |
617 forGenerativeConstructorBody: | |
618 astElement.isGenerativeConstructorBody); | |
619 } | |
620 } | |
621 inlinedFrom(astElement, () { | |
622 _buildInitializers(constructor, constructorChain, fieldValues); | 613 _buildInitializers(constructor, constructorChain, fieldValues); |
623 }); | 614 }); |
624 localsHandler.scopeInfo = oldScopeInfo; | 615 localsHandler.scopeInfo = oldScopeInfo; |
625 } | 616 } |
626 | 617 |
627 /// Builds generative constructor body. | 618 /// Builds generative constructor body. |
628 void buildConstructorBody(ir.Constructor constructor) { | 619 void buildConstructorBody(ir.Constructor constructor) { |
629 openFunction(constructor.function); | 620 openFunction(constructor.function); |
630 _addClassTypeVariablesIfNeeded(constructor); | 621 _addClassTypeVariablesIfNeeded(constructor); |
631 constructor.function.body.accept(this); | 622 constructor.function.body.accept(this); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
700 } | 691 } |
701 | 692 |
702 HBasicBlock block = graph.addNewBlock(); | 693 HBasicBlock block = graph.addNewBlock(); |
703 open(graph.entry); | 694 open(graph.entry); |
704 | 695 |
705 localsHandler.startFunction( | 696 localsHandler.startFunction( |
706 targetElement, | 697 targetElement, |
707 closureDataLookup.getScopeInfo(targetElement), | 698 closureDataLookup.getScopeInfo(targetElement), |
708 closureDataLookup.getClosureScope(targetElement), | 699 closureDataLookup.getClosureScope(targetElement), |
709 parameterMap, | 700 parameterMap, |
710 isGenerativeConstructorBody: _targetIsConstructorBody); | 701 isGenerativeConstructorBody: targetElement is ConstructorBodyEntity); |
711 close(new HGoto()).addSuccessor(block); | 702 close(new HGoto()).addSuccessor(block); |
712 | 703 |
713 open(block); | 704 open(block); |
714 } | 705 } |
715 | 706 |
716 void closeFunction() { | 707 void closeFunction() { |
717 if (!isAborted()) closeAndGotoExit(new HGoto()); | 708 if (!isAborted()) closeAndGotoExit(new HGoto()); |
718 graph.finalize(); | 709 graph.finalize(); |
719 } | 710 } |
720 | 711 |
(...skipping 20 matching lines...) Expand all Loading... | |
741 push(trap); | 732 push(trap); |
742 } | 733 } |
743 | 734 |
744 /// Returns the current source element. This is used by the type builder. | 735 /// Returns the current source element. This is used by the type builder. |
745 /// | 736 /// |
746 /// The returned element is a declaration element. | 737 /// The returned element is a declaration element. |
747 // TODO(efortuna): Update this when we implement inlining. | 738 // TODO(efortuna): Update this when we implement inlining. |
748 // TODO(sra): Re-implement type builder using Kernel types and the | 739 // TODO(sra): Re-implement type builder using Kernel types and the |
749 // `target` for context. | 740 // `target` for context. |
750 @override | 741 @override |
751 MemberElement get sourceElement => _targetStack.last; | 742 MemberEntity get sourceElement => _targetStack.last; |
752 | 743 |
753 List<MemberEntity> _targetStack = <MemberEntity>[]; | 744 List<MemberEntity> _targetStack = <MemberEntity>[]; |
754 | 745 |
755 @override | 746 @override |
756 void visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded checkLoad) { | 747 void visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded checkLoad) { |
757 HInstruction prefixConstant = | 748 HInstruction prefixConstant = |
758 graph.addConstantString(checkLoad.import.name, closedWorld); | 749 graph.addConstantString(checkLoad.import.name, closedWorld); |
759 PrefixElement prefixElement = astAdapter.getElement(checkLoad.import); | 750 String uri = _elementMap.getDeferredUri(checkLoad.import); |
Siggi Cherem (dart-lang)
2017/07/07 20:00:25
I think in this case we don't need the extra metho
Johnni Winther
2017/07/10 14:11:34
They're not the same in rasta :(
Added a TODO on
Siggi Cherem (dart-lang)
2017/07/10 16:39:13
mmm - what is the actual difference? Is it that we
Johnni Winther
2017/07/11 08:09:17
One is relative and one is absolute.
I think long
| |
760 HInstruction uriConstant = graph.addConstantString( | 751 HInstruction uriConstant = graph.addConstantString(uri, closedWorld); |
761 prefixElement.deferredImport.uri.toString(), closedWorld); | |
762 _pushStaticInvocation( | 752 _pushStaticInvocation( |
763 _commonElements.checkDeferredIsLoaded, | 753 _commonElements.checkDeferredIsLoaded, |
764 [prefixConstant, uriConstant], | 754 [prefixConstant, uriConstant], |
765 _typeInferenceMap | 755 _typeInferenceMap |
766 .getReturnTypeOf(_commonElements.checkDeferredIsLoaded)); | 756 .getReturnTypeOf(_commonElements.checkDeferredIsLoaded)); |
767 } | 757 } |
768 | 758 |
769 @override | 759 @override |
770 void visitLoadLibrary(ir.LoadLibrary loadLibrary) { | 760 void visitLoadLibrary(ir.LoadLibrary loadLibrary) { |
771 // TODO(efortuna): Source information! | 761 // TODO(efortuna): Source information! |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1356 void visitAsExpression(ir.AsExpression asExpression) { | 1346 void visitAsExpression(ir.AsExpression asExpression) { |
1357 asExpression.operand.accept(this); | 1347 asExpression.operand.accept(this); |
1358 HInstruction expressionInstruction = pop(); | 1348 HInstruction expressionInstruction = pop(); |
1359 | 1349 |
1360 if (asExpression.type is ir.InvalidType) { | 1350 if (asExpression.type is ir.InvalidType) { |
1361 generateTypeError(asExpression, 'invalid type'); | 1351 generateTypeError(asExpression, 'invalid type'); |
1362 stack.add(expressionInstruction); | 1352 stack.add(expressionInstruction); |
1363 return; | 1353 return; |
1364 } | 1354 } |
1365 | 1355 |
1366 ResolutionDartType type = _elementMap.getDartType(asExpression.type); | 1356 DartType type = _elementMap.getDartType(asExpression.type); |
1367 if (type.isMalformed) { | 1357 if (type.isMalformed) { |
1368 if (type is MalformedType) { | 1358 if (type is MalformedType) { |
1369 ErroneousElement element = type.element; | 1359 ErroneousElement element = type.element; |
1370 generateTypeError(asExpression, element.message); | 1360 generateTypeError(asExpression, element.message); |
1371 } else { | 1361 } else { |
1372 assert(type is MethodTypeVariableType); | 1362 assert(type is MethodTypeVariableType); |
1373 stack.add(expressionInstruction); | 1363 stack.add(expressionInstruction); |
1374 } | 1364 } |
1375 } else { | 1365 } else { |
1376 HInstruction converted = typeBuilder.buildTypeConversion( | 1366 HInstruction converted = typeBuilder.buildTypeConversion( |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2087 ir.DartType type = typeLiteral.type; | 2077 ir.DartType type = typeLiteral.type; |
2088 if (type is ir.InterfaceType || type is ir.DynamicType) { | 2078 if (type is ir.InterfaceType || type is ir.DynamicType) { |
2089 ConstantValue constant = _elementMap.getConstantValue(typeLiteral); | 2079 ConstantValue constant = _elementMap.getConstantValue(typeLiteral); |
2090 stack.add(graph.addConstant(constant, closedWorld)); | 2080 stack.add(graph.addConstant(constant, closedWorld)); |
2091 return; | 2081 return; |
2092 } | 2082 } |
2093 // For other types (e.g. TypeParameterType, function types from expanded | 2083 // For other types (e.g. TypeParameterType, function types from expanded |
2094 // typedefs), look-up or construct a reified type representation and convert | 2084 // typedefs), look-up or construct a reified type representation and convert |
2095 // to a RuntimeType. | 2085 // to a RuntimeType. |
2096 | 2086 |
2097 // TODO(sra): Convert the type logic here to use ir.DartType. | 2087 DartType dartType = _elementMap.getDartType(type); |
2098 ResolutionDartType dartType = _elementMap.getDartType(type); | |
2099 dartType = localsHandler.substInContext(dartType); | 2088 dartType = localsHandler.substInContext(dartType); |
2100 HInstruction value = typeBuilder | 2089 HInstruction value = typeBuilder |
2101 .analyzeTypeArgument(dartType, sourceElement, sourceInformation: null); | 2090 .analyzeTypeArgument(dartType, sourceElement, sourceInformation: null); |
2102 _pushStaticInvocation(_commonElements.runtimeTypeToString, | 2091 _pushStaticInvocation(_commonElements.runtimeTypeToString, |
2103 <HInstruction>[value], commonMasks.stringType); | 2092 <HInstruction>[value], commonMasks.stringType); |
2104 _pushStaticInvocation( | 2093 _pushStaticInvocation( |
2105 _commonElements.createRuntimeType, | 2094 _commonElements.createRuntimeType, |
2106 <HInstruction>[pop()], | 2095 <HInstruction>[pop()], |
2107 _typeInferenceMap.getReturnTypeOf(_commonElements.createRuntimeType)); | 2096 _typeInferenceMap.getReturnTypeOf(_commonElements.createRuntimeType)); |
2108 } | 2097 } |
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3432 void pushCondition(ir.Catch catchBlock) { | 3421 void pushCondition(ir.Catch catchBlock) { |
3433 // `guard` is often `dynamic`, which generates `true`. | 3422 // `guard` is often `dynamic`, which generates `true`. |
3434 kernelBuilder.pushIsTest( | 3423 kernelBuilder.pushIsTest( |
3435 catchBlock.exception, catchBlock.guard, unwrappedException); | 3424 catchBlock.exception, catchBlock.guard, unwrappedException); |
3436 } | 3425 } |
3437 | 3426 |
3438 void visitThen() { | 3427 void visitThen() { |
3439 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; | 3428 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; |
3440 catchesIndex++; | 3429 catchesIndex++; |
3441 if (catchBlock.exception != null) { | 3430 if (catchBlock.exception != null) { |
3442 LocalVariableElement exceptionVariable = | 3431 Local exceptionVariable = |
3443 kernelBuilder.localsMap.getLocal(catchBlock.exception); | 3432 kernelBuilder.localsMap.getLocal(catchBlock.exception); |
3444 kernelBuilder.localsHandler | 3433 kernelBuilder.localsHandler |
3445 .updateLocal(exceptionVariable, unwrappedException); | 3434 .updateLocal(exceptionVariable, unwrappedException); |
3446 } | 3435 } |
3447 if (catchBlock.stackTrace != null) { | 3436 if (catchBlock.stackTrace != null) { |
3448 kernelBuilder._pushStaticInvocation( | 3437 kernelBuilder._pushStaticInvocation( |
3449 kernelBuilder._commonElements.traceFromException, | 3438 kernelBuilder._commonElements.traceFromException, |
3450 [exception], | 3439 [exception], |
3451 kernelBuilder._typeInferenceMap.getReturnTypeOf( | 3440 kernelBuilder._typeInferenceMap.getReturnTypeOf( |
3452 kernelBuilder._commonElements.traceFromException)); | 3441 kernelBuilder._commonElements.traceFromException)); |
3453 HInstruction traceInstruction = kernelBuilder.pop(); | 3442 HInstruction traceInstruction = kernelBuilder.pop(); |
3454 LocalVariableElement traceVariable = | 3443 Local traceVariable = |
3455 kernelBuilder.localsMap.getLocal(catchBlock.stackTrace); | 3444 kernelBuilder.localsMap.getLocal(catchBlock.stackTrace); |
3456 kernelBuilder.localsHandler | 3445 kernelBuilder.localsHandler |
3457 .updateLocal(traceVariable, traceInstruction); | 3446 .updateLocal(traceVariable, traceInstruction); |
3458 } | 3447 } |
3459 catchBlock.body.accept(kernelBuilder); | 3448 catchBlock.body.accept(kernelBuilder); |
3460 } | 3449 } |
3461 | 3450 |
3462 void visitElse() { | 3451 void visitElse() { |
3463 if (catchesIndex >= tryCatch.catches.length) { | 3452 if (catchesIndex >= tryCatch.catches.length) { |
3464 kernelBuilder.closeAndGotoExit(new HThrow( | 3453 kernelBuilder.closeAndGotoExit(new HThrow( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3505 enterBlock.setBlockFlow( | 3494 enterBlock.setBlockFlow( |
3506 new HTryBlockInformation( | 3495 new HTryBlockInformation( |
3507 kernelBuilder.wrapStatementGraph(bodyGraph), | 3496 kernelBuilder.wrapStatementGraph(bodyGraph), |
3508 exception, | 3497 exception, |
3509 kernelBuilder.wrapStatementGraph(catchGraph), | 3498 kernelBuilder.wrapStatementGraph(catchGraph), |
3510 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3499 kernelBuilder.wrapStatementGraph(finallyGraph)), |
3511 exitBlock); | 3500 exitBlock); |
3512 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3501 kernelBuilder.inTryStatement = previouslyInTryStatement; |
3513 } | 3502 } |
3514 } | 3503 } |
OLD | NEW |