| 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, CodegenWorkItem; | 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
| 11 import '../common/tasks.dart' show CompilerTask; | 11 import '../common/tasks.dart' show CompilerTask; |
| 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/resolution_types.dart'; | 19 import '../elements/resolution_types.dart'; |
| 20 import '../elements/elements.dart'; | 20 import '../elements/elements.dart'; |
| 21 import '../elements/entities.dart' show MemberEntity; |
| 21 import '../io/source_information.dart'; | 22 import '../io/source_information.dart'; |
| 22 import '../js/js.dart' as js; | 23 import '../js/js.dart' as js; |
| 23 import '../js_backend/backend.dart' show JavaScriptBackend; | 24 import '../js_backend/backend.dart' show JavaScriptBackend; |
| 24 import '../kernel/kernel.dart'; | 25 import '../kernel/kernel.dart'; |
| 25 import '../native/native.dart' as native; | 26 import '../native/native.dart' as native; |
| 26 import '../resolution/tree_elements.dart'; | 27 import '../resolution/tree_elements.dart'; |
| 27 import '../tree/dartstring.dart'; | 28 import '../tree/dartstring.dart'; |
| 28 import '../tree/nodes.dart' show Node, BreakStatement; | 29 import '../tree/nodes.dart' show Node, BreakStatement; |
| 29 import '../types/masks.dart'; | 30 import '../types/masks.dart'; |
| 30 import '../universe/call_structure.dart' show CallStructure; | 31 import '../universe/call_structure.dart' show CallStructure; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 backend.tracer.traceGraph('builder', graph); | 85 backend.tracer.traceGraph('builder', graph); |
| 85 } | 86 } |
| 86 | 87 |
| 87 return graph; | 88 return graph; |
| 88 }); | 89 }); |
| 89 } | 90 } |
| 90 } | 91 } |
| 91 | 92 |
| 92 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { | 93 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
| 93 ir.Node target; | 94 ir.Node target; |
| 95 bool _targetIsConstructorBody = false; |
| 94 final AstElement targetElement; | 96 final AstElement targetElement; |
| 95 final ResolvedAst resolvedAst; | 97 final ResolvedAst resolvedAst; |
| 96 final ClosedWorld closedWorld; | 98 final ClosedWorld closedWorld; |
| 97 final CodegenRegistry registry; | 99 final CodegenRegistry registry; |
| 98 | 100 |
| 99 /// Helper accessor for all kernel function-like targets (Procedure, | 101 /// Helper accessor for all kernel function-like targets (Procedure, |
| 100 /// FunctionExpression, FunctionDeclaration) of the inner FunctionNode itself. | 102 /// FunctionExpression, FunctionDeclaration) of the inner FunctionNode itself. |
| 101 /// If the current target is not a function-like target, _targetFunction will | 103 /// If the current target is not a function-like target, _targetFunction will |
| 102 /// be null. | 104 /// be null. |
| 103 ir.FunctionNode _targetFunction; | 105 ir.FunctionNode _targetFunction; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 graph.sourceInformation = | 151 graph.sourceInformation = |
| 150 sourceInformationBuilder.buildVariableDeclaration(); | 152 sourceInformationBuilder.buildVariableDeclaration(); |
| 151 this.localsHandler = new LocalsHandler(this, targetElement, null, compiler); | 153 this.localsHandler = new LocalsHandler(this, targetElement, null, compiler); |
| 152 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, | 154 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, |
| 153 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); | 155 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); |
| 154 Element originTarget = targetElement; | 156 Element originTarget = targetElement; |
| 155 if (originTarget.isPatch) { | 157 if (originTarget.isPatch) { |
| 156 originTarget = originTarget.origin; | 158 originTarget = originTarget.origin; |
| 157 } | 159 } |
| 158 if (originTarget is FunctionElement) { | 160 if (originTarget is FunctionElement) { |
| 161 if (originTarget is ConstructorBodyElement) { |
| 162 ConstructorBodyElement body = originTarget; |
| 163 _targetIsConstructorBody = true; |
| 164 originTarget = body.constructor; |
| 165 } |
| 159 target = kernel.functions[originTarget]; | 166 target = kernel.functions[originTarget]; |
| 160 // Closures require a lookup one level deeper in the closure class mapper. | 167 // Closures require a lookup one level deeper in the closure class mapper. |
| 161 if (target == null) { | 168 if (target == null) { |
| 169 FunctionElement originTargetFunction = originTarget; |
| 162 ClosureClassMap classMap = compiler.closureToClassMapper | 170 ClosureClassMap classMap = compiler.closureToClassMapper |
| 163 .getClosureToClassMapping(originTarget.resolvedAst); | 171 .getClosureToClassMapping(originTargetFunction.resolvedAst); |
| 164 if (classMap.closureElement != null) { | 172 if (classMap.closureElement != null) { |
| 165 target = kernel.localFunctions[classMap.closureElement]; | 173 target = kernel.localFunctions[classMap.closureElement]; |
| 166 } | 174 } |
| 167 } | 175 } |
| 168 } else if (originTarget is FieldElement) { | 176 } else if (originTarget is FieldElement) { |
| 169 target = kernel.fields[originTarget]; | 177 target = kernel.fields[originTarget]; |
| 170 } | 178 } |
| 171 } | 179 } |
| 172 | 180 |
| 173 HGraph build() { | 181 HGraph build() { |
| 174 // TODO(het): no reason to do this here... | 182 // TODO(het): no reason to do this here... |
| 175 HInstruction.idCounter = 0; | 183 HInstruction.idCounter = 0; |
| 176 if (target is ir.Procedure) { | 184 if (target is ir.Procedure) { |
| 177 _targetFunction = (target as ir.Procedure).function; | 185 _targetFunction = (target as ir.Procedure).function; |
| 178 buildFunctionNode(_targetFunction); | 186 buildFunctionNode(_targetFunction); |
| 179 } else if (target is ir.Field) { | 187 } else if (target is ir.Field) { |
| 180 buildField(target); | 188 buildField(target); |
| 181 } else if (target is ir.Constructor) { | 189 } else if (target is ir.Constructor) { |
| 182 buildConstructor(target); | 190 if (_targetIsConstructorBody) { |
| 191 buildConstructorBody(target); |
| 192 } else { |
| 193 buildConstructor(target); |
| 194 } |
| 183 } else if (target is ir.FunctionExpression) { | 195 } else if (target is ir.FunctionExpression) { |
| 184 _targetFunction = (target as ir.FunctionExpression).function; | 196 _targetFunction = (target as ir.FunctionExpression).function; |
| 185 buildFunctionNode(_targetFunction); | 197 buildFunctionNode(_targetFunction); |
| 186 } else if (target is ir.FunctionDeclaration) { | 198 } else if (target is ir.FunctionDeclaration) { |
| 187 _targetFunction = (target as ir.FunctionDeclaration).function; | 199 _targetFunction = (target as ir.FunctionDeclaration).function; |
| 188 buildFunctionNode(_targetFunction); | 200 buildFunctionNode(_targetFunction); |
| 189 } else { | 201 } else { |
| 190 throw 'No case implemented to handle $target'; | 202 throw 'No case implemented to handle target: $target'; |
| 191 } | 203 } |
| 192 assert(graph.isValid()); | 204 assert(graph.isValid()); |
| 193 return graph; | 205 return graph; |
| 194 } | 206 } |
| 195 | 207 |
| 196 void buildField(ir.Field field) { | 208 void buildField(ir.Field field) { |
| 197 openFunction(); | 209 openFunction(); |
| 198 if (field.initializer != null) { | 210 if (field.initializer != null) { |
| 199 field.initializer.accept(this); | 211 field.initializer.accept(this); |
| 200 HInstruction fieldValue = pop(); | 212 HInstruction fieldValue = pop(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 /// constructor bodies for all constructors in the hierarchy. | 266 /// constructor bodies for all constructors in the hierarchy. |
| 255 void buildConstructor(ir.Constructor constructor) { | 267 void buildConstructor(ir.Constructor constructor) { |
| 256 openFunction(); | 268 openFunction(); |
| 257 _addClassTypeVariablesIfNeeded(constructor); | 269 _addClassTypeVariablesIfNeeded(constructor); |
| 258 | 270 |
| 259 // Collect field values for the current class. | 271 // Collect field values for the current class. |
| 260 // TODO(het): Does kernel always put field initializers in the constructor | 272 // TODO(het): Does kernel always put field initializers in the constructor |
| 261 // initializer list? If so then this is unnecessary... | 273 // initializer list? If so then this is unnecessary... |
| 262 Map<ir.Field, HInstruction> fieldValues = | 274 Map<ir.Field, HInstruction> fieldValues = |
| 263 _collectFieldValues(constructor.enclosingClass); | 275 _collectFieldValues(constructor.enclosingClass); |
| 276 List<ir.Constructor> constructorChain = <ir.Constructor>[]; |
| 264 | 277 |
| 265 _buildInitializers(constructor, fieldValues); | 278 _buildInitializers(constructor, constructorChain, fieldValues); |
| 266 | 279 |
| 267 final constructorArguments = <HInstruction>[]; | 280 final constructorArguments = <HInstruction>[]; |
| 268 astAdapter.getClass(constructor.enclosingClass).forEachInstanceField( | 281 astAdapter.getClass(constructor.enclosingClass).forEachInstanceField( |
| 269 (ClassElement enclosingClass, FieldElement member) { | 282 (ClassElement enclosingClass, FieldElement member) { |
| 270 var value = fieldValues[astAdapter.getFieldFromElement(member)]; | 283 var value = fieldValues[astAdapter.getFieldFromElement(member)]; |
| 271 constructorArguments.add(value); | 284 constructorArguments.add(value); |
| 272 }, includeSuperAndInjectedMembers: true); | 285 }, includeSuperAndInjectedMembers: true); |
| 273 | 286 |
| 274 // TODO(het): If the class needs runtime type information, add it as a | 287 // TODO(het): If the class needs runtime type information, add it as a |
| 275 // constructor argument. | 288 // constructor argument. |
| 276 HInstruction create = new HCreate( | 289 HInstruction newObject = new HCreate( |
| 277 astAdapter.getClass(constructor.enclosingClass), | 290 astAdapter.getClass(constructor.enclosingClass), |
| 278 constructorArguments, | 291 constructorArguments, |
| 279 new TypeMask.nonNullExact( | 292 new TypeMask.nonNullExact( |
| 280 astAdapter.getClass(constructor.enclosingClass), closedWorld), | 293 astAdapter.getClass(constructor.enclosingClass), closedWorld), |
| 281 instantiatedTypes: <ResolutionDartType>[ | 294 instantiatedTypes: <ResolutionDartType>[ |
| 282 astAdapter.getClass(constructor.enclosingClass).thisType | 295 astAdapter.getClass(constructor.enclosingClass).thisType |
| 283 ], | 296 ], |
| 284 hasRtiInput: false); | 297 hasRtiInput: false); |
| 285 | 298 |
| 286 add(create); | 299 add(newObject); |
| 287 | 300 |
| 288 // Generate calls to the constructor bodies. | 301 // Generate calls to the constructor bodies. |
| 289 | 302 |
| 290 closeAndGotoExit(new HReturn(create, null)); | 303 for (ir.Constructor body in constructorChain.reversed) { |
| 304 if (_isEmptyStatement(body.function.body)) continue; |
| 305 |
| 306 List<HInstruction> bodyCallInputs = <HInstruction>[]; |
| 307 bodyCallInputs.add(newObject); |
| 308 |
| 309 // TODO(sra): Pass arguments, boxes and type parameters. |
| 310 _invokeConstructorBody(body, bodyCallInputs); |
| 311 } |
| 312 |
| 313 closeAndGotoExit(new HReturn(newObject, null)); |
| 291 closeFunction(); | 314 closeFunction(); |
| 292 } | 315 } |
| 293 | 316 |
| 317 static bool _isEmptyStatement(ir.Statement body) { |
| 318 if (body is ir.EmptyStatement) return true; |
| 319 if (body is ir.Block) return body.statements.every(_isEmptyStatement); |
| 320 return false; |
| 321 } |
| 322 |
| 323 void _invokeConstructorBody( |
| 324 ir.Constructor constructor, List<HInstruction> inputs) { |
| 325 // TODO(sra): Inline the constructor body. |
| 326 MemberEntity constructorBody = |
| 327 astAdapter.getConstructorBodyEntity(constructor); |
| 328 HInvokeConstructorBody invoke = new HInvokeConstructorBody( |
| 329 constructorBody, inputs, commonMasks.nonNullType); |
| 330 add(invoke); |
| 331 } |
| 332 |
| 294 /// Maps the instance fields of a class to their SSA values. | 333 /// Maps the instance fields of a class to their SSA values. |
| 295 Map<ir.Field, HInstruction> _collectFieldValues(ir.Class clazz) { | 334 Map<ir.Field, HInstruction> _collectFieldValues(ir.Class clazz) { |
| 296 final fieldValues = <ir.Field, HInstruction>{}; | 335 final fieldValues = <ir.Field, HInstruction>{}; |
| 297 | 336 |
| 298 for (var field in clazz.fields) { | 337 for (var field in clazz.fields) { |
| 299 if (field.isInstanceMember) { | 338 if (field.isInstanceMember) { |
| 300 if (field.initializer == null) { | 339 if (field.initializer == null) { |
| 301 fieldValues[field] = graph.addConstantNull(closedWorld); | 340 fieldValues[field] = graph.addConstantNull(closedWorld); |
| 302 } else { | 341 } else { |
| 303 // Gotta update the resolvedAst when we're looking at field values | 342 // Gotta update the resolvedAst when we're looking at field values |
| 304 // outside the constructor. | 343 // outside the constructor. |
| 305 astAdapter.pushResolvedAst(field); | 344 astAdapter.pushResolvedAst(field); |
| 306 field.initializer.accept(this); | 345 field.initializer.accept(this); |
| 307 fieldValues[field] = pop(); | 346 fieldValues[field] = pop(); |
| 308 astAdapter.popResolvedAstStack(); | 347 astAdapter.popResolvedAstStack(); |
| 309 } | 348 } |
| 310 } | 349 } |
| 311 } | 350 } |
| 312 | 351 |
| 313 return fieldValues; | 352 return fieldValues; |
| 314 } | 353 } |
| 315 | 354 |
| 316 /// Collects field initializers all the way up the inheritance chain. | 355 /// Collects field initializers all the way up the inheritance chain. |
| 317 void _buildInitializers( | 356 void _buildInitializers( |
| 318 ir.Constructor constructor, Map<ir.Field, HInstruction> fieldValues) { | 357 ir.Constructor constructor, |
| 358 List<ir.Constructor> constructorChain, |
| 359 Map<ir.Field, HInstruction> fieldValues) { |
| 360 constructorChain.add(constructor); |
| 319 var foundSuperOrRedirectCall = false; | 361 var foundSuperOrRedirectCall = false; |
| 320 for (var initializer in constructor.initializers) { | 362 for (var initializer in constructor.initializers) { |
| 321 if (initializer is ir.SuperInitializer || | 363 if (initializer is ir.SuperInitializer || |
| 322 initializer is ir.RedirectingInitializer) { | 364 initializer is ir.RedirectingInitializer) { |
| 323 foundSuperOrRedirectCall = true; | 365 foundSuperOrRedirectCall = true; |
| 324 var superOrRedirectConstructor = initializer.target; | 366 var superOrRedirectConstructor = initializer.target; |
| 325 var arguments = _normalizeAndBuildArguments( | 367 var arguments = _normalizeAndBuildArguments( |
| 326 superOrRedirectConstructor.function, initializer.arguments); | 368 superOrRedirectConstructor.function, initializer.arguments); |
| 327 _buildInlinedInitializers( | 369 _buildInlinedInitializers(superOrRedirectConstructor, arguments, |
| 328 superOrRedirectConstructor, arguments, fieldValues); | 370 constructorChain, fieldValues); |
| 329 } else if (initializer is ir.FieldInitializer) { | 371 } else if (initializer is ir.FieldInitializer) { |
| 330 initializer.value.accept(this); | 372 initializer.value.accept(this); |
| 331 fieldValues[initializer.field] = pop(); | 373 fieldValues[initializer.field] = pop(); |
| 332 } | 374 } |
| 333 } | 375 } |
| 334 | 376 |
| 335 // Kernel always set the super initializer at the end, so if there was no | |
| 336 // super-call initializer, then the default constructor is called in the | |
| 337 // superclass. | |
| 338 if (!foundSuperOrRedirectCall) { | 377 if (!foundSuperOrRedirectCall) { |
| 339 if (constructor.enclosingClass != astAdapter.objectClass) { | 378 assert(constructor.enclosingClass == astAdapter.objectClass, |
| 340 var superclass = constructor.enclosingClass.superclass; | 379 'All constructors have super-constructor initializers, except Object()
'); |
| 341 var defaultConstructor = superclass.constructors | |
| 342 .firstWhere((c) => c.name.name == '', orElse: () => null); | |
| 343 if (defaultConstructor == null) { | |
| 344 compiler.reporter.internalError( | |
| 345 NO_LOCATION_SPANNABLE, 'Could not find default constructor.'); | |
| 346 } | |
| 347 _buildInlinedInitializers( | |
| 348 defaultConstructor, <HInstruction>[], fieldValues); | |
| 349 } | |
| 350 } | 380 } |
| 351 } | 381 } |
| 352 | 382 |
| 353 List<HInstruction> _normalizeAndBuildArguments( | 383 List<HInstruction> _normalizeAndBuildArguments( |
| 354 ir.FunctionNode function, ir.Arguments arguments) { | 384 ir.FunctionNode function, ir.Arguments arguments) { |
| 355 var signature = astAdapter.getFunctionSignature(function); | 385 var signature = astAdapter.getFunctionSignature(function); |
| 356 var builtArguments = <HInstruction>[]; | 386 var builtArguments = <HInstruction>[]; |
| 357 var positionalIndex = 0; | 387 var positionalIndex = 0; |
| 358 signature.forEachRequiredParameter((_) { | 388 signature.forEachRequiredParameter((_) { |
| 359 arguments.positional[positionalIndex++].accept(this); | 389 arguments.positional[positionalIndex++].accept(this); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 389 } | 419 } |
| 390 }); | 420 }); |
| 391 } | 421 } |
| 392 | 422 |
| 393 return builtArguments; | 423 return builtArguments; |
| 394 } | 424 } |
| 395 | 425 |
| 396 /// Inlines the given super [constructor]'s initializers by collecting its | 426 /// Inlines the given super [constructor]'s initializers by collecting its |
| 397 /// field values and building its constructor initializers. We visit super | 427 /// field values and building its constructor initializers. We visit super |
| 398 /// constructors all the way up to the [Object] constructor. | 428 /// constructors all the way up to the [Object] constructor. |
| 399 void _buildInlinedInitializers(ir.Constructor constructor, | 429 void _buildInlinedInitializers( |
| 400 List<HInstruction> arguments, Map<ir.Field, HInstruction> fieldValues) { | 430 ir.Constructor constructor, |
| 431 List<HInstruction> arguments, |
| 432 List<ir.Constructor> constructorChain, |
| 433 Map<ir.Field, HInstruction> fieldValues) { |
| 401 // TODO(het): Handle RTI if class needs it | 434 // TODO(het): Handle RTI if class needs it |
| 402 fieldValues.addAll(_collectFieldValues(constructor.enclosingClass)); | 435 fieldValues.addAll(_collectFieldValues(constructor.enclosingClass)); |
| 403 | 436 |
| 404 var signature = astAdapter.getFunctionSignature(constructor.function); | 437 var signature = astAdapter.getFunctionSignature(constructor.function); |
| 405 var index = 0; | 438 var index = 0; |
| 406 signature.orderedForEachParameter((ParameterElement parameter) { | 439 signature.orderedForEachParameter((ParameterElement parameter) { |
| 407 HInstruction argument = arguments[index++]; | 440 HInstruction argument = arguments[index++]; |
| 408 // Because we are inlining the initializer, we must update | 441 // Because we are inlining the initializer, we must update |
| 409 // what was given as parameter. This will be used in case | 442 // what was given as parameter. This will be used in case |
| 410 // there is a parameter check expression in the initializer. | 443 // there is a parameter check expression in the initializer. |
| 411 parameters[parameter] = argument; | 444 parameters[parameter] = argument; |
| 412 localsHandler.updateLocal(parameter, argument); | 445 localsHandler.updateLocal(parameter, argument); |
| 413 }); | 446 }); |
| 414 | 447 |
| 415 // TODO(het): set the locals handler state as if we were inlining the | 448 // TODO(het): set the locals handler state as if we were inlining the |
| 416 // constructor. | 449 // constructor. |
| 417 _buildInitializers(constructor, fieldValues); | 450 _buildInitializers(constructor, constructorChain, fieldValues); |
| 418 } | 451 } |
| 419 | 452 |
| 420 HTypeConversion buildFunctionTypeConversion( | 453 HTypeConversion buildFunctionTypeConversion( |
| 421 HInstruction original, ResolutionDartType type, int kind) { | 454 HInstruction original, ResolutionDartType type, int kind) { |
| 422 HInstruction reifiedType = buildFunctionType(type); | 455 HInstruction reifiedType = buildFunctionType(type); |
| 423 return new HTypeConversion.viaMethodOnType( | 456 return new HTypeConversion.viaMethodOnType( |
| 424 type, kind, original.instructionType, reifiedType, original); | 457 type, kind, original.instructionType, reifiedType, original); |
| 425 } | 458 } |
| 426 | 459 |
| 460 /// Builds generative constructor body. |
| 461 void buildConstructorBody(ir.Constructor constructor) { |
| 462 openFunction(); |
| 463 constructor.function.body.accept(this); |
| 464 closeFunction(); |
| 465 } |
| 466 |
| 427 /// Builds a SSA graph for FunctionNodes, found in FunctionExpressions and | 467 /// Builds a SSA graph for FunctionNodes, found in FunctionExpressions and |
| 428 /// Procedures. | 468 /// Procedures. |
| 429 void buildFunctionNode(ir.FunctionNode functionNode) { | 469 void buildFunctionNode(ir.FunctionNode functionNode) { |
| 430 openFunction(); | 470 openFunction(); |
| 431 if (functionNode.parent is ir.Procedure && | 471 if (functionNode.parent is ir.Procedure && |
| 432 (functionNode.parent as ir.Procedure).kind == | 472 (functionNode.parent as ir.Procedure).kind == |
| 433 ir.ProcedureKind.Factory) { | 473 ir.ProcedureKind.Factory) { |
| 434 _addClassTypeVariablesIfNeeded(functionNode.parent); | 474 _addClassTypeVariablesIfNeeded(functionNode.parent); |
| 435 } | 475 } |
| 436 functionNode.body.accept(this); | 476 functionNode.body.accept(this); |
| (...skipping 2590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3027 enterBlock.setBlockFlow( | 3067 enterBlock.setBlockFlow( |
| 3028 new HTryBlockInformation( | 3068 new HTryBlockInformation( |
| 3029 kernelBuilder.wrapStatementGraph(bodyGraph), | 3069 kernelBuilder.wrapStatementGraph(bodyGraph), |
| 3030 exception, | 3070 exception, |
| 3031 kernelBuilder.wrapStatementGraph(catchGraph), | 3071 kernelBuilder.wrapStatementGraph(catchGraph), |
| 3032 kernelBuilder.wrapStatementGraph(finallyGraph)), | 3072 kernelBuilder.wrapStatementGraph(finallyGraph)), |
| 3033 exitBlock); | 3073 exitBlock); |
| 3034 kernelBuilder.inTryStatement = previouslyInTryStatement; | 3074 kernelBuilder.inTryStatement = previouslyInTryStatement; |
| 3035 } | 3075 } |
| 3036 } | 3076 } |
| OLD | NEW |