| 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'; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 this.functionNode, | 111 this.functionNode, |
| 112 {bool targetIsConstructorBody: false}) | 112 {bool targetIsConstructorBody: false}) |
| 113 : this._targetIsConstructorBody = targetIsConstructorBody { | 113 : this._targetIsConstructorBody = targetIsConstructorBody { |
| 114 this.loopHandler = new KernelLoopHandler(this); | 114 this.loopHandler = new KernelLoopHandler(this); |
| 115 typeBuilder = new TypeBuilder(this); | 115 typeBuilder = new TypeBuilder(this); |
| 116 graph.element = targetElement; | 116 graph.element = targetElement; |
| 117 graph.sourceInformation = | 117 graph.sourceInformation = |
| 118 sourceInformationBuilder.buildVariableDeclaration(); | 118 sourceInformationBuilder.buildVariableDeclaration(); |
| 119 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, | 119 this.localsHandler = new LocalsHandler(this, targetElement, targetElement, |
| 120 contextClass, null, nativeData, interceptorData); | 120 contextClass, null, nativeData, interceptorData); |
| 121 _targetStack.add(target); | 121 _targetStack.add(targetElement); |
| 122 } | 122 } |
| 123 | 123 |
| 124 @deprecated // Use [_elementMap] instead. | 124 @deprecated // Use [_elementMap] instead. |
| 125 KernelAstAdapter get astAdapter => _elementMap; | 125 KernelAstAdapter get astAdapter => _elementMap; |
| 126 | 126 |
| 127 CommonElements get _commonElements => _elementMap.commonElements; | 127 CommonElements get _commonElements => _elementMap.commonElements; |
| 128 | 128 |
| 129 HGraph build() { | 129 HGraph build() { |
| 130 // TODO(het): no reason to do this here... | 130 // TODO(het): no reason to do this here... |
| 131 HInstruction.idCounter = 0; | 131 HInstruction.idCounter = 0; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 152 assert(graph.isValid()); | 152 assert(graph.isValid()); |
| 153 return graph; | 153 return graph; |
| 154 } | 154 } |
| 155 | 155 |
| 156 void buildField(ir.Field field) { | 156 void buildField(ir.Field field) { |
| 157 openFunction(); | 157 openFunction(); |
| 158 if (field.initializer != null) { | 158 if (field.initializer != null) { |
| 159 field.initializer.accept(this); | 159 field.initializer.accept(this); |
| 160 HInstruction fieldValue = pop(); | 160 HInstruction fieldValue = pop(); |
| 161 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( | 161 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( |
| 162 fieldValue, astAdapter.getDartTypeIfValid(field.type)); | 162 fieldValue, _getDartTypeIfValid(field.type)); |
| 163 stack.add(checkInstruction); | 163 stack.add(checkInstruction); |
| 164 } else { | 164 } else { |
| 165 stack.add(graph.addConstantNull(closedWorld)); | 165 stack.add(graph.addConstantNull(closedWorld)); |
| 166 } | 166 } |
| 167 HInstruction value = pop(); | 167 HInstruction value = pop(); |
| 168 closeAndGotoExit(new HReturn(value, null)); | 168 closeAndGotoExit(new HReturn(value, null)); |
| 169 closeFunction(); | 169 closeFunction(); |
| 170 } | 170 } |
| 171 | 171 |
| 172 DartType _getDartTypeIfValid(ir.DartType type) { |
| 173 if (type is ir.InvalidType) return null; |
| 174 return _elementMap.getDartType(type); |
| 175 } |
| 176 |
| 172 /// Pops the most recent instruction from the stack and 'boolifies' it. | 177 /// Pops the most recent instruction from the stack and 'boolifies' it. |
| 173 /// | 178 /// |
| 174 /// Boolification is checking if the value is '=== true'. | 179 /// Boolification is checking if the value is '=== true'. |
| 175 @override | 180 @override |
| 176 HInstruction popBoolified() { | 181 HInstruction popBoolified() { |
| 177 HInstruction value = pop(); | 182 HInstruction value = pop(); |
| 178 if (typeBuilder.checkOrTrustTypes) { | 183 if (typeBuilder.checkOrTrustTypes) { |
| 179 ResolutionInterfaceType type = commonElements.boolType; | 184 ResolutionInterfaceType type = commonElements.boolType; |
| 180 return typeBuilder.potentiallyCheckOrTrustType(value, type, | 185 return typeBuilder.potentiallyCheckOrTrustType(value, type, |
| 181 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 186 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 ir.Class constructedClass = constructor.enclosingClass; | 249 ir.Class constructedClass = constructor.enclosingClass; |
| 245 | 250 |
| 246 openFunction(); | 251 openFunction(); |
| 247 _addClassTypeVariablesIfNeeded(constructor); | 252 _addClassTypeVariablesIfNeeded(constructor); |
| 248 | 253 |
| 249 // TODO(sra): Type parameter constraint checks. | 254 // TODO(sra): Type parameter constraint checks. |
| 250 | 255 |
| 251 // TODO(sra): Checked mode parameter checks. | 256 // TODO(sra): Checked mode parameter checks. |
| 252 | 257 |
| 253 // Collect field values for the current class. | 258 // Collect field values for the current class. |
| 254 Map<ir.Field, HInstruction> fieldValues = | 259 Map<FieldEntity, HInstruction> fieldValues = |
| 255 _collectFieldValues(constructedClass); | 260 _collectFieldValues(constructedClass); |
| 256 List<ir.Constructor> constructorChain = <ir.Constructor>[]; | 261 List<ir.Constructor> constructorChain = <ir.Constructor>[]; |
| 257 _buildInitializers(constructor, constructorChain, fieldValues); | 262 _buildInitializers(constructor, constructorChain, fieldValues); |
| 258 | 263 |
| 259 final constructorArguments = <HInstruction>[]; | 264 final constructorArguments = <HInstruction>[]; |
| 260 // Doing this instead of fieldValues.forEach because we haven't defined the | 265 // Doing this instead of fieldValues.forEach because we haven't defined the |
| 261 // order of the arguments here. We can define that with JElements. | 266 // order of the arguments here. We can define that with JElements. |
| 262 ClassElement cls = _elementMap.getClass(constructedClass); | 267 ClassElement cls = _elementMap.getClass(constructedClass); |
| 263 cls.forEachInstanceField( | 268 cls.forEachInstanceField( |
| 264 (ClassElement enclosingClass, FieldElement member) { | 269 (ClassElement enclosingClass, FieldElement member) { |
| 265 var value = fieldValues[astAdapter.getFieldFromElement(member)]; | 270 var value = fieldValues[member]; |
| 266 assert(value != null, | 271 assert(value != null, 'No value for field ${member}'); |
| 267 'No value for field ${member} aka ${astAdapter.getFieldFromElement(mem
ber)}'); | |
| 268 constructorArguments.add(value); | 272 constructorArguments.add(value); |
| 269 }, includeSuperAndInjectedMembers: true); | 273 }, includeSuperAndInjectedMembers: true); |
| 270 | 274 |
| 271 // Create the runtime type information, if needed. | 275 // Create the runtime type information, if needed. |
| 272 bool hasRtiInput = backend.rtiNeed | 276 bool hasRtiInput = backend.rtiNeed |
| 273 .classNeedsRtiField(_elementMap.getClass(constructedClass)); | 277 .classNeedsRtiField(_elementMap.getClass(constructedClass)); |
| 274 if (hasRtiInput) { | 278 if (hasRtiInput) { |
| 275 // Read the values of the type arguments and create a HTypeInfoExpression | 279 // Read the values of the type arguments and create a HTypeInfoExpression |
| 276 // to set on the newly create object. | 280 // to set on the newly create object. |
| 277 List<HInstruction> typeArguments = <HInstruction>[]; | 281 List<HInstruction> typeArguments = <HInstruction>[]; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 308 | 312 |
| 309 for (ir.Constructor body in constructorChain.reversed) { | 313 for (ir.Constructor body in constructorChain.reversed) { |
| 310 if (_isEmptyStatement(body.function.body)) continue; | 314 if (_isEmptyStatement(body.function.body)) continue; |
| 311 | 315 |
| 312 List<HInstruction> bodyCallInputs = <HInstruction>[]; | 316 List<HInstruction> bodyCallInputs = <HInstruction>[]; |
| 313 bodyCallInputs.add(newObject); | 317 bodyCallInputs.add(newObject); |
| 314 | 318 |
| 315 // Pass uncaptured arguments first, captured arguments in a box, then type | 319 // Pass uncaptured arguments first, captured arguments in a box, then type |
| 316 // arguments. | 320 // arguments. |
| 317 | 321 |
| 318 ConstructorElement constructorElement = astAdapter.getElement(body); | 322 ConstructorElement constructorElement = astAdapter.getConstructor(body); |
| 319 ClosureClassMap parameterClosureData = | 323 ClosureClassMap parameterClosureData = |
| 320 closureToClassMapper.getMemberMap(constructorElement); | 324 closureToClassMapper.getMemberMap(constructorElement); |
| 321 | 325 |
| 322 var functionSignature = astAdapter.getFunctionSignature(body.function); | 326 var functionSignature = astAdapter.getFunctionSignature(body.function); |
| 323 // Provide the parameters to the generative constructor body. | 327 // Provide the parameters to the generative constructor body. |
| 324 functionSignature.orderedForEachParameter((ParameterElement parameter) { | 328 functionSignature.orderedForEachParameter((ParameterElement parameter) { |
| 325 // If [parameter] is boxed, it will be a field in the box passed as the | 329 // If [parameter] is boxed, it will be a field in the box passed as the |
| 326 // last parameter. So no need to directly pass it. | 330 // last parameter. So no need to directly pass it. |
| 327 if (!localsHandler.isBoxed(parameter)) { | 331 if (!localsHandler.isBoxed(parameter)) { |
| 328 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 332 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 void _invokeConstructorBody( | 368 void _invokeConstructorBody( |
| 365 ir.Constructor constructor, List<HInstruction> inputs) { | 369 ir.Constructor constructor, List<HInstruction> inputs) { |
| 366 // TODO(sra): Inline the constructor body. | 370 // TODO(sra): Inline the constructor body. |
| 367 MemberEntity constructorBody = | 371 MemberEntity constructorBody = |
| 368 astAdapter.getConstructorBodyEntity(constructor); | 372 astAdapter.getConstructorBodyEntity(constructor); |
| 369 HInvokeConstructorBody invoke = new HInvokeConstructorBody( | 373 HInvokeConstructorBody invoke = new HInvokeConstructorBody( |
| 370 constructorBody, inputs, commonMasks.nonNullType); | 374 constructorBody, inputs, commonMasks.nonNullType); |
| 371 add(invoke); | 375 add(invoke); |
| 372 } | 376 } |
| 373 | 377 |
| 374 withCurrentIrNode(ir.Node node, f()) { | |
| 375 reporter.withCurrentElement(astAdapter.getElement(node), f); | |
| 376 } | |
| 377 | |
| 378 /// Sets context for generating code that is the result of inlining | 378 /// Sets context for generating code that is the result of inlining |
| 379 /// [inlinedTarget]. | 379 /// [inlinedTarget]. |
| 380 inlinedFrom(ir.TreeNode inlinedTarget, f()) { | 380 inlinedFrom(MemberEntity inlinedTarget, f()) { |
| 381 withCurrentIrNode(inlinedTarget, () { | 381 reporter.withCurrentElement(inlinedTarget, () { |
| 382 SourceInformationBuilder oldSourceInformationBuilder = | 382 SourceInformationBuilder oldSourceInformationBuilder = |
| 383 sourceInformationBuilder; | 383 sourceInformationBuilder; |
| 384 // TODO(sra): Update sourceInformationBuilder to Kernel. | 384 // TODO(sra): Update sourceInformationBuilder to Kernel. |
| 385 // sourceInformationBuilder = | 385 // sourceInformationBuilder = |
| 386 // sourceInformationBuilder.forContext(resolvedAst); | 386 // sourceInformationBuilder.forContext(resolvedAst); |
| 387 |
| 388 _elementMap.enterInlinedMember(inlinedTarget); |
| 387 _targetStack.add(inlinedTarget); | 389 _targetStack.add(inlinedTarget); |
| 388 var result = f(); | 390 var result = f(); |
| 389 sourceInformationBuilder = oldSourceInformationBuilder; | 391 sourceInformationBuilder = oldSourceInformationBuilder; |
| 390 _targetStack.removeLast(); | 392 _targetStack.removeLast(); |
| 393 _elementMap.leaveInlinedMember(inlinedTarget); |
| 391 return result; | 394 return result; |
| 392 }); | 395 }); |
| 393 } | 396 } |
| 394 | 397 |
| 395 /// Maps the instance fields of a class to their SSA values. | 398 /// Maps the instance fields of a class to their SSA values. |
| 396 Map<ir.Field, HInstruction> _collectFieldValues(ir.Class clazz) { | 399 Map<FieldEntity, HInstruction> _collectFieldValues(ir.Class clazz) { |
| 397 final fieldValues = <ir.Field, HInstruction>{}; | 400 Map<FieldEntity, HInstruction> fieldValues = <FieldEntity, HInstruction>{}; |
| 398 | 401 |
| 399 for (var field in clazz.fields) { | 402 for (ir.Field node in clazz.fields) { |
| 400 if (field.isInstanceMember) { | 403 if (node.isInstanceMember) { |
| 401 if (field.initializer == null) { | 404 FieldEntity field = _elementMap.getField(node); |
| 405 if (node.initializer == null) { |
| 402 fieldValues[field] = graph.addConstantNull(closedWorld); | 406 fieldValues[field] = graph.addConstantNull(closedWorld); |
| 403 } else { | 407 } else { |
| 404 // Gotta update the resolvedAst when we're looking at field values | 408 // Gotta update the resolvedAst when we're looking at field values |
| 405 // outside the constructor. | 409 // outside the constructor. |
| 406 astAdapter.pushResolvedAst(field); | |
| 407 inlinedFrom(field, () { | 410 inlinedFrom(field, () { |
| 408 field.initializer.accept(this); | 411 node.initializer.accept(this); |
| 409 fieldValues[field] = pop(); | 412 fieldValues[field] = pop(); |
| 410 }); | 413 }); |
| 411 astAdapter.popResolvedAstStack(); | |
| 412 } | 414 } |
| 413 } | 415 } |
| 414 } | 416 } |
| 415 | 417 |
| 416 return fieldValues; | 418 return fieldValues; |
| 417 } | 419 } |
| 418 | 420 |
| 419 /// Collects field initializers all the way up the inheritance chain. | 421 /// Collects field initializers all the way up the inheritance chain. |
| 420 void _buildInitializers( | 422 void _buildInitializers( |
| 421 ir.Constructor constructor, | 423 ir.Constructor constructor, |
| 422 List<ir.Constructor> constructorChain, | 424 List<ir.Constructor> constructorChain, |
| 423 Map<ir.Field, HInstruction> fieldValues) { | 425 Map<FieldEntity, HInstruction> fieldValues) { |
| 424 astAdapter.assertAtResolvedAstFor(constructor); | 426 astAdapter.assertAtResolvedAstFor(constructor); |
| 425 constructorChain.add(constructor); | 427 constructorChain.add(constructor); |
| 426 | 428 |
| 427 var foundSuperOrRedirectCall = false; | 429 var foundSuperOrRedirectCall = false; |
| 428 for (var initializer in constructor.initializers) { | 430 for (var initializer in constructor.initializers) { |
| 429 if (initializer is ir.FieldInitializer) { | 431 if (initializer is ir.FieldInitializer) { |
| 430 initializer.value.accept(this); | 432 initializer.value.accept(this); |
| 431 fieldValues[initializer.field] = pop(); | 433 fieldValues[_elementMap.getField(initializer.field)] = pop(); |
| 432 } else if (initializer is ir.SuperInitializer) { | 434 } else if (initializer is ir.SuperInitializer) { |
| 433 assert(!foundSuperOrRedirectCall); | 435 assert(!foundSuperOrRedirectCall); |
| 434 foundSuperOrRedirectCall = true; | 436 foundSuperOrRedirectCall = true; |
| 435 _inlineSuperInitializer( | 437 _inlineSuperInitializer( |
| 436 initializer, constructorChain, fieldValues, constructor); | 438 initializer, constructorChain, fieldValues, constructor); |
| 437 } else if (initializer is ir.RedirectingInitializer) { | 439 } else if (initializer is ir.RedirectingInitializer) { |
| 438 assert(!foundSuperOrRedirectCall); | 440 assert(!foundSuperOrRedirectCall); |
| 439 foundSuperOrRedirectCall = true; | 441 foundSuperOrRedirectCall = true; |
| 440 _inlineRedirectingInitializer( | 442 _inlineRedirectingInitializer( |
| 441 initializer, constructorChain, fieldValues, constructor); | 443 initializer, constructorChain, fieldValues, constructor); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 var parameters = cls.typeParameters; | 504 var parameters = cls.typeParameters; |
| 503 var arguments = supertype.typeArguments; | 505 var arguments = supertype.typeArguments; |
| 504 assert(arguments.length == parameters.length); | 506 assert(arguments.length == parameters.length); |
| 505 | 507 |
| 506 for (int i = 0; i < parameters.length; i++) { | 508 for (int i = 0; i < parameters.length; i++) { |
| 507 ir.DartType argument = arguments[i]; | 509 ir.DartType argument = arguments[i]; |
| 508 ir.TypeParameter parameter = parameters[i]; | 510 ir.TypeParameter parameter = parameters[i]; |
| 509 | 511 |
| 510 localsHandler.updateLocal( | 512 localsHandler.updateLocal( |
| 511 localsHandler.getTypeVariableAsLocal( | 513 localsHandler.getTypeVariableAsLocal( |
| 512 astAdapter.getDartType(new ir.TypeParameterType(parameter))), | 514 _elementMap.getDartType(new ir.TypeParameterType(parameter))), |
| 513 typeBuilder.analyzeTypeArgument( | 515 typeBuilder.analyzeTypeArgument( |
| 514 astAdapter.getDartType(argument), sourceElement)); | 516 _elementMap.getDartType(argument), sourceElement)); |
| 515 } | 517 } |
| 516 } | 518 } |
| 517 | 519 |
| 518 /// Inlines the given redirecting [constructor]'s initializers by collecting | 520 /// Inlines the given redirecting [constructor]'s initializers by collecting |
| 519 /// its field values and building its constructor initializers. We visit super | 521 /// its field values and building its constructor initializers. We visit super |
| 520 /// constructors all the way up to the [Object] constructor. | 522 /// constructors all the way up to the [Object] constructor. |
| 521 void _inlineRedirectingInitializer( | 523 void _inlineRedirectingInitializer( |
| 522 ir.RedirectingInitializer initializer, | 524 ir.RedirectingInitializer initializer, |
| 523 List<ir.Constructor> constructorChain, | 525 List<ir.Constructor> constructorChain, |
| 524 Map<ir.Field, HInstruction> fieldValues, | 526 Map<FieldEntity, HInstruction> fieldValues, |
| 525 ir.Constructor caller) { | 527 ir.Constructor caller) { |
| 526 var superOrRedirectConstructor = initializer.target; | 528 var superOrRedirectConstructor = initializer.target; |
| 527 var arguments = _normalizeAndBuildArguments( | 529 var arguments = _normalizeAndBuildArguments( |
| 528 superOrRedirectConstructor.function, initializer.arguments); | 530 superOrRedirectConstructor.function, initializer.arguments); |
| 529 | 531 |
| 530 // Redirecting initializer already has [localsHandler] bindings for type | 532 // Redirecting initializer already has [localsHandler] bindings for type |
| 531 // parameters from the redirecting constructor. | 533 // parameters from the redirecting constructor. |
| 532 | 534 |
| 533 // For redirecting constructors, the fields will be initialized later by the | 535 // For redirecting constructors, the fields will be initialized later by the |
| 534 // effective target, so we don't do it here. | 536 // effective target, so we don't do it here. |
| 535 | 537 |
| 536 _inlineSuperOrRedirectCommon(initializer, superOrRedirectConstructor, | 538 _inlineSuperOrRedirectCommon(initializer, superOrRedirectConstructor, |
| 537 arguments, constructorChain, fieldValues, caller); | 539 arguments, constructorChain, fieldValues, caller); |
| 538 } | 540 } |
| 539 | 541 |
| 540 /// Inlines the given super [constructor]'s initializers by collecting its | 542 /// Inlines the given super [constructor]'s initializers by collecting its |
| 541 /// field values and building its constructor initializers. We visit super | 543 /// field values and building its constructor initializers. We visit super |
| 542 /// constructors all the way up to the [Object] constructor. | 544 /// constructors all the way up to the [Object] constructor. |
| 543 void _inlineSuperInitializer( | 545 void _inlineSuperInitializer( |
| 544 ir.SuperInitializer initializer, | 546 ir.SuperInitializer initializer, |
| 545 List<ir.Constructor> constructorChain, | 547 List<ir.Constructor> constructorChain, |
| 546 Map<ir.Field, HInstruction> fieldValues, | 548 Map<FieldEntity, HInstruction> fieldValues, |
| 547 ir.Constructor caller) { | 549 ir.Constructor caller) { |
| 548 var target = initializer.target; | 550 var target = initializer.target; |
| 549 var arguments = | 551 var arguments = |
| 550 _normalizeAndBuildArguments(target.function, initializer.arguments); | 552 _normalizeAndBuildArguments(target.function, initializer.arguments); |
| 551 | 553 |
| 552 ir.Class callerClass = caller.enclosingClass; | 554 ir.Class callerClass = caller.enclosingClass; |
| 553 _bindSupertypeTypeParameters(callerClass.supertype); | 555 _bindSupertypeTypeParameters(callerClass.supertype); |
| 554 if (callerClass.mixedInType != null) { | 556 if (callerClass.mixedInType != null) { |
| 555 _bindSupertypeTypeParameters(callerClass.mixedInType); | 557 _bindSupertypeTypeParameters(callerClass.mixedInType); |
| 556 } | 558 } |
| 557 | 559 |
| 558 ir.Class cls = target.enclosingClass; | 560 ir.Class cls = target.enclosingClass; |
| 559 | 561 |
| 560 inlinedFrom(target, () { | 562 inlinedFrom(_elementMap.getConstructor(target), () { |
| 561 fieldValues.addAll(_collectFieldValues(cls)); | 563 fieldValues.addAll(_collectFieldValues(cls)); |
| 562 }); | 564 }); |
| 563 | 565 |
| 564 _inlineSuperOrRedirectCommon( | 566 _inlineSuperOrRedirectCommon( |
| 565 initializer, target, arguments, constructorChain, fieldValues, caller); | 567 initializer, target, arguments, constructorChain, fieldValues, caller); |
| 566 } | 568 } |
| 567 | 569 |
| 568 void _inlineSuperOrRedirectCommon( | 570 void _inlineSuperOrRedirectCommon( |
| 569 ir.Initializer initializer, | 571 ir.Initializer initializer, |
| 570 ir.Constructor constructor, | 572 ir.Constructor constructor, |
| 571 List<HInstruction> arguments, | 573 List<HInstruction> arguments, |
| 572 List<ir.Constructor> constructorChain, | 574 List<ir.Constructor> constructorChain, |
| 573 Map<ir.Field, HInstruction> fieldValues, | 575 Map<FieldEntity, HInstruction> fieldValues, |
| 574 ir.Constructor caller) { | 576 ir.Constructor caller) { |
| 575 var signature = astAdapter.getFunctionSignature(constructor.function); | 577 var signature = astAdapter.getFunctionSignature(constructor.function); |
| 576 var index = 0; | 578 var index = 0; |
| 577 signature.orderedForEachParameter((ParameterElement parameter) { | 579 signature.orderedForEachParameter((ParameterElement parameter) { |
| 578 HInstruction argument = arguments[index++]; | 580 HInstruction argument = arguments[index++]; |
| 579 // Because we are inlining the initializer, we must update | 581 // Because we are inlining the initializer, we must update |
| 580 // what was given as parameter. This will be used in case | 582 // what was given as parameter. This will be used in case |
| 581 // there is a parameter check expression in the initializer. | 583 // there is a parameter check expression in the initializer. |
| 582 parameters[parameter] = argument; | 584 parameters[parameter] = argument; |
| 583 localsHandler.updateLocal(parameter, argument); | 585 localsHandler.updateLocal(parameter, argument); |
| 584 }); | 586 }); |
| 585 | 587 |
| 586 // Set the locals handler state as if we were inlining the constructor. | 588 // Set the locals handler state as if we were inlining the constructor. |
| 587 astAdapter.pushResolvedAst(constructor); | 589 ConstructorElement astElement = _elementMap.getConstructor(constructor); |
| 588 ConstructorElement astElement = astAdapter.getElement(constructor); | |
| 589 ResolvedAst resolvedAst = astElement.resolvedAst; | 590 ResolvedAst resolvedAst = astElement.resolvedAst; |
| 590 ClosureClassMap oldClosureData = localsHandler.closureData; | 591 ClosureClassMap oldClosureData = localsHandler.closureData; |
| 591 ClosureClassMap newClosureData = | 592 ClosureClassMap newClosureData = |
| 592 closureToClassMapper.getMemberMap(astElement); | 593 closureToClassMapper.getMemberMap(astElement); |
| 593 localsHandler.closureData = newClosureData; | 594 localsHandler.closureData = newClosureData; |
| 594 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 595 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
| 595 localsHandler.enterScope(resolvedAst.node, | 596 localsHandler.enterScope(resolvedAst.node, |
| 596 forGenerativeConstructorBody: astElement.isGenerativeConstructorBody); | 597 forGenerativeConstructorBody: astElement.isGenerativeConstructorBody); |
| 597 } | 598 } |
| 598 inlinedFrom(constructor, () { | 599 inlinedFrom(astElement, () { |
| 599 _buildInitializers(constructor, constructorChain, fieldValues); | 600 _buildInitializers(constructor, constructorChain, fieldValues); |
| 600 }); | 601 }); |
| 601 localsHandler.closureData = oldClosureData; | 602 localsHandler.closureData = oldClosureData; |
| 602 astAdapter.popResolvedAstStack(); | |
| 603 } | 603 } |
| 604 | 604 |
| 605 /// Builds generative constructor body. | 605 /// Builds generative constructor body. |
| 606 void buildConstructorBody(ir.Constructor constructor) { | 606 void buildConstructorBody(ir.Constructor constructor) { |
| 607 openFunction(); | 607 openFunction(); |
| 608 _addClassTypeVariablesIfNeeded(constructor); | 608 _addClassTypeVariablesIfNeeded(constructor); |
| 609 constructor.function.body.accept(this); | 609 constructor.function.body.accept(this); |
| 610 closeFunction(); | 610 closeFunction(); |
| 611 } | 611 } |
| 612 | 612 |
| 613 /// Builds a SSA graph for FunctionNodes, found in FunctionExpressions and | 613 /// Builds a SSA graph for FunctionNodes, found in FunctionExpressions and |
| 614 /// Procedures. | 614 /// Procedures. |
| 615 void buildFunctionNode(ir.FunctionNode functionNode) { | 615 void buildFunctionNode(ir.FunctionNode functionNode) { |
| 616 openFunction(); | 616 openFunction(); |
| 617 ir.TreeNode parent = functionNode.parent; | 617 ir.TreeNode parent = functionNode.parent; |
| 618 if (parent is ir.Procedure && parent.kind == ir.ProcedureKind.Factory) { | 618 if (parent is ir.Procedure && parent.kind == ir.ProcedureKind.Factory) { |
| 619 _addClassTypeVariablesIfNeeded(functionNode.parent); | 619 _addClassTypeVariablesIfNeeded(functionNode.parent); |
| 620 } | 620 } |
| 621 | 621 |
| 622 // If [functionNode] is `operator==` we explicitly add a null check at the | 622 // If [functionNode] is `operator==` we explicitly add a null check at the |
| 623 // beginning of the method. This is to avoid having call sites do the null | 623 // beginning of the method. This is to avoid having call sites do the null |
| 624 // check. | 624 // check. |
| 625 if (parent is ir.Procedure && | 625 if (parent is ir.Procedure && |
| 626 parent.kind == ir.ProcedureKind.Operator && | 626 parent.kind == ir.ProcedureKind.Operator && |
| 627 parent.name.name == '==') { | 627 parent.name.name == '==') { |
| 628 if (!backend | 628 MethodElement method = _elementMap.getMethod(parent); |
| 629 .operatorEqHandlesNullArgument(_elementMap.getMethod(parent))) { | 629 if (!backend.operatorEqHandlesNullArgument(method)) { |
| 630 handleIf( | 630 handleIf( |
| 631 visitCondition: () { | 631 visitCondition: () { |
| 632 HParameterValue parameter = parameters.values.first; | 632 HParameterValue parameter = parameters.values.first; |
| 633 push(new HIdentity(parameter, graph.addConstantNull(closedWorld), | 633 push(new HIdentity(parameter, graph.addConstantNull(closedWorld), |
| 634 null, commonMasks.boolType)); | 634 null, commonMasks.boolType)); |
| 635 }, | 635 }, |
| 636 visitThen: () { | 636 visitThen: () { |
| 637 closeAndGotoExit(new HReturn( | 637 closeAndGotoExit(new HReturn( |
| 638 graph.addConstantBool(false, closedWorld), | 638 graph.addConstantBool(false, closedWorld), |
| 639 sourceInformationBuilder | 639 sourceInformationBuilder.buildImplicitReturn(method))); |
| 640 .buildImplicitReturn(astAdapter.getElement(parent)))); | |
| 641 }, | 640 }, |
| 642 visitElse: null, | 641 visitElse: null, |
| 643 // TODO(27394): Add sourceInformation via | 642 // TODO(27394): Add sourceInformation via |
| 644 // `sourceInformationBuilder.buildIf(?)`. | 643 // `sourceInformationBuilder.buildIf(?)`. |
| 645 ); | 644 ); |
| 646 } | 645 } |
| 647 } | 646 } |
| 648 functionNode.body.accept(this); | 647 functionNode.body.accept(this); |
| 649 closeFunction(); | 648 closeFunction(); |
| 650 } | 649 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 push(trap); | 705 push(trap); |
| 707 } | 706 } |
| 708 | 707 |
| 709 /// Returns the current source element. This is used by the type builder. | 708 /// Returns the current source element. This is used by the type builder. |
| 710 /// | 709 /// |
| 711 /// The returned element is a declaration element. | 710 /// The returned element is a declaration element. |
| 712 // TODO(efortuna): Update this when we implement inlining. | 711 // TODO(efortuna): Update this when we implement inlining. |
| 713 // TODO(sra): Re-implement type builder using Kernel types and the | 712 // TODO(sra): Re-implement type builder using Kernel types and the |
| 714 // `target` for context. | 713 // `target` for context. |
| 715 @override | 714 @override |
| 716 Element get sourceElement => _sourceElementForTarget(_targetStack.last); | 715 MemberElement get sourceElement => _targetStack.last; |
| 717 | 716 |
| 718 List<ir.Node> _targetStack = <ir.Node>[]; | 717 List<MemberEntity> _targetStack = <MemberEntity>[]; |
| 719 | |
| 720 Element _sourceElementForTarget(ir.Node target) { | |
| 721 // For closure-converted (i.e. local functions) the source element is the | |
| 722 // 'call' method of the class that represents the closure. | |
| 723 Element callMethodOfClosureClass() { | |
| 724 LocalFunctionElement element = astAdapter.getElement(target); | |
| 725 ClosureClassMap classMap = | |
| 726 closureToClassMapper.getLocalFunctionMap(element); | |
| 727 return classMap.callElement; | |
| 728 } | |
| 729 | |
| 730 if (target is ir.FunctionExpression) { | |
| 731 return callMethodOfClosureClass(); | |
| 732 } | |
| 733 if (target is ir.FunctionDeclaration) { | |
| 734 return callMethodOfClosureClass(); | |
| 735 } | |
| 736 Element element = astAdapter.getElement(target); | |
| 737 return element; | |
| 738 } | |
| 739 | 718 |
| 740 @override | 719 @override |
| 741 void visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded checkLoad) { | 720 void visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded checkLoad) { |
| 742 HInstruction prefixConstant = | 721 HInstruction prefixConstant = |
| 743 graph.addConstantString(checkLoad.import.name, closedWorld); | 722 graph.addConstantString(checkLoad.import.name, closedWorld); |
| 744 var prefixElement = astAdapter.getElement(checkLoad.import); | 723 var prefixElement = astAdapter.getElement(checkLoad.import); |
| 745 HInstruction uriConstant = graph.addConstantString( | 724 HInstruction uriConstant = graph.addConstantString( |
| 746 prefixElement.deferredImport.uri.toString(), closedWorld); | 725 prefixElement.deferredImport.uri.toString(), closedWorld); |
| 747 _pushStaticInvocation( | 726 _pushStaticInvocation( |
| 748 _commonElements.checkDeferredIsLoaded, | 727 _commonElements.checkDeferredIsLoaded, |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 _commonElements.checkConcurrentModificationError, | 921 _commonElements.checkConcurrentModificationError, |
| 943 [pop(), array], | 922 [pop(), array], |
| 944 _typeInferenceMap.getReturnTypeOf( | 923 _typeInferenceMap.getReturnTypeOf( |
| 945 _commonElements.checkConcurrentModificationError)); | 924 _commonElements.checkConcurrentModificationError)); |
| 946 pop(); | 925 pop(); |
| 947 } | 926 } |
| 948 | 927 |
| 949 void buildInitializer() { | 928 void buildInitializer() { |
| 950 forInStatement.iterable.accept(this); | 929 forInStatement.iterable.accept(this); |
| 951 array = pop(); | 930 array = pop(); |
| 952 isFixed = astAdapter.isFixedLength(array.instructionType, closedWorld); | 931 isFixed = |
| 932 _typeInferenceMap.isFixedLength(array.instructionType, closedWorld); |
| 953 localsHandler.updateLocal( | 933 localsHandler.updateLocal( |
| 954 indexVariable, graph.addConstantInt(0, closedWorld)); | 934 indexVariable, graph.addConstantInt(0, closedWorld)); |
| 955 originalLength = buildGetLength(); | 935 originalLength = buildGetLength(); |
| 956 } | 936 } |
| 957 | 937 |
| 958 HInstruction buildCondition() { | 938 HInstruction buildCondition() { |
| 959 HInstruction index = localsHandler.readLocal(indexVariable); | 939 HInstruction index = localsHandler.readLocal(indexVariable); |
| 960 HInstruction length = buildGetLength(); | 940 HInstruction length = buildGetLength(); |
| 961 HInstruction compare = | 941 HInstruction compare = |
| 962 new HLess(index, length, null, commonMasks.boolType); | 942 new HLess(index, length, null, commonMasks.boolType); |
| (...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2041 if (staticTarget is ir.Procedure) { | 2021 if (staticTarget is ir.Procedure) { |
| 2042 FunctionEntity setter = _elementMap.getMember(staticTarget); | 2022 FunctionEntity setter = _elementMap.getMember(staticTarget); |
| 2043 // Invoke the setter | 2023 // Invoke the setter |
| 2044 _pushStaticInvocation(setter, <HInstruction>[value], | 2024 _pushStaticInvocation(setter, <HInstruction>[value], |
| 2045 _typeInferenceMap.getReturnTypeOf(setter)); | 2025 _typeInferenceMap.getReturnTypeOf(setter)); |
| 2046 pop(); | 2026 pop(); |
| 2047 } else { | 2027 } else { |
| 2048 add(new HStaticStore( | 2028 add(new HStaticStore( |
| 2049 _elementMap.getMember(staticTarget), | 2029 _elementMap.getMember(staticTarget), |
| 2050 typeBuilder.potentiallyCheckOrTrustType( | 2030 typeBuilder.potentiallyCheckOrTrustType( |
| 2051 value, astAdapter.getDartTypeIfValid(staticTarget.setterType)))); | 2031 value, _getDartTypeIfValid(staticTarget.setterType)))); |
| 2052 } | 2032 } |
| 2053 stack.add(value); | 2033 stack.add(value); |
| 2054 } | 2034 } |
| 2055 | 2035 |
| 2056 @override | 2036 @override |
| 2057 void visitPropertyGet(ir.PropertyGet propertyGet) { | 2037 void visitPropertyGet(ir.PropertyGet propertyGet) { |
| 2058 propertyGet.receiver.accept(this); | 2038 propertyGet.receiver.accept(this); |
| 2059 HInstruction receiver = pop(); | 2039 HInstruction receiver = pop(); |
| 2060 | 2040 |
| 2061 _pushDynamicInvocation(propertyGet, | 2041 _pushDynamicInvocation(propertyGet, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2128 HInstruction initialValue = pop(); | 2108 HInstruction initialValue = pop(); |
| 2129 | 2109 |
| 2130 _visitLocalSetter(declaration, initialValue); | 2110 _visitLocalSetter(declaration, initialValue); |
| 2131 | 2111 |
| 2132 // Ignore value | 2112 // Ignore value |
| 2133 pop(); | 2113 pop(); |
| 2134 } | 2114 } |
| 2135 } | 2115 } |
| 2136 | 2116 |
| 2137 void _visitLocalSetter(ir.VariableDeclaration variable, HInstruction value) { | 2117 void _visitLocalSetter(ir.VariableDeclaration variable, HInstruction value) { |
| 2138 LocalElement local = astAdapter.getElement(variable); | 2118 LocalElement local = astAdapter.getLocal(variable); |
| 2139 | 2119 |
| 2140 // Give the value a name if it doesn't have one already. | 2120 // Give the value a name if it doesn't have one already. |
| 2141 if (value.sourceElement == null) { | 2121 if (value.sourceElement == null) { |
| 2142 value.sourceElement = local; | 2122 value.sourceElement = local; |
| 2143 } | 2123 } |
| 2144 | 2124 |
| 2145 stack.add(value); | 2125 stack.add(value); |
| 2146 localsHandler.updateLocal( | 2126 localsHandler.updateLocal( |
| 2147 local, | 2127 local, |
| 2148 typeBuilder.potentiallyCheckOrTrustType( | 2128 typeBuilder.potentiallyCheckOrTrustType( |
| 2149 value, astAdapter.getDartTypeIfValid(variable.type))); | 2129 value, _getDartTypeIfValid(variable.type))); |
| 2150 } | 2130 } |
| 2151 | 2131 |
| 2152 @override | 2132 @override |
| 2153 void visitLet(ir.Let let) { | 2133 void visitLet(ir.Let let) { |
| 2154 ir.VariableDeclaration variable = let.variable; | 2134 ir.VariableDeclaration variable = let.variable; |
| 2155 variable.initializer.accept(this); | 2135 variable.initializer.accept(this); |
| 2156 HInstruction initializedValue = pop(); | 2136 HInstruction initializedValue = pop(); |
| 2157 // TODO(sra): Apply inferred type information. | 2137 // TODO(sra): Apply inferred type information. |
| 2158 letBindings[variable] = initializedValue; | 2138 letBindings[variable] = initializedValue; |
| 2159 let.body.accept(this); | 2139 let.body.accept(this); |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2773 } else if (selector.isSetter) { | 2753 } else if (selector.isSetter) { |
| 2774 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); | 2754 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); |
| 2775 } else { | 2755 } else { |
| 2776 push(new HInvokeDynamicMethod( | 2756 push(new HInvokeDynamicMethod( |
| 2777 selector, mask, inputs, type, isIntercepted)); | 2757 selector, mask, inputs, type, isIntercepted)); |
| 2778 } | 2758 } |
| 2779 } | 2759 } |
| 2780 | 2760 |
| 2781 @override | 2761 @override |
| 2782 visitFunctionNode(ir.FunctionNode node) { | 2762 visitFunctionNode(ir.FunctionNode node) { |
| 2783 LocalFunctionElement methodElement = astAdapter.getElement(node); | 2763 Local methodElement = _elementMap.getLocalFunction(node); |
| 2784 ClosureClassMap nestedClosureData = | 2764 ClosureClassMap nestedClosureData = |
| 2785 closureToClassMapper.getLocalFunctionMap(methodElement); | 2765 closureToClassMapper.getLocalFunctionMap(methodElement); |
| 2786 assert(nestedClosureData != null); | 2766 assert(nestedClosureData != null); |
| 2787 assert(nestedClosureData.closureClassElement != null); | 2767 assert(nestedClosureData.closureClassElement != null); |
| 2788 ClosureClassElement closureClassElement = | 2768 ClosureClassElement closureClassElement = |
| 2789 nestedClosureData.closureClassElement; | 2769 nestedClosureData.closureClassElement; |
| 2790 MethodElement callElement = nestedClosureData.callElement; | 2770 MethodElement callElement = nestedClosureData.callElement; |
| 2791 | 2771 |
| 2792 List<HInstruction> capturedVariables = <HInstruction>[]; | 2772 List<HInstruction> capturedVariables = <HInstruction>[]; |
| 2793 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | 2773 closureClassElement.closureFields.forEach((ClosureFieldElement field) { |
| 2794 Local capturedLocal = | 2774 Local capturedLocal = |
| 2795 nestedClosureData.getLocalVariableForClosureField(field); | 2775 nestedClosureData.getLocalVariableForClosureField(field); |
| 2796 assert(capturedLocal != null); | 2776 assert(capturedLocal != null); |
| 2797 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2777 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
| 2798 }); | 2778 }); |
| 2799 | 2779 |
| 2800 TypeMask type = new TypeMask.nonNullExact(closureClassElement, closedWorld); | 2780 TypeMask type = new TypeMask.nonNullExact(closureClassElement, closedWorld); |
| 2801 // TODO(efortuna): Add source information here. | 2781 // TODO(efortuna): Add source information here. |
| 2802 push(new HCreate(closureClassElement, capturedVariables, type, | 2782 push(new HCreate(closureClassElement, capturedVariables, type, |
| 2803 callMethod: callElement, localFunction: methodElement)); | 2783 callMethod: callElement, localFunction: methodElement)); |
| 2804 } | 2784 } |
| 2805 | 2785 |
| 2806 @override | 2786 @override |
| 2807 visitFunctionDeclaration(ir.FunctionDeclaration declaration) { | 2787 visitFunctionDeclaration(ir.FunctionDeclaration declaration) { |
| 2808 assert(isReachable); | 2788 assert(isReachable); |
| 2809 declaration.function.accept(this); | 2789 declaration.function.accept(this); |
| 2810 LocalFunctionElement localFunction = | 2790 Local localFunction = _elementMap.getLocalFunction(declaration.function); |
| 2811 astAdapter.getElement(declaration.function); | |
| 2812 localsHandler.updateLocal(localFunction, pop()); | 2791 localsHandler.updateLocal(localFunction, pop()); |
| 2813 } | 2792 } |
| 2814 | 2793 |
| 2815 @override | 2794 @override |
| 2816 void visitFunctionExpression(ir.FunctionExpression funcExpression) { | 2795 void visitFunctionExpression(ir.FunctionExpression funcExpression) { |
| 2817 funcExpression.function.accept(this); | 2796 funcExpression.function.accept(this); |
| 2818 } | 2797 } |
| 2819 | 2798 |
| 2820 // TODO(het): Decide when to inline | 2799 // TODO(het): Decide when to inline |
| 2821 @override | 2800 @override |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3353 // `guard` is often `dynamic`, which generates `true`. | 3332 // `guard` is often `dynamic`, which generates `true`. |
| 3354 kernelBuilder.pushIsTest( | 3333 kernelBuilder.pushIsTest( |
| 3355 catchBlock.exception, catchBlock.guard, unwrappedException); | 3334 catchBlock.exception, catchBlock.guard, unwrappedException); |
| 3356 } | 3335 } |
| 3357 | 3336 |
| 3358 void visitThen() { | 3337 void visitThen() { |
| 3359 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; | 3338 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; |
| 3360 catchesIndex++; | 3339 catchesIndex++; |
| 3361 if (catchBlock.exception != null) { | 3340 if (catchBlock.exception != null) { |
| 3362 LocalVariableElement exceptionVariable = | 3341 LocalVariableElement exceptionVariable = |
| 3363 kernelBuilder.astAdapter.getElement(catchBlock.exception); | 3342 kernelBuilder.astAdapter.getLocal(catchBlock.exception); |
| 3364 kernelBuilder.localsHandler | 3343 kernelBuilder.localsHandler |
| 3365 .updateLocal(exceptionVariable, unwrappedException); | 3344 .updateLocal(exceptionVariable, unwrappedException); |
| 3366 } | 3345 } |
| 3367 if (catchBlock.stackTrace != null) { | 3346 if (catchBlock.stackTrace != null) { |
| 3368 kernelBuilder._pushStaticInvocation( | 3347 kernelBuilder._pushStaticInvocation( |
| 3369 kernelBuilder._commonElements.traceFromException, | 3348 kernelBuilder._commonElements.traceFromException, |
| 3370 [exception], | 3349 [exception], |
| 3371 kernelBuilder._typeInferenceMap.getReturnTypeOf( | 3350 kernelBuilder._typeInferenceMap.getReturnTypeOf( |
| 3372 kernelBuilder._commonElements.traceFromException)); | 3351 kernelBuilder._commonElements.traceFromException)); |
| 3373 HInstruction traceInstruction = kernelBuilder.pop(); | 3352 HInstruction traceInstruction = kernelBuilder.pop(); |
| 3374 LocalVariableElement traceVariable = | 3353 LocalVariableElement traceVariable = |
| 3375 kernelBuilder.astAdapter.getElement(catchBlock.stackTrace); | 3354 kernelBuilder.astAdapter.getLocal(catchBlock.stackTrace); |
| 3376 kernelBuilder.localsHandler | 3355 kernelBuilder.localsHandler |
| 3377 .updateLocal(traceVariable, traceInstruction); | 3356 .updateLocal(traceVariable, traceInstruction); |
| 3378 } | 3357 } |
| 3379 catchBlock.body.accept(kernelBuilder); | 3358 catchBlock.body.accept(kernelBuilder); |
| 3380 } | 3359 } |
| 3381 | 3360 |
| 3382 void visitElse() { | 3361 void visitElse() { |
| 3383 if (catchesIndex >= tryCatch.catches.length) { | 3362 if (catchesIndex >= tryCatch.catches.length) { |
| 3384 kernelBuilder.closeAndGotoExit(new HThrow( | 3363 kernelBuilder.closeAndGotoExit(new HThrow( |
| 3385 exception, exception.sourceInformation, | 3364 exception, exception.sourceInformation, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3425 enterBlock.setBlockFlow( | 3404 enterBlock.setBlockFlow( |
| 3426 new HTryBlockInformation( | 3405 new HTryBlockInformation( |
| 3427 kernelBuilder.wrapStatementGraph(bodyGraph), | 3406 kernelBuilder.wrapStatementGraph(bodyGraph), |
| 3428 exception, | 3407 exception, |
| 3429 kernelBuilder.wrapStatementGraph(catchGraph), | 3408 kernelBuilder.wrapStatementGraph(catchGraph), |
| 3430 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3409 kernelBuilder.wrapStatementGraph(finallyGraph)), |
| 3431 exitBlock); | 3410 exitBlock); |
| 3432 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3411 kernelBuilder.inTryStatement = previouslyInTryStatement; |
| 3433 } | 3412 } |
| 3434 } | 3413 } |
| OLD | NEW |