Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2256)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2920753002: Use entities as keys rather than IR nodes (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698