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