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

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

Issue 1196433002: Create and test source mapping for invocations. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Rebased Created 5 years, 5 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
« no previous file with comments | « pkg/compiler/lib/src/source_file_provider.dart ('k') | pkg/compiler/lib/src/ssa/codegen.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of ssa; 5 part of ssa;
6 6
7 class SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 SsaCodeGeneratorTask generator; 8 SsaCodeGeneratorTask generator;
9 SsaBuilderTask builder; 9 SsaBuilderTask builder;
10 SsaOptimizerTask optimizer; 10 SsaOptimizerTask optimizer;
11 11
12 SsaFunctionCompiler(JavaScriptBackend backend, 12 SsaFunctionCompiler(JavaScriptBackend backend,
13 SourceInformationFactory sourceInformationFactory) 13 SourceInformationStrategy sourceInformationFactory)
14 : generator = new SsaCodeGeneratorTask(backend, sourceInformationFactory), 14 : generator = new SsaCodeGeneratorTask(backend, sourceInformationFactory),
15 builder = new SsaBuilderTask(backend, sourceInformationFactory), 15 builder = new SsaBuilderTask(backend, sourceInformationFactory),
16 optimizer = new SsaOptimizerTask(backend); 16 optimizer = new SsaOptimizerTask(backend);
17 17
18 /// Generates JavaScript code for `work.element`. 18 /// Generates JavaScript code for `work.element`.
19 /// Using the ssa builder, optimizer and codegenerator. 19 /// Using the ssa builder, optimizer and codegenerator.
20 js.Fun compile(CodegenWorkItem work) { 20 js.Fun compile(CodegenWorkItem work) {
21 HGraph graph = builder.build(work); 21 HGraph graph = builder.build(work);
22 optimizer.optimize(work, graph); 22 optimizer.optimize(work, graph);
23 Element element = work.element; 23 Element element = work.element;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 final ExecutableElement executableContext; 90 final ExecutableElement executableContext;
91 91
92 SyntheticLocal(this.name, this.executableContext); 92 SyntheticLocal(this.name, this.executableContext);
93 93
94 toString() => 'SyntheticLocal($name)'; 94 toString() => 'SyntheticLocal($name)';
95 } 95 }
96 96
97 class SsaBuilderTask extends CompilerTask { 97 class SsaBuilderTask extends CompilerTask {
98 final CodeEmitterTask emitter; 98 final CodeEmitterTask emitter;
99 final JavaScriptBackend backend; 99 final JavaScriptBackend backend;
100 final SourceInformationFactory sourceInformationFactory; 100 final SourceInformationStrategy sourceInformationFactory;
101 101
102 String get name => 'SSA builder'; 102 String get name => 'SSA builder';
103 103
104 SsaBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) 104 SsaBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory)
105 : emitter = backend.emitter, 105 : emitter = backend.emitter,
106 backend = backend, 106 backend = backend,
107 super(backend.compiler); 107 super(backend.compiler);
108 108
109 HGraph build(CodegenWorkItem work) { 109 HGraph build(CodegenWorkItem work) {
110 return measure(() { 110 return measure(() {
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 473
474 bool isUsedInTryOrGenerator(Local local) { 474 bool isUsedInTryOrGenerator(Local local) {
475 return closureData.variablesUsedInTryOrGenerator.contains(local); 475 return closureData.variablesUsedInTryOrGenerator.contains(local);
476 } 476 }
477 477
478 /** 478 /**
479 * Returns an [HInstruction] for the given element. If the element is 479 * Returns an [HInstruction] for the given element. If the element is
480 * boxed or stored in a closure then the method generates code to retrieve 480 * boxed or stored in a closure then the method generates code to retrieve
481 * the value. 481 * the value.
482 */ 482 */
483 HInstruction readLocal(Local local) { 483 HInstruction readLocal(Local local,
484 {SourceInformation sourceInformation}) {
484 if (isAccessedDirectly(local)) { 485 if (isAccessedDirectly(local)) {
485 if (directLocals[local] == null) { 486 if (directLocals[local] == null) {
486 if (local is TypeVariableElement) { 487 if (local is TypeVariableElement) {
487 builder.compiler.internalError(builder.compiler.currentElement, 488 builder.compiler.internalError(builder.compiler.currentElement,
488 "Runtime type information not available for $local."); 489 "Runtime type information not available for $local.");
489 } else { 490 } else {
490 builder.compiler.internalError(local, 491 builder.compiler.internalError(local,
491 "Cannot find value $local."); 492 "Cannot find value $local.");
492 } 493 }
493 } 494 }
494 return directLocals[local]; 495 return directLocals[local];
495 } else if (isStoredInClosureField(local)) { 496 } else if (isStoredInClosureField(local)) {
496 ClosureFieldElement redirect = redirectionMapping[local]; 497 ClosureFieldElement redirect = redirectionMapping[local];
497 HInstruction receiver = readLocal(closureData.closureElement); 498 HInstruction receiver = readLocal(closureData.closureElement);
498 TypeMask type = local is BoxLocal 499 TypeMask type = local is BoxLocal
499 ? builder.backend.nonNullType 500 ? builder.backend.nonNullType
500 : builder.getTypeOfCapturedVariable(redirect); 501 : builder.getTypeOfCapturedVariable(redirect);
501 HInstruction fieldGet = new HFieldGet(redirect, receiver, type); 502 HInstruction fieldGet = new HFieldGet(redirect, receiver, type);
502 builder.add(fieldGet); 503 builder.add(fieldGet);
503 return fieldGet; 504 return fieldGet..sourceInformation = sourceInformation;
504 } else if (isBoxed(local)) { 505 } else if (isBoxed(local)) {
505 BoxFieldElement redirect = redirectionMapping[local]; 506 BoxFieldElement redirect = redirectionMapping[local];
506 // In the function that declares the captured variable the box is 507 // In the function that declares the captured variable the box is
507 // accessed as direct local. Inside the nested closure the box is 508 // accessed as direct local. Inside the nested closure the box is
508 // accessed through a closure-field. 509 // accessed through a closure-field.
509 // Calling [readLocal] makes sure we generate the correct code to get 510 // Calling [readLocal] makes sure we generate the correct code to get
510 // the box. 511 // the box.
511 HInstruction box = readLocal(redirect.box); 512 HInstruction box = readLocal(redirect.box);
512 HInstruction lookup = new HFieldGet( 513 HInstruction lookup = new HFieldGet(
513 redirect, box, builder.getTypeOfCapturedVariable(redirect)); 514 redirect, box, builder.getTypeOfCapturedVariable(redirect));
514 builder.add(lookup); 515 builder.add(lookup);
515 return lookup; 516 return lookup..sourceInformation = sourceInformation;
516 } else { 517 } else {
517 assert(isUsedInTryOrGenerator(local)); 518 assert(isUsedInTryOrGenerator(local));
518 HLocalValue localValue = getLocal(local); 519 HLocalValue localValue = getLocal(local);
519 HInstruction instruction = new HLocalGet( 520 HInstruction instruction = new HLocalGet(
520 local, localValue, builder.backend.dynamicType); 521 local, localValue, builder.backend.dynamicType);
521 builder.add(instruction); 522 builder.add(instruction);
522 return instruction; 523 return instruction..sourceInformation = sourceInformation;
523 } 524 }
524 } 525 }
525 526
526 HInstruction readThis() { 527 HInstruction readThis() {
527 HInstruction res = readLocal(closureData.thisLocal); 528 HInstruction res = readLocal(closureData.thisLocal);
528 if (res.instructionType == null) { 529 if (res.instructionType == null) {
529 res.instructionType = builder.getTypeOfThis(); 530 res.instructionType = builder.getTypeOfThis();
530 } 531 }
531 return res; 532 return res;
532 } 533 }
533 534
534 HLocalValue getLocal(Local local) { 535 HLocalValue getLocal(Local local,
536 {SourceInformation sourceInformation}) {
535 // If the element is a parameter, we already have a 537 // If the element is a parameter, we already have a
536 // HParameterValue for it. We cannot create another one because 538 // HParameterValue for it. We cannot create another one because
537 // it could then have another name than the real parameter. And 539 // it could then have another name than the real parameter. And
538 // the other one would not know it is just a copy of the real 540 // the other one would not know it is just a copy of the real
539 // parameter. 541 // parameter.
540 if (local is ParameterElement) return builder.parameters[local]; 542 if (local is ParameterElement) return builder.parameters[local];
541 543
542 return builder.activationVariables.putIfAbsent(local, () { 544 return builder.activationVariables.putIfAbsent(local, () {
543 JavaScriptBackend backend = builder.backend; 545 JavaScriptBackend backend = builder.backend;
544 HLocalValue localValue = new HLocalValue(local, backend.nonNullType); 546 HLocalValue localValue = new HLocalValue(local, backend.nonNullType)
547 ..sourceInformation = sourceInformation;
545 builder.graph.entry.addAtExit(localValue); 548 builder.graph.entry.addAtExit(localValue);
546 return localValue; 549 return localValue;
547 }); 550 });
548 } 551 }
549 552
550 Local getTypeVariableAsLocal(TypeVariableType type) { 553 Local getTypeVariableAsLocal(TypeVariableType type) {
551 return typeVariableLocals.putIfAbsent(type, () { 554 return typeVariableLocals.putIfAbsent(type, () {
552 return new TypeVariableLocal(type, executableContext); 555 return new TypeVariableLocal(type, executableContext);
553 }); 556 });
554 } 557 }
555 558
556 /** 559 /**
557 * Sets the [element] to [value]. If the element is boxed or stored in a 560 * Sets the [element] to [value]. If the element is boxed or stored in a
558 * closure then the method generates code to set the value. 561 * closure then the method generates code to set the value.
559 */ 562 */
560 void updateLocal(Local local, HInstruction value) { 563 void updateLocal(Local local, HInstruction value,
564 {SourceInformation sourceInformation}) {
561 assert(!isStoredInClosureField(local)); 565 assert(!isStoredInClosureField(local));
562 if (isAccessedDirectly(local)) { 566 if (isAccessedDirectly(local)) {
563 directLocals[local] = value; 567 directLocals[local] = value;
564 } else if (isBoxed(local)) { 568 } else if (isBoxed(local)) {
565 BoxFieldElement redirect = redirectionMapping[local]; 569 BoxFieldElement redirect = redirectionMapping[local];
566 // The box itself could be captured, or be local. A local variable that 570 // The box itself could be captured, or be local. A local variable that
567 // is captured will be boxed, but the box itself will be a local. 571 // is captured will be boxed, but the box itself will be a local.
568 // Inside the closure the box is stored in a closure-field and cannot 572 // Inside the closure the box is stored in a closure-field and cannot
569 // be accessed directly. 573 // be accessed directly.
570 HInstruction box = readLocal(redirect.box); 574 HInstruction box = readLocal(redirect.box);
571 builder.add(new HFieldSet(redirect, box, value)); 575 builder.add(new HFieldSet(redirect, box, value)
576 ..sourceInformation = sourceInformation);
572 } else { 577 } else {
573 assert(isUsedInTryOrGenerator(local)); 578 assert(isUsedInTryOrGenerator(local));
574 HLocalValue localValue = getLocal(local); 579 HLocalValue localValue = getLocal(local);
575 builder.add(new HLocalSet(local, localValue, value)); 580 builder.add(new HLocalSet(local, localValue, value)
581 ..sourceInformation = sourceInformation);
576 } 582 }
577 } 583 }
578 584
579 /** 585 /**
580 * This function, startLoop, must be called before visiting any children of 586 * This function, startLoop, must be called before visiting any children of
581 * the loop. In particular it needs to be called before executing the 587 * the loop. In particular it needs to be called before executing the
582 * initializers. 588 * initializers.
583 * 589 *
584 * The [LocalsHandler] will make the boxes and updates at the right moment. 590 * The [LocalsHandler] will make the boxes and updates at the right moment.
585 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] 591 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates]
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 /// Returns `true` if the current element is an `async` function. 1118 /// Returns `true` if the current element is an `async` function.
1113 bool get isBuildingAsyncFunction { 1119 bool get isBuildingAsyncFunction {
1114 Element element = sourceElement; 1120 Element element = sourceElement;
1115 return (element is FunctionElement && 1121 return (element is FunctionElement &&
1116 element.asyncMarker == AsyncMarker.ASYNC); 1122 element.asyncMarker == AsyncMarker.ASYNC);
1117 } 1123 }
1118 1124
1119 SsaBuilder(JavaScriptBackend backend, 1125 SsaBuilder(JavaScriptBackend backend,
1120 CodegenWorkItem work, 1126 CodegenWorkItem work,
1121 this.nativeEmitter, 1127 this.nativeEmitter,
1122 SourceInformationFactory sourceInformationFactory) 1128 SourceInformationStrategy sourceInformationFactory)
1123 : this.compiler = backend.compiler, 1129 : this.compiler = backend.compiler,
1124 this.backend = backend, 1130 this.backend = backend,
1125 this.constantSystem = backend.constantSystem, 1131 this.constantSystem = backend.constantSystem,
1126 this.work = work, 1132 this.work = work,
1127 this.rti = backend.rti, 1133 this.rti = backend.rti,
1128 this.elements = work.resolutionTree { 1134 this.elements = work.resolutionTree {
1129 localsHandler = new LocalsHandler(this, work.element, null); 1135 localsHandler = new LocalsHandler(this, work.element, null);
1130 sourceElementStack.add(work.element); 1136 sourceElementStack.add(work.element);
1131 sourceInformationBuilder = 1137 sourceInformationBuilder =
1132 sourceInformationFactory.forContext(work.element.implementation); 1138 sourceInformationFactory.createBuilderForContext(
1139 work.element.implementation);
1133 } 1140 }
1134 1141
1135 @override 1142 @override
1136 SemanticSendVisitor get sendVisitor => this; 1143 SemanticSendVisitor get sendVisitor => this;
1137 1144
1138 @override 1145 @override
1139 void visitNode(ast.Node node) { 1146 void visitNode(ast.Node node) {
1140 internalError(node, "Unhandled node: $node"); 1147 internalError(node, "Unhandled node: $node");
1141 } 1148 }
1142 1149
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 assert(elements.getFunctionDefinition(function) != null); 1635 assert(elements.getFunctionDefinition(function) != null);
1629 openFunction(functionElement, function); 1636 openFunction(functionElement, function);
1630 String name = functionElement.name; 1637 String name = functionElement.name;
1631 // If [functionElement] is `operator==` we explicitely add a null check at 1638 // If [functionElement] is `operator==` we explicitely add a null check at
1632 // the beginning of the method. This is to avoid having call sites do the 1639 // the beginning of the method. This is to avoid having call sites do the
1633 // null check. 1640 // null check.
1634 if (name == '==') { 1641 if (name == '==') {
1635 if (!backend.operatorEqHandlesNullArgument(functionElement)) { 1642 if (!backend.operatorEqHandlesNullArgument(functionElement)) {
1636 handleIf( 1643 handleIf(
1637 function, 1644 function,
1638 () { 1645 visitCondition: () {
1639 HParameterValue parameter = parameters.values.first; 1646 HParameterValue parameter = parameters.values.first;
1640 push(new HIdentity( 1647 push(new HIdentity(
1641 parameter, graph.addConstantNull(compiler), null, 1648 parameter, graph.addConstantNull(compiler), null,
1642 backend.boolType)); 1649 backend.boolType));
1643 }, 1650 },
1644 () { 1651 visitThen: () {
1652 // TODO(johnniwinther): Add source information.
1645 closeAndGotoExit(new HReturn( 1653 closeAndGotoExit(new HReturn(
1646 graph.addConstantBool(false, compiler))); 1654 graph.addConstantBool(false, compiler),
1655 null));
1647 }, 1656 },
1648 null); 1657 visitElse: null);
1649 } 1658 }
1650 } 1659 }
1651 function.body.accept(this); 1660 function.body.accept(this);
1652 return closeFunction(); 1661 return closeFunction();
1653 } 1662 }
1654 1663
1655 HGraph buildCheckedSetter(VariableElement field) { 1664 HGraph buildCheckedSetter(VariableElement field) {
1656 openFunction(field, field.node); 1665 openFunction(field, field.node);
1657 HInstruction thisInstruction = localsHandler.readThis(); 1666 HInstruction thisInstruction = localsHandler.readThis();
1658 // Use dynamic type because the type computed by the inferrer is 1667 // Use dynamic type because the type computed by the inferrer is
1659 // narrowed to the type annotation. 1668 // narrowed to the type annotation.
1660 HInstruction parameter = new HParameterValue(field, backend.dynamicType); 1669 HInstruction parameter = new HParameterValue(field, backend.dynamicType);
1661 // Add the parameter as the last instruction of the entry block. 1670 // Add the parameter as the last instruction of the entry block.
1662 // If the method is intercepted, we want the actual receiver 1671 // If the method is intercepted, we want the actual receiver
1663 // to be the first parameter. 1672 // to be the first parameter.
1664 graph.entry.addBefore(graph.entry.last, parameter); 1673 graph.entry.addBefore(graph.entry.last, parameter);
1665 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type); 1674 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type);
1666 add(new HFieldSet(field, thisInstruction, value)); 1675 add(new HFieldSet(field, thisInstruction, value));
1667 return closeFunction(); 1676 return closeFunction();
1668 } 1677 }
1669 1678
1670 HGraph buildLazyInitializer(VariableElement variable) { 1679 HGraph buildLazyInitializer(VariableElement variable) {
1671 inLazyInitializerExpression = true; 1680 inLazyInitializerExpression = true;
1672 ast.Node node = variable.node; 1681 ast.VariableDefinitions node = variable.node;
1673 openFunction(variable, node); 1682 openFunction(variable, node);
1674 assert(invariant(variable, variable.initializer != null, 1683 assert(invariant(variable, variable.initializer != null,
1675 message: "Non-constant variable $variable has no initializer.")); 1684 message: "Non-constant variable $variable has no initializer."));
1676 visit(variable.initializer); 1685 visit(variable.initializer);
1677 HInstruction value = pop(); 1686 HInstruction value = pop();
1678 value = potentiallyCheckOrTrustType(value, variable.type); 1687 value = potentiallyCheckOrTrustType(value, variable.type);
1679 closeAndGotoExit(new HReturn(value)); 1688 ast.SendSet sendSet = node.definitions.nodes.head;
1689 closeAndGotoExit(new HReturn(value,
1690 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)));
1680 return closeFunction(); 1691 return closeFunction();
1681 } 1692 }
1682 1693
1683 /** 1694 /**
1684 * Returns the constructor body associated with the given constructor or 1695 * Returns the constructor body associated with the given constructor or
1685 * creates a new constructor body, if none can be found. 1696 * creates a new constructor body, if none can be found.
1686 * 1697 *
1687 * Returns [:null:] if the constructor does not have a body. 1698 * Returns [:null:] if the constructor does not have a body.
1688 */ 1699 */
1689 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 1700 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
2172 if (!currentInlinedInstantiations.isEmpty) { 2183 if (!currentInlinedInstantiations.isEmpty) {
2173 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); 2184 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations);
2174 } 2185 }
2175 2186
2176 HInstruction newObject; 2187 HInstruction newObject;
2177 if (!isNativeUpgradeFactory) { 2188 if (!isNativeUpgradeFactory) {
2178 newObject = new HForeignNew(classElement, 2189 newObject = new HForeignNew(classElement,
2179 ssaType, 2190 ssaType,
2180 constructorArguments, 2191 constructorArguments,
2181 instantiatedTypes); 2192 instantiatedTypes);
2193 if (function != null) {
2194 newObject.sourceInformation =
2195 sourceInformationBuilder.buildGeneric(function);
2196 }
2182 add(newObject); 2197 add(newObject);
2183 } else { 2198 } else {
2184 // Bulk assign to the initialized fields. 2199 // Bulk assign to the initialized fields.
2185 newObject = graph.explicitReceiverParameter; 2200 newObject = graph.explicitReceiverParameter;
2186 // Null guard ensures an error if we are being called from an explicit 2201 // Null guard ensures an error if we are being called from an explicit
2187 // 'new' of the constructor instead of via an upgrade. It is optimized out 2202 // 'new' of the constructor instead of via an upgrade. It is optimized out
2188 // if there are field initializers. 2203 // if there are field initializers.
2189 add(new HFieldGet( 2204 add(new HFieldGet(
2190 null, newObject, backend.dynamicType, isAssignable: false)); 2205 null, newObject, backend.dynamicType, isAssignable: false));
2191 for (int i = 0; i < fields.length; i++) { 2206 for (int i = 0; i < fields.length; i++) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 pop(); 2340 pop();
2326 } else { 2341 } else {
2327 HInvokeConstructorBody invoke = new HInvokeConstructorBody( 2342 HInvokeConstructorBody invoke = new HInvokeConstructorBody(
2328 body.declaration, bodyCallInputs, backend.nonNullType); 2343 body.declaration, bodyCallInputs, backend.nonNullType);
2329 invoke.sideEffects = 2344 invoke.sideEffects =
2330 compiler.world.getSideEffectsOfElement(constructor); 2345 compiler.world.getSideEffectsOfElement(constructor);
2331 add(invoke); 2346 add(invoke);
2332 } 2347 }
2333 } 2348 }
2334 if (inliningStack.isEmpty) { 2349 if (inliningStack.isEmpty) {
2335 closeAndGotoExit(new HReturn(newObject)); 2350 closeAndGotoExit(new HReturn(newObject,
2351 sourceInformationBuilder.buildImplicitReturn(functionElement)));
2336 return closeFunction(); 2352 return closeFunction();
2337 } else { 2353 } else {
2338 localsHandler.updateLocal(returnLocal, newObject); 2354 localsHandler.updateLocal(returnLocal, newObject);
2339 return null; 2355 return null;
2340 } 2356 }
2341 } 2357 }
2342 2358
2343 /** 2359 /**
2344 * Documentation wanted -- johnniwinther 2360 * Documentation wanted -- johnniwinther
2345 * 2361 *
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2627 inExpressionOfThrow = old; 2643 inExpressionOfThrow = old;
2628 } 2644 }
2629 } 2645 }
2630 2646
2631 visitExpressionStatement(ast.ExpressionStatement node) { 2647 visitExpressionStatement(ast.ExpressionStatement node) {
2632 if (!isReachable) return; 2648 if (!isReachable) return;
2633 ast.Throw throwExpression = node.expression.asThrow(); 2649 ast.Throw throwExpression = node.expression.asThrow();
2634 if (throwExpression != null && inliningStack.isEmpty) { 2650 if (throwExpression != null && inliningStack.isEmpty) {
2635 visitThrowExpression(throwExpression.expression); 2651 visitThrowExpression(throwExpression.expression);
2636 handleInTryStatement(); 2652 handleInTryStatement();
2637 closeAndGotoExit(new HThrow(pop())); 2653 closeAndGotoExit(
2654 new HThrow(pop(), sourceInformationBuilder.buildThrow(node)));
2638 } else { 2655 } else {
2639 visit(node.expression); 2656 visit(node.expression);
2640 pop(); 2657 pop();
2641 } 2658 }
2642 } 2659 }
2643 2660
2644 /** 2661 /**
2645 * Creates a new loop-header block. The previous [current] block 2662 * Creates a new loop-header block. The previous [current] block
2646 * is closed with an [HGoto] and replaced by the newly created block. 2663 * is closed with an [HGoto] and replaced by the newly created block.
2647 * Also notifies the locals handler that we're entering a loop. 2664 * Also notifies the locals handler that we're entering a loop.
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
3122 List<HInstruction> capturedVariables = <HInstruction>[]; 3139 List<HInstruction> capturedVariables = <HInstruction>[];
3123 closureClassElement.closureFields.forEach((ClosureFieldElement field) { 3140 closureClassElement.closureFields.forEach((ClosureFieldElement field) {
3124 Local capturedLocal = 3141 Local capturedLocal =
3125 nestedClosureData.getLocalVariableForClosureField(field); 3142 nestedClosureData.getLocalVariableForClosureField(field);
3126 assert(capturedLocal != null); 3143 assert(capturedLocal != null);
3127 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 3144 capturedVariables.add(localsHandler.readLocal(capturedLocal));
3128 }); 3145 });
3129 3146
3130 TypeMask type = 3147 TypeMask type =
3131 new TypeMask.nonNullExact(compiler.functionClass, compiler.world); 3148 new TypeMask.nonNullExact(compiler.functionClass, compiler.world);
3132 push(new HForeignNew(closureClassElement, type, capturedVariables)); 3149 push(new HForeignNew(closureClassElement, type, capturedVariables)
3150 ..sourceInformation = sourceInformationBuilder.buildGeneric(node));
3133 3151
3134 Element methodElement = nestedClosureData.closureElement; 3152 Element methodElement = nestedClosureData.closureElement;
3135 registry.registerInstantiatedClosure(methodElement); 3153 registry.registerInstantiatedClosure(methodElement);
3136 } 3154 }
3137 3155
3138 visitFunctionDeclaration(ast.FunctionDeclaration node) { 3156 visitFunctionDeclaration(ast.FunctionDeclaration node) {
3139 assert(isReachable); 3157 assert(isReachable);
3140 visit(node.function); 3158 visit(node.function);
3141 LocalFunctionElement localFunction = 3159 LocalFunctionElement localFunction =
3142 elements.getFunctionDefinition(node.function); 3160 elements.getFunctionDefinition(node.function);
3143 localsHandler.updateLocal(localFunction, pop()); 3161 localsHandler.updateLocal(localFunction, pop());
3144 } 3162 }
3145 3163
3146 @override 3164 @override
3147 void visitThisGet(ast.Identifier node, [_]) { 3165 void visitThisGet(ast.Identifier node, [_]) {
3148 stack.add(localsHandler.readThis()); 3166 stack.add(localsHandler.readThis());
3149 } 3167 }
3150 3168
3151 visitIdentifier(ast.Identifier node) { 3169 visitIdentifier(ast.Identifier node) {
3152 if (node.isThis()) { 3170 if (node.isThis()) {
3153 visitThisGet(node); 3171 visitThisGet(node);
3154 } else { 3172 } else {
3155 compiler.internalError(node, 3173 compiler.internalError(node,
3156 "SsaFromAstMixin.visitIdentifier on non-this."); 3174 "SsaFromAstMixin.visitIdentifier on non-this.");
3157 } 3175 }
3158 } 3176 }
3159 3177
3160 visitIf(ast.If node) { 3178 visitIf(ast.If node) {
3161 assert(isReachable); 3179 assert(isReachable);
3162 handleIf(node, 3180 handleIf(
3163 () => visit(node.condition), 3181 node,
3164 () => visit(node.thenPart), 3182 visitCondition: () => visit(node.condition),
3165 node.elsePart != null ? () => visit(node.elsePart) : null); 3183 visitThen: () => visit(node.thenPart),
3184 visitElse: node.elsePart != null ? () => visit(node.elsePart) : null,
3185 sourceInformation: sourceInformationBuilder.buildIf(node));
3166 } 3186 }
3167 3187
3168 void handleIf(ast.Node diagnosticNode, 3188 void handleIf(ast.Node diagnosticNode,
3169 void visitCondition(), void visitThen(), void visitElse()) { 3189 {void visitCondition(),
3190 void visitThen(),
3191 void visitElse(),
3192 SourceInformation sourceInformation}) {
3170 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, diagnosticNode); 3193 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, diagnosticNode);
3171 branchBuilder.handleIf(visitCondition, visitThen, visitElse); 3194 branchBuilder.handleIf(
3195 visitCondition, visitThen, visitElse,
3196 sourceInformation: sourceInformation);
3172 } 3197 }
3173 3198
3174 @override 3199 @override
3175 void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) { 3200 void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
3176 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); 3201 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
3177 brancher.handleIfNull(() => visit(left), () => visit(right)); 3202 brancher.handleIfNull(() => visit(left), () => visit(right));
3178 } 3203 }
3179 3204
3180 @override 3205 @override
3181 void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) { 3206 void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) {
(...skipping 10 matching lines...) Expand all
3192 branchBuilder.handleLogicalAndOrWithLeftNode( 3217 branchBuilder.handleLogicalAndOrWithLeftNode(
3193 left, 3218 left,
3194 () { visit(right); }, 3219 () { visit(right); },
3195 isAnd: false); 3220 isAnd: false);
3196 } 3221 }
3197 3222
3198 @override 3223 @override
3199 void visitNot(ast.Send node, ast.Node expression, _) { 3224 void visitNot(ast.Send node, ast.Node expression, _) {
3200 assert(node.argumentsNode is ast.Prefix); 3225 assert(node.argumentsNode is ast.Prefix);
3201 visit(expression); 3226 visit(expression);
3202 HNot not = new HNot(popBoolified(), backend.boolType); 3227 SourceInformation sourceInformation =
3203 pushWithPosition(not, node); 3228 sourceInformationBuilder.buildGeneric(node);
3229 push(new HNot(popBoolified(), backend.boolType)
3230 ..sourceInformation = sourceInformation);
3204 } 3231 }
3205 3232
3206 @override 3233 @override
3207 void visitUnary(ast.Send node, 3234 void visitUnary(ast.Send node,
3208 UnaryOperator operator, 3235 UnaryOperator operator,
3209 ast.Node expression,_) { 3236 ast.Node expression,_) {
3210 assert(node.argumentsNode is ast.Prefix); 3237 assert(node.argumentsNode is ast.Prefix);
3211 HInstruction operand = visitAndPop(expression); 3238 HInstruction operand = visitAndPop(expression);
3212 3239
3213 // See if we can constant-fold right away. This avoids rewrites later on. 3240 // See if we can constant-fold right away. This avoids rewrites later on.
3214 if (operand is HConstant) { 3241 if (operand is HConstant) {
3215 UnaryOperation operation = constantSystem.lookupUnary(operator); 3242 UnaryOperation operation = constantSystem.lookupUnary(operator);
3216 HConstant constant = operand; 3243 HConstant constant = operand;
3217 ConstantValue folded = operation.fold(constant.constant); 3244 ConstantValue folded = operation.fold(constant.constant);
3218 if (folded != null) { 3245 if (folded != null) {
3219 stack.add(graph.addConstant(folded, compiler)); 3246 stack.add(graph.addConstant(folded, compiler));
3220 return; 3247 return;
3221 } 3248 }
3222 } 3249 }
3223 3250
3224 pushInvokeDynamic( 3251 pushInvokeDynamic(
3225 node, 3252 node,
3226 elements.getSelector(node), 3253 elements.getSelector(node),
3227 elements.getTypeMask(node), 3254 elements.getTypeMask(node),
3228 [operand]); 3255 [operand],
3256 sourceInformation: sourceInformationBuilder.buildGeneric(node));
3229 } 3257 }
3230 3258
3231 @override 3259 @override
3232 void visitBinary(ast.Send node, 3260 void visitBinary(ast.Send node,
3233 ast.Node left, 3261 ast.Node left,
3234 BinaryOperator operator, 3262 BinaryOperator operator,
3235 ast.Node right, _) { 3263 ast.Node right, _) {
3236 handleBinary(node, left, right); 3264 handleBinary(node, left, right);
3237 } 3265 }
3238 3266
(...skipping 13 matching lines...) Expand all
3252 pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector); 3280 pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector);
3253 } 3281 }
3254 3282
3255 void handleBinary(ast.Send node, ast.Node left, ast.Node right) { 3283 void handleBinary(ast.Send node, ast.Node left, ast.Node right) {
3256 visitBinarySend( 3284 visitBinarySend(
3257 visitAndPop(left), 3285 visitAndPop(left),
3258 visitAndPop(right), 3286 visitAndPop(right),
3259 elements.getSelector(node), 3287 elements.getSelector(node),
3260 elements.getTypeMask(node), 3288 elements.getTypeMask(node),
3261 node, 3289 node,
3262 location: node.selector); 3290 sourceInformation:
3291 sourceInformationBuilder.buildGeneric(node.selector));
3263 } 3292 }
3264 3293
3265 /// TODO(johnniwinther): Merge [visitBinarySend] with [handleBinary] and 3294 /// TODO(johnniwinther): Merge [visitBinarySend] with [handleBinary] and
3266 /// remove use of [location] for source information. 3295 /// remove use of [location] for source information.
3267 void visitBinarySend(HInstruction left, 3296 void visitBinarySend(HInstruction left,
3268 HInstruction right, 3297 HInstruction right,
3269 Selector selector, 3298 Selector selector,
3270 TypeMask mask, 3299 TypeMask mask,
3271 ast.Send send, 3300 ast.Send send,
3272 {ast.Node location}) { 3301 {SourceInformation sourceInformation}) {
3273 pushInvokeDynamic(send, selector, mask, [left, right], location: location); 3302 pushInvokeDynamic(send, selector, mask, [left, right],
3303 sourceInformation: sourceInformation);
3274 } 3304 }
3275 3305
3276 HInstruction generateInstanceSendReceiver(ast.Send send) { 3306 HInstruction generateInstanceSendReceiver(ast.Send send) {
3277 assert(Elements.isInstanceSend(send, elements)); 3307 assert(Elements.isInstanceSend(send, elements));
3278 if (send.receiver == null) { 3308 if (send.receiver == null) {
3279 return localsHandler.readThis(); 3309 return localsHandler.readThis();
3280 } 3310 }
3281 visit(send.receiver); 3311 visit(send.receiver);
3282 return pop(); 3312 return pop();
3283 } 3313 }
3284 3314
3285 String noSuchMethodTargetSymbolString(Element error, [String prefix]) { 3315 String noSuchMethodTargetSymbolString(Element error, [String prefix]) {
3286 String result = error.name; 3316 String result = error.name;
3287 if (prefix == "set") return "$result="; 3317 if (prefix == "set") return "$result=";
3288 return result; 3318 return result;
3289 } 3319 }
3290 3320
3291 /** 3321 /**
3292 * Returns a set of interceptor classes that contain the given 3322 * Returns a set of interceptor classes that contain the given
3293 * [selector]. 3323 * [selector].
3294 */ 3324 */
3295 void generateInstanceGetterWithCompiledReceiver( 3325 void generateInstanceGetterWithCompiledReceiver(
3296 ast.Send send, 3326 ast.Send send,
3297 Selector selector, 3327 Selector selector,
3298 TypeMask mask, 3328 TypeMask mask,
3299 HInstruction receiver) { 3329 HInstruction receiver) {
3300 assert(Elements.isInstanceSend(send, elements)); 3330 assert(Elements.isInstanceSend(send, elements));
3301 assert(selector.isGetter); 3331 assert(selector.isGetter);
3302 pushInvokeDynamic(send, selector, mask, [receiver]); 3332 pushInvokeDynamic(send, selector, mask, [receiver],
3333 sourceInformation: sourceInformationBuilder.buildGet(send));
3303 } 3334 }
3304 3335
3305 /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. 3336 /// Inserts a call to checkDeferredIsLoaded for [prefixElement].
3306 /// If [prefixElement] is [null] ndo nothing. 3337 /// If [prefixElement] is [null] ndo nothing.
3307 void generateIsDeferredLoadedCheckIfNeeded(PrefixElement prefixElement, 3338 void generateIsDeferredLoadedCheckIfNeeded(PrefixElement prefixElement,
3308 ast.Node location) { 3339 ast.Node location) {
3309 if (prefixElement == null) return; 3340 if (prefixElement == null) return;
3310 String loadId = 3341 String loadId =
3311 compiler.deferredLoadTask.importDeferName[prefixElement.deferredImport]; 3342 compiler.deferredLoadTask.importDeferName[prefixElement.deferredImport];
3312 HInstruction loadIdConstant = addConstantString(loadId); 3343 HInstruction loadIdConstant = addConstantString(loadId);
3313 String uri = prefixElement.deferredImport.uri.dartString.slowToString(); 3344 String uri = prefixElement.deferredImport.uri.dartString.slowToString();
3314 HInstruction uriConstant = addConstantString(uri); 3345 HInstruction uriConstant = addConstantString(uri);
3315 Element helper = backend.getCheckDeferredIsLoaded(); 3346 Element helper = backend.getCheckDeferredIsLoaded();
3316 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); 3347 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]);
3317 pop(); 3348 pop();
3318 } 3349 }
3319 3350
3320 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that 3351 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that
3321 /// resolves to a deferred library. 3352 /// resolves to a deferred library.
3322 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { 3353 void generateIsDeferredLoadedCheckOfSend(ast.Send node) {
3323 generateIsDeferredLoadedCheckIfNeeded( 3354 generateIsDeferredLoadedCheckIfNeeded(
3324 compiler.deferredLoadTask.deferredPrefixElement(node, elements), 3355 compiler.deferredLoadTask.deferredPrefixElement(node, elements),
3325 node); 3356 node);
3326 } 3357 }
3327 3358
3328 void handleInvalidStaticGet(ast.Send node, Element element) { 3359 void handleInvalidStaticGet(ast.Send node, Element element) {
3360 SourceInformation sourceInformation =
3361 sourceInformationBuilder.buildGet(node);
3329 generateThrowNoSuchMethod( 3362 generateThrowNoSuchMethod(
3330 node, 3363 node,
3331 noSuchMethodTargetSymbolString(element, 'get'), 3364 noSuchMethodTargetSymbolString(element, 'get'),
3332 argumentNodes: const Link<ast.Node>()); 3365 argumentNodes: const Link<ast.Node>(),
3366 sourceInformation: sourceInformation);
3333 } 3367 }
3334 3368
3335 /// Generate read access of an unresolved static or top level entity. 3369 /// Generate read access of an unresolved static or top level entity.
3336 void generateStaticUnresolvedGet(ast.Send node, Element element) { 3370 void generateStaticUnresolvedGet(ast.Send node, Element element) {
3337 if (element is ErroneousElement) { 3371 if (element is ErroneousElement) {
3372 SourceInformation sourceInformation =
3373 sourceInformationBuilder.buildGet(node);
3338 // An erroneous element indicates an unresolved static getter. 3374 // An erroneous element indicates an unresolved static getter.
3339 handleInvalidStaticGet(node, element); 3375 handleInvalidStaticGet(node, element);
3340 } else { 3376 } else {
3341 // This happens when [element] has parse errors. 3377 // This happens when [element] has parse errors.
3342 assert(invariant(node, element == null || element.isErroneous)); 3378 assert(invariant(node, element == null || element.isErroneous));
3343 // TODO(ahe): Do something like the above, that is, emit a runtime 3379 // TODO(ahe): Do something like the above, that is, emit a runtime
3344 // error. 3380 // error.
3345 stack.add(graph.addConstantNull(compiler)); 3381 stack.add(graph.addConstantNull(compiler));
3346 } 3382 }
3347 } 3383 }
3348 3384
3349 /// Read a static or top level [field] of constant value. 3385 /// Read a static or top level [field] of constant value.
3350 void generateStaticConstGet( 3386 void generateStaticConstGet(
3351 ast.Send node, 3387 ast.Send node,
3352 FieldElement field, 3388 FieldElement field,
3353 ConstantExpression constant) { 3389 ConstantExpression constant,
3390 SourceInformation sourceInformation) {
3354 ConstantValue value = backend.constants.getConstantValue(constant); 3391 ConstantValue value = backend.constants.getConstantValue(constant);
3355 HConstant instruction; 3392 HConstant instruction;
3356 // Constants that are referred via a deferred prefix should be referred 3393 // Constants that are referred via a deferred prefix should be referred
3357 // by reference. 3394 // by reference.
3358 PrefixElement prefix = compiler.deferredLoadTask 3395 PrefixElement prefix = compiler.deferredLoadTask
3359 .deferredPrefixElement(node, elements); 3396 .deferredPrefixElement(node, elements);
3360 if (prefix != null) { 3397 if (prefix != null) {
3361 instruction = graph.addDeferredConstant(value, prefix, compiler); 3398 instruction =
3399 graph.addDeferredConstant(value, prefix, sourceInformation, compiler);
3362 } else { 3400 } else {
3363 instruction = graph.addConstant(value, compiler); 3401 instruction = graph.addConstant(
3402 value, compiler, sourceInformation: sourceInformation);
3364 } 3403 }
3365 stack.add(instruction); 3404 stack.add(instruction);
3366 // The inferrer may have found a better type than the constant 3405 // The inferrer may have found a better type than the constant
3367 // handler in the case of lists, because the constant handler 3406 // handler in the case of lists, because the constant handler
3368 // does not look at elements in the list. 3407 // does not look at elements in the list.
3369 TypeMask type = 3408 TypeMask type =
3370 TypeMaskFactory.inferredTypeForElement(field, compiler); 3409 TypeMaskFactory.inferredTypeForElement(field, compiler);
3371 if (!type.containsAll(compiler.world) && 3410 if (!type.containsAll(compiler.world) &&
3372 !instruction.isConstantNull()) { 3411 !instruction.isConstantNull()) {
3373 // TODO(13429): The inferrer should know that an element 3412 // TODO(13429): The inferrer should know that an element
3374 // cannot be null. 3413 // cannot be null.
3375 instruction.instructionType = type.nonNullable(); 3414 instruction.instructionType = type.nonNullable();
3376 } 3415 }
3377 } 3416 }
3378 3417
3379 /// Read a static or top level [field]. 3418 /// Read a static or top level [field].
3380 void generateStaticFieldGet(ast.Send node, FieldElement field) { 3419 void generateStaticFieldGet(ast.Send node, FieldElement field) {
3381 generateIsDeferredLoadedCheckOfSend(node); 3420 generateIsDeferredLoadedCheckOfSend(node);
3382 3421
3383 ConstantExpression constant = 3422 ConstantExpression constant =
3384 backend.constants.getConstantForVariable(field); 3423 backend.constants.getConstantForVariable(field);
3424 SourceInformation sourceInformation =
3425 sourceInformationBuilder.buildGet(node);
3385 if (constant != null) { 3426 if (constant != null) {
3386 if (!field.isAssignable) { 3427 if (!field.isAssignable) {
3387 // A static final or const. Get its constant value and inline it if 3428 // A static final or const. Get its constant value and inline it if
3388 // the value can be compiled eagerly. 3429 // the value can be compiled eagerly.
3389 generateStaticConstGet(node, field, constant); 3430 generateStaticConstGet(node, field, constant, sourceInformation);
3390 } else { 3431 } else {
3391 // TODO(5346): Try to avoid the need for calling [declaration] before 3432 // TODO(5346): Try to avoid the need for calling [declaration] before
3392 // creating an [HStatic]. 3433 // creating an [HStatic].
3393 HInstruction instruction = new HStatic( 3434 HInstruction instruction = new HStatic(
3394 field.declaration, 3435 field.declaration,
3395 TypeMaskFactory.inferredTypeForElement(field, compiler)); 3436 TypeMaskFactory.inferredTypeForElement(field, compiler))
3437 ..sourceInformation = sourceInformation;
3396 push(instruction); 3438 push(instruction);
3397 } 3439 }
3398 } else { 3440 } else {
3399 HInstruction instruction = new HLazyStatic( 3441 HInstruction instruction = new HLazyStatic(
3400 field, 3442 field,
3401 TypeMaskFactory.inferredTypeForElement(field, compiler)); 3443 TypeMaskFactory.inferredTypeForElement(field, compiler))
3444 ..sourceInformation = sourceInformation;
3402 push(instruction); 3445 push(instruction);
3403 } 3446 }
3404 } 3447 }
3405 3448
3406 /// Generate a getter invocation of the static or top level [getter]. 3449 /// Generate a getter invocation of the static or top level [getter].
3407 void generateStaticGetterGet(ast.Send node, MethodElement getter) { 3450 void generateStaticGetterGet(ast.Send node, MethodElement getter) {
3451 SourceInformation sourceInformation =
3452 sourceInformationBuilder.buildGet(node);
3408 if (getter.isDeferredLoaderGetter) { 3453 if (getter.isDeferredLoaderGetter) {
3409 generateDeferredLoaderGet(node, getter); 3454 generateDeferredLoaderGet(node, getter, sourceInformation);
3410 } else { 3455 } else {
3411 generateIsDeferredLoadedCheckOfSend(node); 3456 generateIsDeferredLoadedCheckOfSend(node);
3412 pushInvokeStatic(node, getter, <HInstruction>[]); 3457 pushInvokeStatic(node, getter, <HInstruction>[],
3458 sourceInformation: sourceInformation);
3413 } 3459 }
3414 } 3460 }
3415 3461
3416 /// Generate a dynamic getter invocation. 3462 /// Generate a dynamic getter invocation.
3417 void generateDynamicGet(ast.Send node) { 3463 void generateDynamicGet(ast.Send node) {
3418 HInstruction receiver = generateInstanceSendReceiver(node); 3464 HInstruction receiver = generateInstanceSendReceiver(node);
3419 generateInstanceGetterWithCompiledReceiver( 3465 generateInstanceGetterWithCompiledReceiver(
3420 node, elements.getSelector(node), elements.getTypeMask(node), receiver); 3466 node, elements.getSelector(node), elements.getTypeMask(node), receiver);
3421 } 3467 }
3422 3468
3423 /// Generate a closurization of the static or top level [function]. 3469 /// Generate a closurization of the static or top level [function].
3424 void generateStaticFunctionGet(ast.Send node, MethodElement function) { 3470 void generateStaticFunctionGet(ast.Send node, MethodElement function) {
3425 generateIsDeferredLoadedCheckOfSend(node); 3471 generateIsDeferredLoadedCheckOfSend(node);
3426 // TODO(5346): Try to avoid the need for calling [declaration] before 3472 // TODO(5346): Try to avoid the need for calling [declaration] before
3427 // creating an [HStatic]. 3473 // creating an [HStatic].
3428 push(new HStatic(function.declaration, backend.nonNullType)); 3474 SourceInformation sourceInformation =
3475 sourceInformationBuilder.buildGet(node);
3476 push(new HStatic(function.declaration, backend.nonNullType)
3477 ..sourceInformation = sourceInformation);
3429 } 3478 }
3430 3479
3431 /// Read a local variable, function or parameter. 3480 /// Read a local variable, function or parameter.
3432 void handleLocalGet(LocalElement local) { 3481 void buildLocalGet(LocalElement local, SourceInformation sourceInformation) {
3433 stack.add(localsHandler.readLocal(local)); 3482 stack.add(localsHandler.readLocal(
3483 local, sourceInformation: sourceInformation));
3484 }
3485
3486 void handleLocalGet(ast.Send node, LocalElement local) {
3487 buildLocalGet(local, sourceInformationBuilder.buildGet(node));
3434 } 3488 }
3435 3489
3436 @override 3490 @override
3437 void visitDynamicPropertyGet( 3491 void visitDynamicPropertyGet(
3438 ast.Send node, 3492 ast.Send node,
3439 ast.Node receiver, 3493 ast.Node receiver,
3440 Selector selector, 3494 Selector selector,
3441 _) { 3495 _) {
3442 generateDynamicGet(node); 3496 generateDynamicGet(node);
3443 } 3497 }
(...skipping 28 matching lines...) Expand all
3472 } 3526 }
3473 3527
3474 /// Pushes a boolean checking [expression] against null. 3528 /// Pushes a boolean checking [expression] against null.
3475 pushCheckNull(HInstruction expression) { 3529 pushCheckNull(HInstruction expression) {
3476 push(new HIdentity(expression, graph.addConstantNull(compiler), 3530 push(new HIdentity(expression, graph.addConstantNull(compiler),
3477 null, backend.boolType)); 3531 null, backend.boolType));
3478 } 3532 }
3479 3533
3480 @override 3534 @override
3481 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) { 3535 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
3482 handleLocalGet(variable); 3536 handleLocalGet(node, variable);
3483 } 3537 }
3484 3538
3485 @override 3539 @override
3486 void visitParameterGet(ast.Send node, ParameterElement parameter, _) { 3540 void visitParameterGet(ast.Send node, ParameterElement parameter, _) {
3487 handleLocalGet(parameter); 3541 handleLocalGet(node, parameter);
3488 } 3542 }
3489 3543
3490 @override 3544 @override
3491 void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) { 3545 void visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
3492 handleLocalGet(function); 3546 handleLocalGet(node, function);
3493 } 3547 }
3494 3548
3495 @override 3549 @override
3496 void visitStaticFieldGet( 3550 void visitStaticFieldGet(
3497 ast.Send node, 3551 ast.Send node,
3498 FieldElement field, 3552 FieldElement field,
3499 _) { 3553 _) {
3500 generateStaticFieldGet(node, field); 3554 generateStaticFieldGet(node, field);
3501 } 3555 }
3502 3556
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3560 selector = elements.getSelector(send); 3614 selector = elements.getSelector(send);
3561 if (mask == null) { 3615 if (mask == null) {
3562 mask = elements.getTypeMask(send); 3616 mask = elements.getTypeMask(send);
3563 } 3617 }
3564 } 3618 }
3565 if (location == null) { 3619 if (location == null) {
3566 assert(send != null); 3620 assert(send != null);
3567 location = send; 3621 location = send;
3568 } 3622 }
3569 assert(selector.isSetter); 3623 assert(selector.isSetter);
3570 pushInvokeDynamic(location, selector, mask, [receiver, value]); 3624 pushInvokeDynamic(location, selector, mask, [receiver, value],
3625 sourceInformation: sourceInformationBuilder.buildAssignment(location));
3571 pop(); 3626 pop();
3572 stack.add(value); 3627 stack.add(value);
3573 } 3628 }
3574 3629
3575 void generateNonInstanceSetter(ast.SendSet send, 3630 void generateNonInstanceSetter(ast.SendSet send,
3576 Element element, 3631 Element element,
3577 HInstruction value, 3632 HInstruction value,
3578 {ast.Node location}) { 3633 {ast.Node location}) {
3579 assert(send == null || !Elements.isInstanceSend(send, elements)); 3634 assert(send == null || !Elements.isInstanceSend(send, elements));
3580 if (location == null) { 3635 if (location == null) {
(...skipping 29 matching lines...) Expand all
3610 if (value.sourceElement == null) { 3665 if (value.sourceElement == null) {
3611 value.sourceElement = local; 3666 value.sourceElement = local;
3612 } 3667 }
3613 HInstruction checkedOrTrusted = 3668 HInstruction checkedOrTrusted =
3614 potentiallyCheckOrTrustType(value, local.type); 3669 potentiallyCheckOrTrustType(value, local.type);
3615 if (!identical(checkedOrTrusted, value)) { 3670 if (!identical(checkedOrTrusted, value)) {
3616 pop(); 3671 pop();
3617 stack.add(checkedOrTrusted); 3672 stack.add(checkedOrTrusted);
3618 } 3673 }
3619 3674
3620 localsHandler.updateLocal(local, checkedOrTrusted); 3675 localsHandler.updateLocal(local, checkedOrTrusted,
3676 sourceInformation:
3677 sourceInformationBuilder.buildAssignment(location));
3621 } 3678 }
3622 } 3679 }
3623 3680
3624 HInstruction invokeInterceptor(HInstruction receiver) { 3681 HInstruction invokeInterceptor(HInstruction receiver) {
3625 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); 3682 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType);
3626 add(interceptor); 3683 add(interceptor);
3627 return interceptor; 3684 return interceptor;
3628 } 3685 }
3629 3686
3630 HLiteralList buildLiteralList(List<HInstruction> inputs) { 3687 HLiteralList buildLiteralList(List<HInstruction> inputs) {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3820 3877
3821 /// Generate a dynamic method, getter or setter invocation. 3878 /// Generate a dynamic method, getter or setter invocation.
3822 void generateDynamicSend(ast.Send node) { 3879 void generateDynamicSend(ast.Send node) {
3823 HInstruction receiver = generateInstanceSendReceiver(node); 3880 HInstruction receiver = generateInstanceSendReceiver(node);
3824 _generateDynamicSend(node, receiver); 3881 _generateDynamicSend(node, receiver);
3825 } 3882 }
3826 3883
3827 void _generateDynamicSend(ast.Send node, HInstruction receiver) { 3884 void _generateDynamicSend(ast.Send node, HInstruction receiver) {
3828 Selector selector = elements.getSelector(node); 3885 Selector selector = elements.getSelector(node);
3829 TypeMask mask = elements.getTypeMask(node); 3886 TypeMask mask = elements.getTypeMask(node);
3887 SourceInformation sourceInformation =
3888 sourceInformationBuilder.buildCall(node, node.selector);
3830 3889
3831 List<HInstruction> inputs = <HInstruction>[]; 3890 List<HInstruction> inputs = <HInstruction>[];
3832 inputs.add(receiver); 3891 inputs.add(receiver);
3833 addDynamicSendArgumentsToList(node, inputs); 3892 addDynamicSendArgumentsToList(node, inputs);
3834 3893
3835 pushInvokeDynamic(node, selector, mask, inputs); 3894 pushInvokeDynamic(node, selector, mask, inputs,
3895 sourceInformation: sourceInformation);
3836 if (selector.isSetter || selector.isIndexSet) { 3896 if (selector.isSetter || selector.isIndexSet) {
3837 pop(); 3897 pop();
3838 stack.add(inputs.last); 3898 stack.add(inputs.last);
3839 } 3899 }
3840 } 3900 }
3841 3901
3842 @override 3902 @override
3843 visitDynamicPropertyInvoke( 3903 visitDynamicPropertyInvoke(
3844 ast.Send node, 3904 ast.Send node,
3845 ast.Node receiver, 3905 ast.Node receiver,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3877 generateDynamicSend(node); 3937 generateDynamicSend(node);
3878 } 3938 }
3879 3939
3880 @override 3940 @override
3881 visitExpressionInvoke( 3941 visitExpressionInvoke(
3882 ast.Send node, 3942 ast.Send node,
3883 ast.Node expression, 3943 ast.Node expression,
3884 ast.NodeList arguments, 3944 ast.NodeList arguments,
3885 Selector selector, 3945 Selector selector,
3886 _) { 3946 _) {
3887 generateCallInvoke(node, visitAndPop(expression)); 3947 generateCallInvoke(
3948 node,
3949 visitAndPop(expression),
3950 sourceInformationBuilder.buildCall(node, node.argumentsNode));
3888 } 3951 }
3889 3952
3890 @override 3953 @override
3891 visitThisInvoke( 3954 visitThisInvoke(
3892 ast.Send node, 3955 ast.Send node,
3893 ast.NodeList arguments, 3956 ast.NodeList arguments,
3894 CallStructure callStructure, 3957 CallStructure callStructure,
3895 _) { 3958 _) {
3896 generateCallInvoke(node, localsHandler.readThis()); 3959 generateCallInvoke(
3960 node,
3961 localsHandler.readThis(),
3962 sourceInformationBuilder.buildCall(node, node.argumentsNode));
3897 } 3963 }
3898 3964
3899 @override 3965 @override
3900 visitParameterInvoke( 3966 visitParameterInvoke(
3901 ast.Send node, 3967 ast.Send node,
3902 ParameterElement parameter, 3968 ParameterElement parameter,
3903 ast.NodeList arguments, 3969 ast.NodeList arguments,
3904 CallStructure callStructure, 3970 CallStructure callStructure,
3905 _) { 3971 _) {
3906 generateCallInvoke(node, localsHandler.readLocal(parameter)); 3972 generateCallInvoke(
3973 node,
3974 localsHandler.readLocal(parameter),
3975 sourceInformationBuilder.buildCall(node, node.argumentsNode));
3907 } 3976 }
3908 3977
3909 @override 3978 @override
3910 visitLocalVariableInvoke( 3979 visitLocalVariableInvoke(
3911 ast.Send node, 3980 ast.Send node,
3912 LocalVariableElement variable, 3981 LocalVariableElement variable,
3913 ast.NodeList arguments, 3982 ast.NodeList arguments,
3914 CallStructure callStructure, 3983 CallStructure callStructure,
3915 _) { 3984 _) {
3916 generateCallInvoke(node, localsHandler.readLocal(variable)); 3985 generateCallInvoke(
3986 node,
3987 localsHandler.readLocal(variable),
3988 sourceInformationBuilder.buildCall(node, node.argumentsNode));
3917 } 3989 }
3918 3990
3919 @override 3991 @override
3920 visitLocalFunctionInvoke( 3992 visitLocalFunctionInvoke(
3921 ast.Send node, 3993 ast.Send node,
3922 LocalFunctionElement function, 3994 LocalFunctionElement function,
3923 ast.NodeList arguments, 3995 ast.NodeList arguments,
3924 CallStructure callStructure, 3996 CallStructure callStructure,
3925 _) { 3997 _) {
3926 generateCallInvoke(node, localsHandler.readLocal(function)); 3998 generateCallInvoke(
3999 node,
4000 localsHandler.readLocal(function),
4001 sourceInformationBuilder.buildCall(node, node.argumentsNode));
3927 } 4002 }
3928 4003
3929 @override 4004 @override
3930 visitLocalFunctionIncompatibleInvoke( 4005 visitLocalFunctionIncompatibleInvoke(
3931 ast.Send node, 4006 ast.Send node,
3932 LocalFunctionElement function, 4007 LocalFunctionElement function,
3933 ast.NodeList arguments, 4008 ast.NodeList arguments,
3934 CallStructure callStructure, 4009 CallStructure callStructure,
3935 _) { 4010 _) {
3936 generateCallInvoke(node, localsHandler.readLocal(function)); 4011 generateCallInvoke(node, localsHandler.readLocal(function),
4012 sourceInformationBuilder.buildCall(node, node.argumentsNode));
3937 } 4013 }
3938 4014
3939 void handleForeignJs(ast.Send node) { 4015 void handleForeignJs(ast.Send node) {
3940 Link<ast.Node> link = node.arguments; 4016 Link<ast.Node> link = node.arguments;
3941 // Don't visit the first argument, which is the type, and the second 4017 // Don't visit the first argument, which is the type, and the second
3942 // argument, which is the foreign code. 4018 // argument, which is the foreign code.
3943 if (link.isEmpty || link.tail.isEmpty) { 4019 if (link.isEmpty || link.tail.isEmpty) {
3944 compiler.internalError(node.argumentsNode, 4020 compiler.internalError(node.argumentsNode,
3945 'At least two arguments expected.'); 4021 'At least two arguments expected.');
3946 } 4022 }
3947 native.NativeBehavior nativeBehavior = 4023 native.NativeBehavior nativeBehavior =
3948 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); 4024 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
3949 4025
3950 List<HInstruction> inputs = <HInstruction>[]; 4026 List<HInstruction> inputs = <HInstruction>[];
3951 addGenericSendArgumentsToList(link.tail.tail, inputs); 4027 addGenericSendArgumentsToList(link.tail.tail, inputs);
3952 4028
3953 TypeMask ssaType = 4029 TypeMask ssaType =
3954 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler); 4030 TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
3955 4031
4032 SourceInformation sourceInformation =
4033 sourceInformationBuilder.buildCall(node, node.argumentsNode);
3956 if (nativeBehavior.codeTemplate.isExpression) { 4034 if (nativeBehavior.codeTemplate.isExpression) {
3957 push(new HForeignCode( 4035 push(new HForeignCode(
3958 nativeBehavior.codeTemplate, ssaType, inputs, 4036 nativeBehavior.codeTemplate, ssaType, inputs,
3959 effects: nativeBehavior.sideEffects, 4037 effects: nativeBehavior.sideEffects,
3960 nativeBehavior: nativeBehavior)); 4038 nativeBehavior: nativeBehavior)
4039 ..sourceInformation = sourceInformation);
3961 } else { 4040 } else {
3962 push(new HForeignCode( 4041 push(new HForeignCode(
3963 nativeBehavior.codeTemplate, ssaType, inputs, 4042 nativeBehavior.codeTemplate, ssaType, inputs,
3964 isStatement: true, 4043 isStatement: true,
3965 effects: nativeBehavior.sideEffects, 4044 effects: nativeBehavior.sideEffects,
3966 nativeBehavior: nativeBehavior)); 4045 nativeBehavior: nativeBehavior)
4046 ..sourceInformation = sourceInformation);
3967 } 4047 }
3968 } 4048 }
3969 4049
3970 void handleJsStringConcat(ast.Send node) { 4050 void handleJsStringConcat(ast.Send node) {
3971 List<HInstruction> inputs = <HInstruction>[]; 4051 List<HInstruction> inputs = <HInstruction>[];
3972 addGenericSendArgumentsToList(node.arguments, inputs); 4052 addGenericSendArgumentsToList(node.arguments, inputs);
3973 if (inputs.length != 2) { 4053 if (inputs.length != 2) {
3974 compiler.internalError(node.argumentsNode, 'Two arguments expected.'); 4054 compiler.internalError(node.argumentsNode, 'Two arguments expected.');
3975 } 4055 }
3976 push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType)); 4056 push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType));
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
4305 stack.add(graph.addConstantNull(compiler)); 4385 stack.add(graph.addConstantNull(compiler));
4306 } else if (name == 'JS_INTERCEPTOR_CONSTANT') { 4386 } else if (name == 'JS_INTERCEPTOR_CONSTANT') {
4307 handleJsInterceptorConstant(node); 4387 handleJsInterceptorConstant(node);
4308 } else if (name == 'JS_STRING_CONCAT') { 4388 } else if (name == 'JS_STRING_CONCAT') {
4309 handleJsStringConcat(node); 4389 handleJsStringConcat(node);
4310 } else { 4390 } else {
4311 compiler.internalError(node, "Unknown foreign: ${element}"); 4391 compiler.internalError(node, "Unknown foreign: ${element}");
4312 } 4392 }
4313 } 4393 }
4314 4394
4315 generateDeferredLoaderGet(ast.Send node, FunctionElement deferredLoader) { 4395 generateDeferredLoaderGet(ast.Send node,
4396 FunctionElement deferredLoader,
4397 SourceInformation sourceInformation) {
4316 // Until now we only handle these as getters. 4398 // Until now we only handle these as getters.
4317 invariant(node, deferredLoader.isDeferredLoaderGetter); 4399 invariant(node, deferredLoader.isDeferredLoaderGetter);
4318 Element loadFunction = compiler.loadLibraryFunction; 4400 Element loadFunction = compiler.loadLibraryFunction;
4319 PrefixElement prefixElement = deferredLoader.enclosingElement; 4401 PrefixElement prefixElement = deferredLoader.enclosingElement;
4320 String loadId = compiler.deferredLoadTask 4402 String loadId = compiler.deferredLoadTask
4321 .importDeferName[prefixElement.deferredImport]; 4403 .importDeferName[prefixElement.deferredImport];
4322 var inputs = [graph.addConstantString( 4404 var inputs = [graph.addConstantString(
4323 new ast.DartString.literal(loadId), compiler)]; 4405 new ast.DartString.literal(loadId), compiler)];
4324 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, 4406 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType,
4325 targetCanThrow: false)); 4407 targetCanThrow: false)
4408 ..sourceInformation = sourceInformation);
4326 } 4409 }
4327 4410
4328 generateSuperNoSuchMethodSend(ast.Send node, 4411 generateSuperNoSuchMethodSend(ast.Send node,
4329 Selector selector, 4412 Selector selector,
4330 List<HInstruction> arguments) { 4413 List<HInstruction> arguments) {
4331 String name = selector.name; 4414 String name = selector.name;
4332 4415
4333 ClassElement cls = currentNonClosureClass; 4416 ClassElement cls = currentNonClosureClass;
4334 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); 4417 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
4335 if (compiler.enabledInvokeOn 4418 if (compiler.enabledInvokeOn
(...skipping 28 matching lines...) Expand all
4364 ConstantValue kindConstant = 4447 ConstantValue kindConstant =
4365 constantSystem.createInt(selector.invocationMirrorKind); 4448 constantSystem.createInt(selector.invocationMirrorKind);
4366 4449
4367 pushInvokeStatic(null, 4450 pushInvokeStatic(null,
4368 createInvocationMirror, 4451 createInvocationMirror,
4369 [graph.addConstant(nameConstant, compiler), 4452 [graph.addConstant(nameConstant, compiler),
4370 graph.addConstantStringFromName(internalName, compiler), 4453 graph.addConstantStringFromName(internalName, compiler),
4371 graph.addConstant(kindConstant, compiler), 4454 graph.addConstant(kindConstant, compiler),
4372 argumentsInstruction, 4455 argumentsInstruction,
4373 argumentNamesInstruction], 4456 argumentNamesInstruction],
4374 typeMask: backend.dynamicType); 4457 typeMask: backend.dynamicType);
4375 4458
4376 var inputs = <HInstruction>[pop()]; 4459 var inputs = <HInstruction>[pop()];
4377 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); 4460 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs));
4378 } 4461 }
4379 4462
4380 /// Generate a call to a super method or constructor. 4463 /// Generate a call to a super method or constructor.
4381 void generateSuperInvoke(ast.Send node, FunctionElement function) { 4464 void generateSuperInvoke(ast.Send node,
4465 FunctionElement function,
4466 SourceInformation sourceInformation) {
4382 // TODO(5347): Try to avoid the need for calling [implementation] before 4467 // TODO(5347): Try to avoid the need for calling [implementation] before
4383 // calling [makeStaticArgumentList]. 4468 // calling [makeStaticArgumentList].
4384 Selector selector = elements.getSelector(node); 4469 Selector selector = elements.getSelector(node);
4385 assert(invariant(node, 4470 assert(invariant(node,
4386 selector.applies(function.implementation, compiler.world), 4471 selector.applies(function.implementation, compiler.world),
4387 message: "$selector does not apply to ${function.implementation}")); 4472 message: "$selector does not apply to ${function.implementation}"));
4388 List<HInstruction> inputs = 4473 List<HInstruction> inputs =
4389 makeStaticArgumentList(selector.callStructure, 4474 makeStaticArgumentList(selector.callStructure,
4390 node.arguments, 4475 node.arguments,
4391 function.implementation); 4476 function.implementation);
4392 push(buildInvokeSuper(selector, function, inputs)); 4477 push(buildInvokeSuper(selector, function, inputs, sourceInformation));
4393 } 4478 }
4394 4479
4395 /// Access the value from the super [element]. 4480 /// Access the value from the super [element].
4396 void handleSuperGet(ast.Send node, Element element) { 4481 void handleSuperGet(ast.Send node, Element element) {
4397 Selector selector = elements.getSelector(node); 4482 Selector selector = elements.getSelector(node);
4398 push(buildInvokeSuper(selector, element, const <HInstruction>[])); 4483 SourceInformation sourceInformation =
4484 sourceInformationBuilder.buildGet(node);
4485 push(buildInvokeSuper(
4486 selector, element, const <HInstruction>[], sourceInformation));
4399 } 4487 }
4400 4488
4401 /// Invoke .call on the value retrieved from the super [element]. 4489 /// Invoke .call on the value retrieved from the super [element].
4402 void handleSuperCallInvoke(ast.Send node, Element element) { 4490 void handleSuperCallInvoke(ast.Send node, Element element) {
4403 Selector selector = elements.getSelector(node); 4491 Selector selector = elements.getSelector(node);
4404 HInstruction target = 4492 HInstruction target = buildInvokeSuper(
4405 buildInvokeSuper(selector, element, const <HInstruction>[]); 4493 selector, element, const <HInstruction>[],
4494 sourceInformationBuilder.buildGet(node));
4406 add(target); 4495 add(target);
4407 generateCallInvoke(node, target); 4496 generateCallInvoke(
4497 node,
4498 target,
4499 sourceInformationBuilder.buildCall(node, node.argumentsNode));
4408 } 4500 }
4409 4501
4410 /// Invoke super [method]. 4502 /// Invoke super [method].
4411 void handleSuperMethodInvoke( 4503 void handleSuperMethodInvoke(
4412 ast.Send node, 4504 ast.Send node,
4413 MethodElement method) { 4505 MethodElement method) {
4414 generateSuperInvoke(node, method); 4506 generateSuperInvoke(node, method,
4507 sourceInformationBuilder.buildCall(node, node.selector));
4415 } 4508 }
4416 4509
4417 /// Access an unresolved super property. 4510 /// Access an unresolved super property.
4418 void handleUnresolvedSuperInvoke(ast.Send node) { 4511 void handleUnresolvedSuperInvoke(ast.Send node) {
4419 Selector selector = elements.getSelector(node); 4512 Selector selector = elements.getSelector(node);
4420 List<HInstruction> arguments = <HInstruction>[]; 4513 List<HInstruction> arguments = <HInstruction>[];
4421 if (!node.isPropertyAccess) { 4514 if (!node.isPropertyAccess) {
4422 addGenericSendArgumentsToList(node.arguments, arguments); 4515 addGenericSendArgumentsToList(node.arguments, arguments);
4423 } 4516 }
4424 generateSuperNoSuchMethodSend(node, selector, arguments); 4517 generateSuperNoSuchMethodSend(node, selector, arguments);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
4615 return !rti.isTrivialSubstitution(subclass, cls); 4708 return !rti.isTrivialSubstitution(subclass, cls);
4616 }); 4709 });
4617 } 4710 }
4618 4711
4619 /** 4712 /**
4620 * Generate code to extract the type arguments from the object, substitute 4713 * Generate code to extract the type arguments from the object, substitute
4621 * them as an instance of the type we are testing against (if necessary), and 4714 * them as an instance of the type we are testing against (if necessary), and
4622 * extract the type argument by the index of the variable in the list of type 4715 * extract the type argument by the index of the variable in the list of type
4623 * variables for that class. 4716 * variables for that class.
4624 */ 4717 */
4625 HInstruction readTypeVariable(ClassElement cls, 4718 HInstruction readTypeVariable(
4626 TypeVariableElement variable) { 4719 ClassElement cls,
4720 TypeVariableElement variable,
4721 {SourceInformation sourceInformation}) {
4627 assert(sourceElement.isInstanceMember); 4722 assert(sourceElement.isInstanceMember);
4628 4723
4629 HInstruction target = localsHandler.readThis(); 4724 HInstruction target = localsHandler.readThis();
4630 HConstant index = graph.addConstantInt( 4725 HConstant index = graph.addConstantInt(
4631 RuntimeTypes.getTypeVariableIndex(variable), 4726 RuntimeTypes.getTypeVariableIndex(variable),
4632 compiler); 4727 compiler);
4633 4728
4634 if (needsSubstitutionForTypeVariableAccess(cls)) { 4729 if (needsSubstitutionForTypeVariableAccess(cls)) {
4635 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to 4730 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to
4636 // string concatenation in the implementation), and may prevent 4731 // string concatenation in the implementation), and may prevent
4637 // segmentation of '$'. 4732 // segmentation of '$'.
4638 js.Name substitutionName = backend.namer.runtimeTypeName(cls); 4733 js.Name substitutionName = backend.namer.runtimeTypeName(cls);
4639 HInstruction substitutionNameInstr = graph.addConstantStringFromName( 4734 HInstruction substitutionNameInstr = graph.addConstantStringFromName(
4640 substitutionName, compiler); 4735 substitutionName, compiler);
4641 pushInvokeStatic(null, 4736 pushInvokeStatic(null,
4642 backend.getGetRuntimeTypeArgument(), 4737 backend.getGetRuntimeTypeArgument(),
4643 [target, substitutionNameInstr, index], 4738 [target, substitutionNameInstr, index],
4644 typeMask: backend.dynamicType); 4739 typeMask: backend.dynamicType,
4740 sourceInformation: sourceInformation);
4645 } else { 4741 } else {
4646 pushInvokeStatic(null, backend.getGetTypeArgumentByIndex(), 4742 pushInvokeStatic(
4743 null,
4744 backend.getGetTypeArgumentByIndex(),
4647 [target, index], 4745 [target, index],
4648 typeMask: backend.dynamicType); 4746 typeMask: backend.dynamicType,
4747 sourceInformation: sourceInformation);
4649 } 4748 }
4650 return pop(); 4749 return pop();
4651 } 4750 }
4652 4751
4653 // TODO(karlklose): this is needed to avoid a bug where the resolved type is 4752 // TODO(karlklose): this is needed to avoid a bug where the resolved type is
4654 // not stored on a type annotation in the closure translator. Remove when 4753 // not stored on a type annotation in the closure translator. Remove when
4655 // fixed. 4754 // fixed.
4656 bool hasDirectLocal(Local local) { 4755 bool hasDirectLocal(Local local) {
4657 return !localsHandler.isAccessedDirectly(local) || 4756 return !localsHandler.isAccessedDirectly(local) ||
4658 localsHandler.directLocals[local] != null; 4757 localsHandler.directLocals[local] != null;
4659 } 4758 }
4660 4759
4661 /** 4760 /**
4662 * Helper to create an instruction that gets the value of a type variable. 4761 * Helper to create an instruction that gets the value of a type variable.
4663 */ 4762 */
4664 HInstruction addTypeVariableReference(TypeVariableType type) { 4763 HInstruction addTypeVariableReference(
4764 TypeVariableType type,
4765 {SourceInformation sourceInformation}) {
4766
4665 assert(assertTypeInContext(type)); 4767 assert(assertTypeInContext(type));
4666 Element member = sourceElement; 4768 Element member = sourceElement;
4667 bool isClosure = member.enclosingElement.isClosure; 4769 bool isClosure = member.enclosingElement.isClosure;
4668 if (isClosure) { 4770 if (isClosure) {
4669 ClosureClassElement closureClass = member.enclosingElement; 4771 ClosureClassElement closureClass = member.enclosingElement;
4670 member = closureClass.methodElement; 4772 member = closureClass.methodElement;
4671 member = member.outermostEnclosingMemberOrTopLevel; 4773 member = member.outermostEnclosingMemberOrTopLevel;
4672 } 4774 }
4673 bool isInConstructorContext = member.isConstructor || 4775 bool isInConstructorContext = member.isConstructor ||
4674 member.isGenerativeConstructorBody; 4776 member.isGenerativeConstructorBody;
4675 Local typeVariableLocal = localsHandler.getTypeVariableAsLocal(type); 4777 Local typeVariableLocal = localsHandler.getTypeVariableAsLocal(type);
4676 if (isClosure) { 4778 if (isClosure) {
4677 if (member.isFactoryConstructor || 4779 if (member.isFactoryConstructor ||
4678 (isInConstructorContext && hasDirectLocal(typeVariableLocal))) { 4780 (isInConstructorContext && hasDirectLocal(typeVariableLocal))) {
4679 // The type variable is used from a closure in a factory constructor. 4781 // The type variable is used from a closure in a factory constructor.
4680 // The value of the type argument is stored as a local on the closure 4782 // The value of the type argument is stored as a local on the closure
4681 // itself. 4783 // itself.
4682 return localsHandler.readLocal(typeVariableLocal); 4784 return localsHandler.readLocal(
4785 typeVariableLocal, sourceInformation: sourceInformation);
4683 } else if (member.isFunction || 4786 } else if (member.isFunction ||
4684 member.isGetter || 4787 member.isGetter ||
4685 member.isSetter || 4788 member.isSetter ||
4686 isInConstructorContext) { 4789 isInConstructorContext) {
4687 // The type variable is stored on the "enclosing object" and needs to be 4790 // The type variable is stored on the "enclosing object" and needs to be
4688 // accessed using the this-reference in the closure. 4791 // accessed using the this-reference in the closure.
4689 return readTypeVariable(member.enclosingClass, type.element); 4792 return readTypeVariable(
4793 member.enclosingClass,
4794 type.element,
4795 sourceInformation: sourceInformation);
4690 } else { 4796 } else {
4691 assert(member.isField); 4797 assert(member.isField);
4692 // The type variable is stored in a parameter of the method. 4798 // The type variable is stored in a parameter of the method.
4693 return localsHandler.readLocal(typeVariableLocal); 4799 return localsHandler.readLocal(typeVariableLocal);
4694 } 4800 }
4695 } else if (isInConstructorContext || 4801 } else if (isInConstructorContext ||
4696 // When [member] is a field, we can be either 4802 // When [member] is a field, we can be either
4697 // generating a checked setter or inlining its 4803 // generating a checked setter or inlining its
4698 // initializer in a constructor. An initializer is 4804 // initializer in a constructor. An initializer is
4699 // never built standalone, so [isBuildingFor] will 4805 // never built standalone, so [isBuildingFor] will
4700 // always return true when seeing one. 4806 // always return true when seeing one.
4701 (member.isField && !isBuildingFor(member))) { 4807 (member.isField && !isBuildingFor(member))) {
4702 // The type variable is stored in a parameter of the method. 4808 // The type variable is stored in a parameter of the method.
4703 return localsHandler.readLocal(typeVariableLocal); 4809 return localsHandler.readLocal(
4810 typeVariableLocal, sourceInformation: sourceInformation);
4704 } else if (member.isInstanceMember) { 4811 } else if (member.isInstanceMember) {
4705 // The type variable is stored on the object. 4812 // The type variable is stored on the object.
4706 return readTypeVariable(member.enclosingClass, 4813 return readTypeVariable(
4707 type.element); 4814 member.enclosingClass,
4815 type.element,
4816 sourceInformation: sourceInformation);
4708 } else { 4817 } else {
4709 compiler.internalError(type.element, 4818 compiler.internalError(type.element,
4710 'Unexpected type variable in static context.'); 4819 'Unexpected type variable in static context.');
4711 return null; 4820 return null;
4712 } 4821 }
4713 } 4822 }
4714 4823
4715 HInstruction analyzeTypeArgument(DartType argument) { 4824 HInstruction analyzeTypeArgument(
4825 DartType argument,
4826 {SourceInformation sourceInformation}) {
4827
4716 assert(assertTypeInContext(argument)); 4828 assert(assertTypeInContext(argument));
4717 if (argument.treatAsDynamic) { 4829 if (argument.treatAsDynamic) {
4718 // Represent [dynamic] as [null]. 4830 // Represent [dynamic] as [null].
4719 return graph.addConstantNull(compiler); 4831 return graph.addConstantNull(compiler);
4720 } 4832 }
4721 4833
4722 if (argument.isTypeVariable) { 4834 if (argument.isTypeVariable) {
4723 return addTypeVariableReference(argument); 4835 return addTypeVariableReference(
4836 argument, sourceInformation: sourceInformation);
4724 } 4837 }
4725 4838
4726 List<HInstruction> inputs = <HInstruction>[]; 4839 List<HInstruction> inputs = <HInstruction>[];
4727 4840
4728 js.Expression template = 4841 js.Expression template =
4729 rti.getTypeRepresentationWithPlaceholders(argument, (variable) { 4842 rti.getTypeRepresentationWithPlaceholders(argument, (variable) {
4730 inputs.add(addTypeVariableReference(variable)); 4843 inputs.add(addTypeVariableReference(variable));
4731 }); 4844 });
4732 4845
4733 js.Template code = new js.Template(null, template); 4846 js.Template code = new js.Template(null, template);
(...skipping 14 matching lines...) Expand all
4748 type.typeArguments.forEach((DartType argument) { 4861 type.typeArguments.forEach((DartType argument) {
4749 inputs.add(analyzeTypeArgument(argument)); 4862 inputs.add(analyzeTypeArgument(argument));
4750 }); 4863 });
4751 // TODO(15489): Register at codegen. 4864 // TODO(15489): Register at codegen.
4752 registry.registerInstantiatedType(type); 4865 registry.registerInstantiatedType(type);
4753 return callSetRuntimeTypeInfo(type.element, inputs, newObject); 4866 return callSetRuntimeTypeInfo(type.element, inputs, newObject);
4754 } 4867 }
4755 4868
4756 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { 4869 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) {
4757 Element copyHelper = backend.getCopyTypeArguments(); 4870 Element copyHelper = backend.getCopyTypeArguments();
4758 pushInvokeStatic(null, copyHelper, [source, target]); 4871 pushInvokeStatic(null, copyHelper, [source, target],
4872 sourceInformation: target.sourceInformation);
4759 pop(); 4873 pop();
4760 } 4874 }
4761 4875
4762 HInstruction callSetRuntimeTypeInfo(ClassElement element, 4876 HInstruction callSetRuntimeTypeInfo(ClassElement element,
4763 List<HInstruction> rtiInputs, 4877 List<HInstruction> rtiInputs,
4764 HInstruction newObject) { 4878 HInstruction newObject) {
4765 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) { 4879 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) {
4766 return newObject; 4880 return newObject;
4767 } 4881 }
4768 4882
4769 HInstruction typeInfo = buildLiteralList(rtiInputs); 4883 HInstruction typeInfo = buildLiteralList(rtiInputs);
4770 add(typeInfo); 4884 add(typeInfo);
4771 4885
4772 // Set the runtime type information on the object. 4886 // Set the runtime type information on the object.
4773 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); 4887 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo();
4774 pushInvokeStatic( 4888 pushInvokeStatic(
4775 null, 4889 null,
4776 typeInfoSetterElement, 4890 typeInfoSetterElement,
4777 <HInstruction>[newObject, typeInfo], 4891 <HInstruction>[newObject, typeInfo],
4778 typeMask: backend.dynamicType); 4892 typeMask: backend.dynamicType,
4893 sourceInformation: newObject.sourceInformation);
4779 4894
4780 // The new object will now be referenced through the 4895 // The new object will now be referenced through the
4781 // `setRuntimeTypeInfo` call. We therefore set the type of that 4896 // `setRuntimeTypeInfo` call. We therefore set the type of that
4782 // instruction to be of the object's type. 4897 // instruction to be of the object's type.
4783 assert(stack.last is HInvokeStatic || stack.last == newObject); 4898 assert(stack.last is HInvokeStatic || stack.last == newObject);
4784 stack.last.instructionType = newObject.instructionType; 4899 stack.last.instructionType = newObject.instructionType;
4785 return pop(); 4900 return pop();
4786 } 4901 }
4787 4902
4788 void handleNewSend(ast.NewExpression node) { 4903 void handleNewSend(ast.NewExpression node) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4926 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array'); 5041 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
4927 // We set the instruction as [canThrow] to avoid it being dead code. 5042 // We set the instruction as [canThrow] to avoid it being dead code.
4928 // We need a finer grained side effect. 5043 // We need a finer grained side effect.
4929 add(new HForeignCode(code, backend.nullType, [stack.last], 5044 add(new HForeignCode(code, backend.nullType, [stack.last],
4930 throwBehavior: native.NativeThrowBehavior.MAY)); 5045 throwBehavior: native.NativeThrowBehavior.MAY));
4931 } 5046 }
4932 } else if (isGrowableListConstructorCall) { 5047 } else if (isGrowableListConstructorCall) {
4933 push(buildLiteralList(<HInstruction>[])); 5048 push(buildLiteralList(<HInstruction>[]));
4934 stack.last.instructionType = elementType; 5049 stack.last.instructionType = elementType;
4935 } else { 5050 } else {
5051 SourceInformation sourceInformation =
5052 sourceInformationBuilder.buildNew(send);
4936 ClassElement cls = constructor.enclosingClass; 5053 ClassElement cls = constructor.enclosingClass;
4937 if (cls.isAbstract && constructor.isGenerativeConstructor) { 5054 if (cls.isAbstract && constructor.isGenerativeConstructor) {
4938 generateAbstractClassInstantiationError(send, cls.name); 5055 generateAbstractClassInstantiationError(send, cls.name);
4939 return; 5056 return;
4940 } 5057 }
4941 potentiallyAddTypeArguments(inputs, cls, expectedType); 5058 potentiallyAddTypeArguments(inputs, cls, expectedType);
4942 5059
4943 addInlinedInstantiation(expectedType); 5060 addInlinedInstantiation(expectedType);
4944 pushInvokeStatic(node, constructor, inputs, 5061 pushInvokeStatic(node, constructor, inputs,
4945 typeMask: elementType, instanceType: expectedType); 5062 typeMask: elementType,
5063 instanceType: expectedType,
5064 sourceInformation: sourceInformation);
4946 removeInlinedInstantiation(expectedType); 5065 removeInlinedInstantiation(expectedType);
4947 } 5066 }
4948 HInstruction newInstance = stack.last; 5067 HInstruction newInstance = stack.last;
4949 if (isFixedList) { 5068 if (isFixedList) {
4950 // Overwrite the element type, in case the allocation site has 5069 // Overwrite the element type, in case the allocation site has
4951 // been inlined. 5070 // been inlined.
4952 newInstance.instructionType = elementType; 5071 newInstance.instructionType = elementType;
4953 JavaScriptItemCompilationContext context = work.compilationContext; 5072 JavaScriptItemCompilationContext context = work.compilationContext;
4954 context.allocatedFixedLists.add(newInstance); 5073 context.allocatedFixedLists.add(newInstance);
4955 } 5074 }
(...skipping 13 matching lines...) Expand all
4969 if (isRedirected) { 5088 if (isRedirected) {
4970 HInstruction checked = potentiallyCheckOrTrustType(newInstance, type); 5089 HInstruction checked = potentiallyCheckOrTrustType(newInstance, type);
4971 if (checked != newInstance) { 5090 if (checked != newInstance) {
4972 pop(); 5091 pop();
4973 stack.add(checked); 5092 stack.add(checked);
4974 } 5093 }
4975 } 5094 }
4976 } 5095 }
4977 5096
4978 void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls, 5097 void potentiallyAddTypeArguments(List<HInstruction> inputs, ClassElement cls,
4979 InterfaceType expectedType) { 5098 InterfaceType expectedType,
5099 {SourceInformation sourceInformation}) {
4980 if (!backend.classNeedsRti(cls)) return; 5100 if (!backend.classNeedsRti(cls)) return;
4981 assert(expectedType.typeArguments.isEmpty || 5101 assert(expectedType.typeArguments.isEmpty ||
4982 cls.typeVariables.length == expectedType.typeArguments.length); 5102 cls.typeVariables.length == expectedType.typeArguments.length);
4983 expectedType.typeArguments.forEach((DartType argument) { 5103 expectedType.typeArguments.forEach((DartType argument) {
4984 inputs.add(analyzeTypeArgument(argument)); 5104 inputs.add(analyzeTypeArgument(
5105 argument, sourceInformation: sourceInformation));
4985 }); 5106 });
4986 } 5107 }
4987 5108
4988 /// In checked mode checks the [type] of [node] to be well-bounded. The method 5109 /// In checked mode checks the [type] of [node] to be well-bounded. The method
4989 /// returns [:true:] if an error can be statically determined. 5110 /// returns [:true:] if an error can be statically determined.
4990 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { 5111 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) {
4991 if (!compiler.enableTypeAssertions) return false; 5112 if (!compiler.enableTypeAssertions) return false;
4992 5113
4993 Map<DartType, Set<DartType>> seenChecksMap = 5114 Map<DartType, Set<DartType>> seenChecksMap =
4994 new Map<DartType, Set<DartType>>(); 5115 new Map<DartType, Set<DartType>>();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
5067 List<HInstruction> inputs = makeStaticArgumentList( 5188 List<HInstruction> inputs = makeStaticArgumentList(
5068 callStructure, 5189 callStructure,
5069 node.arguments, 5190 node.arguments,
5070 function.implementation); 5191 function.implementation);
5071 5192
5072 if (function == compiler.identicalFunction) { 5193 if (function == compiler.identicalFunction) {
5073 pushWithPosition( 5194 pushWithPosition(
5074 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node); 5195 new HIdentity(inputs[0], inputs[1], null, backend.boolType), node);
5075 return; 5196 return;
5076 } else { 5197 } else {
5077 pushInvokeStatic(node, function, inputs); 5198 pushInvokeStatic(node, function, inputs,
5199 sourceInformation: sourceInformationBuilder.buildCall(
5200 node, node.selector));
5078 } 5201 }
5079 } 5202 }
5080 5203
5081 /// Generate an invocation to a static or top level function with the wrong 5204 /// Generate an invocation to a static or top level function with the wrong
5082 /// number of arguments. 5205 /// number of arguments.
5083 void generateStaticFunctionIncompatibleInvoke(ast.Send node, 5206 void generateStaticFunctionIncompatibleInvoke(ast.Send node,
5084 Element element) { 5207 Element element) {
5085 generateWrongArgumentCountError(node, element, node.arguments); 5208 generateWrongArgumentCountError(node, element, node.arguments);
5086 } 5209 }
5087 5210
5088 @override 5211 @override
5089 void visitStaticFieldInvoke( 5212 void visitStaticFieldInvoke(
5090 ast.Send node, 5213 ast.Send node,
5091 FieldElement field, 5214 FieldElement field,
5092 ast.NodeList arguments, 5215 ast.NodeList arguments,
5093 CallStructure callStructure, 5216 CallStructure callStructure,
5094 _) { 5217 _) {
5095 generateStaticFieldGet(node, field); 5218 generateStaticFieldGet(node, field);
5096 generateCallInvoke(node, pop()); 5219 generateCallInvoke(
5220 node,
5221 pop(),
5222 sourceInformationBuilder.buildCall(node, node.argumentsNode));
5097 } 5223 }
5098 5224
5099 @override 5225 @override
5100 void visitStaticFunctionInvoke( 5226 void visitStaticFunctionInvoke(
5101 ast.Send node, 5227 ast.Send node,
5102 MethodElement function, 5228 MethodElement function,
5103 ast.NodeList arguments, 5229 ast.NodeList arguments,
5104 CallStructure callStructure, 5230 CallStructure callStructure,
5105 _) { 5231 _) {
5106 generateStaticFunctionInvoke(node, function, callStructure); 5232 generateStaticFunctionInvoke(node, function, callStructure);
(...skipping 10 matching lines...) Expand all
5117 } 5243 }
5118 5244
5119 @override 5245 @override
5120 void visitStaticGetterInvoke( 5246 void visitStaticGetterInvoke(
5121 ast.Send node, 5247 ast.Send node,
5122 FunctionElement getter, 5248 FunctionElement getter,
5123 ast.NodeList arguments, 5249 ast.NodeList arguments,
5124 CallStructure callStructure, 5250 CallStructure callStructure,
5125 _) { 5251 _) {
5126 generateStaticGetterGet(node, getter); 5252 generateStaticGetterGet(node, getter);
5127 generateCallInvoke(node, pop()); 5253 generateCallInvoke(
5254 node,
5255 pop(),
5256 sourceInformationBuilder.buildCall(node, node.argumentsNode));
5128 } 5257 }
5129 5258
5130 @override 5259 @override
5131 void visitTopLevelFieldInvoke( 5260 void visitTopLevelFieldInvoke(
5132 ast.Send node, 5261 ast.Send node,
5133 FieldElement field, 5262 FieldElement field,
5134 ast.NodeList arguments, 5263 ast.NodeList arguments,
5135 CallStructure callStructure, 5264 CallStructure callStructure,
5136 _) { 5265 _) {
5137 generateStaticFieldGet(node, field); 5266 generateStaticFieldGet(node, field);
5138 generateCallInvoke(node, pop()); 5267 generateCallInvoke(
5268 node,
5269 pop(),
5270 sourceInformationBuilder.buildCall(node, node.argumentsNode));
5139 } 5271 }
5140 5272
5141 @override 5273 @override
5142 void visitTopLevelFunctionInvoke( 5274 void visitTopLevelFunctionInvoke(
5143 ast.Send node, 5275 ast.Send node,
5144 MethodElement function, 5276 MethodElement function,
5145 ast.NodeList arguments, 5277 ast.NodeList arguments,
5146 CallStructure callStructure, 5278 CallStructure callStructure,
5147 _) { 5279 _) {
5148 if (backend.isForeign(function)) { 5280 if (backend.isForeign(function)) {
(...skipping 14 matching lines...) Expand all
5163 } 5295 }
5164 5296
5165 @override 5297 @override
5166 void visitTopLevelGetterInvoke( 5298 void visitTopLevelGetterInvoke(
5167 ast.Send node, 5299 ast.Send node,
5168 FunctionElement getter, 5300 FunctionElement getter,
5169 ast.NodeList arguments, 5301 ast.NodeList arguments,
5170 CallStructure callStructure, 5302 CallStructure callStructure,
5171 _) { 5303 _) {
5172 generateStaticGetterGet(node, getter); 5304 generateStaticGetterGet(node, getter);
5173 generateCallInvoke(node, pop()); 5305 generateCallInvoke(
5306 node,
5307 pop(),
5308 sourceInformationBuilder.buildCall(node, node.argumentsNode));
5174 } 5309 }
5175 5310
5176 @override 5311 @override
5177 void visitTopLevelSetterGet( 5312 void visitTopLevelSetterGet(
5178 ast.Send node, 5313 ast.Send node,
5179 MethodElement setter, 5314 MethodElement setter,
5180 _) { 5315 _) {
5181 handleInvalidStaticGet(node, setter); 5316 handleInvalidStaticGet(node, setter);
5182 } 5317 }
5183 5318
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
5328 stack.add(addConstant(node.selector)); 5463 stack.add(addConstant(node.selector));
5329 } else { 5464 } else {
5330 stack.add(addConstant(node)); 5465 stack.add(addConstant(node));
5331 } 5466 }
5332 } 5467 }
5333 5468
5334 /// Generate the literal for [typeVariable] in the current context. 5469 /// Generate the literal for [typeVariable] in the current context.
5335 void generateTypeVariableLiteral(ast.Send node, 5470 void generateTypeVariableLiteral(ast.Send node,
5336 TypeVariableType typeVariable) { 5471 TypeVariableType typeVariable) {
5337 DartType type = localsHandler.substInContext(typeVariable); 5472 DartType type = localsHandler.substInContext(typeVariable);
5338 HInstruction value = analyzeTypeArgument(type); 5473 HInstruction value = analyzeTypeArgument(type,
5474 sourceInformation: sourceInformationBuilder.buildGet(node));
5339 pushInvokeStatic(node, 5475 pushInvokeStatic(node,
5340 backend.getRuntimeTypeToString(), 5476 backend.getRuntimeTypeToString(),
5341 [value], 5477 [value],
5342 typeMask: backend.stringType); 5478 typeMask: backend.stringType);
5343 pushInvokeStatic(node, 5479 pushInvokeStatic(node,
5344 backend.getCreateRuntimeType(), 5480 backend.getCreateRuntimeType(),
5345 [pop()]); 5481 [pop()]);
5346 } 5482 }
5347 5483
5348 /// Generate a call to a type literal. 5484 /// Generate a call to a type literal.
5349 void generateTypeLiteralCall(ast.Send node) { 5485 void generateTypeLiteralCall(ast.Send node) {
5350 // This send is of the form 'e(...)', where e is resolved to a type 5486 // This send is of the form 'e(...)', where e is resolved to a type
5351 // reference. We create a regular closure call on the result of the type 5487 // reference. We create a regular closure call on the result of the type
5352 // reference instead of creating a NoSuchMethodError to avoid pulling it 5488 // reference instead of creating a NoSuchMethodError to avoid pulling it
5353 // in if it is not used (e.g., in a try/catch). 5489 // in if it is not used (e.g., in a try/catch).
5354 HInstruction target = pop(); 5490 HInstruction target = pop();
5355 generateCallInvoke(node, target); 5491 generateCallInvoke(node, target,
5492 sourceInformationBuilder.buildCall(node, node.argumentsNode));
5356 } 5493 }
5357 5494
5358 /// Generate a '.call' invocation on [target]. 5495 /// Generate a '.call' invocation on [target].
5359 void generateCallInvoke(ast.Send node, HInstruction target) { 5496 void generateCallInvoke(ast.Send node,
5497 HInstruction target,
5498 SourceInformation sourceInformation) {
5360 Selector selector = elements.getSelector(node); 5499 Selector selector = elements.getSelector(node);
5361 List<HInstruction> inputs = <HInstruction>[target]; 5500 List<HInstruction> inputs = <HInstruction>[target];
5362 addDynamicSendArgumentsToList(node, inputs); 5501 addDynamicSendArgumentsToList(node, inputs);
5363 pushWithPosition( 5502 push(new HInvokeClosure(
5364 new HInvokeClosure(
5365 new Selector.callClosureFrom(selector), 5503 new Selector.callClosureFrom(selector),
5366 inputs, backend.dynamicType), 5504 inputs, backend.dynamicType)
5367 node); 5505 ..sourceInformation = sourceInformation);
5368 } 5506 }
5369 5507
5370 visitGetterSend(ast.Send node) { 5508 visitGetterSend(ast.Send node) {
5371 internalError(node, "Unexpected visitGetterSend"); 5509 internalError(node, "Unexpected visitGetterSend");
5372 } 5510 }
5373 5511
5374 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError. 5512 // TODO(antonm): migrate rest of SsaFromAstMixin to internalError.
5375 internalError(Spannable node, String reason) { 5513 internalError(Spannable node, String reason) {
5376 compiler.internalError(node, reason); 5514 compiler.internalError(node, reason);
5377 } 5515 }
(...skipping 14 matching lines...) Expand all
5392 void generateAbstractClassInstantiationError(ast.Node node, String message) { 5530 void generateAbstractClassInstantiationError(ast.Node node, String message) {
5393 generateError(node, 5531 generateError(node,
5394 message, 5532 message,
5395 backend.getThrowAbstractClassInstantiationError()); 5533 backend.getThrowAbstractClassInstantiationError());
5396 } 5534 }
5397 5535
5398 void generateThrowNoSuchMethod(ast.Node diagnosticNode, 5536 void generateThrowNoSuchMethod(ast.Node diagnosticNode,
5399 String methodName, 5537 String methodName,
5400 {Link<ast.Node> argumentNodes, 5538 {Link<ast.Node> argumentNodes,
5401 List<HInstruction> argumentValues, 5539 List<HInstruction> argumentValues,
5402 List<String> existingArguments}) { 5540 List<String> existingArguments,
5541 SourceInformation sourceInformation}) {
5403 Element helper = backend.getThrowNoSuchMethod(); 5542 Element helper = backend.getThrowNoSuchMethod();
5404 ConstantValue receiverConstant = 5543 ConstantValue receiverConstant =
5405 constantSystem.createString(new ast.DartString.empty()); 5544 constantSystem.createString(new ast.DartString.empty());
5406 HInstruction receiver = graph.addConstant(receiverConstant, compiler); 5545 HInstruction receiver = graph.addConstant(receiverConstant, compiler);
5407 ast.DartString dartString = new ast.DartString.literal(methodName); 5546 ast.DartString dartString = new ast.DartString.literal(methodName);
5408 ConstantValue nameConstant = constantSystem.createString(dartString); 5547 ConstantValue nameConstant = constantSystem.createString(dartString);
5409 HInstruction name = graph.addConstant(nameConstant, compiler); 5548 HInstruction name = graph.addConstant(nameConstant, compiler);
5410 if (argumentValues == null) { 5549 if (argumentValues == null) {
5411 argumentValues = <HInstruction>[]; 5550 argumentValues = <HInstruction>[];
5412 argumentNodes.forEach((argumentNode) { 5551 argumentNodes.forEach((argumentNode) {
(...skipping 12 matching lines...) Expand all
5425 graph.addConstantString(new ast.DartString.literal(name), compiler); 5564 graph.addConstantString(new ast.DartString.literal(name), compiler);
5426 existingNames.add(nameConstant); 5565 existingNames.add(nameConstant);
5427 } 5566 }
5428 existingNamesList = buildLiteralList(existingNames); 5567 existingNamesList = buildLiteralList(existingNames);
5429 add(existingNamesList); 5568 add(existingNamesList);
5430 } else { 5569 } else {
5431 existingNamesList = graph.addConstantNull(compiler); 5570 existingNamesList = graph.addConstantNull(compiler);
5432 } 5571 }
5433 pushInvokeStatic(diagnosticNode, 5572 pushInvokeStatic(diagnosticNode,
5434 helper, 5573 helper,
5435 [receiver, name, arguments, existingNamesList]); 5574 [receiver, name, arguments, existingNamesList],
5575 sourceInformation: sourceInformation);
5436 } 5576 }
5437 5577
5438 /** 5578 /**
5439 * Generate code to throw a [NoSuchMethodError] exception for calling a 5579 * Generate code to throw a [NoSuchMethodError] exception for calling a
5440 * method with a wrong number of arguments or mismatching named optional 5580 * method with a wrong number of arguments or mismatching named optional
5441 * arguments. 5581 * arguments.
5442 */ 5582 */
5443 void generateWrongArgumentCountError(ast.Node diagnosticNode, 5583 void generateWrongArgumentCountError(ast.Node diagnosticNode,
5444 FunctionElement function, 5584 FunctionElement function,
5445 Link<ast.Node> argumentNodes) { 5585 Link<ast.Node> argumentNodes) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5504 ast.NodeList arguments, 5644 ast.NodeList arguments,
5505 CallStructure callStructure, 5645 CallStructure callStructure,
5506 _) { 5646 _) {
5507 bulkHandleNew(node); 5647 bulkHandleNew(node);
5508 } 5648 }
5509 5649
5510 void pushInvokeDynamic(ast.Node node, 5650 void pushInvokeDynamic(ast.Node node,
5511 Selector selector, 5651 Selector selector,
5512 TypeMask mask, 5652 TypeMask mask,
5513 List<HInstruction> arguments, 5653 List<HInstruction> arguments,
5514 {ast.Node location}) { 5654 {SourceInformation sourceInformation}) {
5515 if (location == null) location = node;
5516 5655
5517 // We prefer to not inline certain operations on indexables, 5656 // We prefer to not inline certain operations on indexables,
5518 // because the constant folder will handle them better and turn 5657 // because the constant folder will handle them better and turn
5519 // them into simpler instructions that allow further 5658 // them into simpler instructions that allow further
5520 // optimizations. 5659 // optimizations.
5521 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { 5660 bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
5522 bool isLength = selector.isGetter 5661 bool isLength = selector.isGetter
5523 && selector.name == "length"; 5662 && selector.name == "length";
5524 if (isLength || selector.isIndex) { 5663 if (isLength || selector.isIndex) {
5525 TypeMask type = new TypeMask.nonNullExact( 5664 TypeMask type = new TypeMask.nonNullExact(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5564 HInstruction receiver = arguments[0]; 5703 HInstruction receiver = arguments[0];
5565 List<HInstruction> inputs = <HInstruction>[]; 5704 List<HInstruction> inputs = <HInstruction>[];
5566 bool isIntercepted = backend.isInterceptedSelector(selector); 5705 bool isIntercepted = backend.isInterceptedSelector(selector);
5567 if (isIntercepted) { 5706 if (isIntercepted) {
5568 inputs.add(invokeInterceptor(receiver)); 5707 inputs.add(invokeInterceptor(receiver));
5569 } 5708 }
5570 inputs.addAll(arguments); 5709 inputs.addAll(arguments);
5571 TypeMask type = 5710 TypeMask type =
5572 TypeMaskFactory.inferredTypeForSelector(selector, mask, compiler); 5711 TypeMaskFactory.inferredTypeForSelector(selector, mask, compiler);
5573 if (selector.isGetter) { 5712 if (selector.isGetter) {
5574 pushWithPosition( 5713 push(
5575 new HInvokeDynamicGetter(selector, mask, null, inputs, type), 5714 new HInvokeDynamicGetter(selector, mask, null, inputs, type)
5576 location); 5715 ..sourceInformation = sourceInformation);
5577 } else if (selector.isSetter) { 5716 } else if (selector.isSetter) {
5578 pushWithPosition( 5717 push(
5579 new HInvokeDynamicSetter(selector, mask, null, inputs, type), 5718 new HInvokeDynamicSetter(selector, mask, null, inputs, type)
5580 location); 5719 ..sourceInformation = sourceInformation);
5581 } else { 5720 } else {
5582 pushWithPosition( 5721 push(
5583 new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted), 5722 new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted)
5584 location); 5723 ..sourceInformation = sourceInformation);
5585 } 5724 }
5586 } 5725 }
5587 5726
5588 void pushInvokeStatic(ast.Node location, 5727 void pushInvokeStatic(ast.Node location,
5589 Element element, 5728 Element element,
5590 List<HInstruction> arguments, 5729 List<HInstruction> arguments,
5591 {TypeMask typeMask, 5730 {TypeMask typeMask,
5592 InterfaceType instanceType}) { 5731 InterfaceType instanceType,
5732 SourceInformation sourceInformation}) {
5733 // TODO(johnniwinther): Use [sourceInformation] instead of [location].
5593 if (tryInlineMethod(element, null, null, arguments, location, 5734 if (tryInlineMethod(element, null, null, arguments, location,
5594 instanceType: instanceType)) { 5735 instanceType: instanceType)) {
5595 return; 5736 return;
5596 } 5737 }
5597 5738
5598 if (typeMask == null) { 5739 if (typeMask == null) {
5599 typeMask = 5740 typeMask =
5600 TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 5741 TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
5601 } 5742 }
5602 bool targetCanThrow = !compiler.world.getCannotThrow(element); 5743 bool targetCanThrow = !compiler.world.getCannotThrow(element);
5603 // TODO(5346): Try to avoid the need for calling [declaration] before 5744 // TODO(5346): Try to avoid the need for calling [declaration] before
5604 // creating an [HInvokeStatic]. 5745 // creating an [HInvokeStatic].
5605 HInvokeStatic instruction = new HInvokeStatic( 5746 HInvokeStatic instruction = new HInvokeStatic(
5606 element.declaration, arguments, typeMask, 5747 element.declaration, arguments, typeMask,
5607 targetCanThrow: targetCanThrow); 5748 targetCanThrow: targetCanThrow)
5749 ..sourceInformation = sourceInformation;
5608 if (!currentInlinedInstantiations.isEmpty) { 5750 if (!currentInlinedInstantiations.isEmpty) {
5609 instruction.instantiatedTypes = new List<DartType>.from( 5751 instruction.instantiatedTypes = new List<DartType>.from(
5610 currentInlinedInstantiations); 5752 currentInlinedInstantiations);
5611 } 5753 }
5612 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); 5754 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element);
5613 if (location == null) { 5755 if (location == null) {
5614 push(instruction); 5756 push(instruction);
5615 } else { 5757 } else {
5616 pushWithPosition(instruction, location); 5758 pushWithPosition(instruction, location);
5617 } 5759 }
5618 } 5760 }
5619 5761
5620 HInstruction buildInvokeSuper(Selector selector, 5762 HInstruction buildInvokeSuper(Selector selector,
5621 Element element, 5763 Element element,
5622 List<HInstruction> arguments) { 5764 List<HInstruction> arguments,
5765 [SourceInformation sourceInformation]) {
5623 HInstruction receiver = localsHandler.readThis(); 5766 HInstruction receiver = localsHandler.readThis();
5624 // TODO(5346): Try to avoid the need for calling [declaration] before 5767 // TODO(5346): Try to avoid the need for calling [declaration] before
5625 // creating an [HStatic]. 5768 // creating an [HStatic].
5626 List<HInstruction> inputs = <HInstruction>[]; 5769 List<HInstruction> inputs = <HInstruction>[];
5627 if (backend.isInterceptedSelector(selector) && 5770 if (backend.isInterceptedSelector(selector) &&
5628 // Fields don't need an interceptor; consider generating HFieldGet/Set 5771 // Fields don't need an interceptor; consider generating HFieldGet/Set
5629 // instead. 5772 // instead.
5630 element.kind != ElementKind.FIELD) { 5773 element.kind != ElementKind.FIELD) {
5631 inputs.add(invokeInterceptor(receiver)); 5774 inputs.add(invokeInterceptor(receiver));
5632 } 5775 }
5633 inputs.add(receiver); 5776 inputs.add(receiver);
5634 inputs.addAll(arguments); 5777 inputs.addAll(arguments);
5635 TypeMask type; 5778 TypeMask type;
5636 if (!element.isGetter && selector.isGetter) { 5779 if (!element.isGetter && selector.isGetter) {
5637 type = TypeMaskFactory.inferredTypeForElement(element, compiler); 5780 type = TypeMaskFactory.inferredTypeForElement(element, compiler);
5638 } else { 5781 } else {
5639 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 5782 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
5640 } 5783 }
5641 HInstruction instruction = new HInvokeSuper( 5784 HInstruction instruction = new HInvokeSuper(
5642 element, 5785 element,
5643 currentNonClosureClass, 5786 currentNonClosureClass,
5644 selector, 5787 selector,
5645 inputs, 5788 inputs,
5646 type, 5789 type,
5790 sourceInformation,
5647 isSetter: selector.isSetter || selector.isIndexSet); 5791 isSetter: selector.isSetter || selector.isIndexSet);
5648 instruction.sideEffects = 5792 instruction.sideEffects =
5649 compiler.world.getSideEffectsOfSelector(selector, null); 5793 compiler.world.getSideEffectsOfSelector(selector, null);
5650 return instruction; 5794 return instruction;
5651 } 5795 }
5652 5796
5653 void handleComplexOperatorSend(ast.SendSet node, 5797 void handleComplexOperatorSend(ast.SendSet node,
5654 HInstruction receiver, 5798 HInstruction receiver,
5655 Link<ast.Node> arguments) { 5799 Link<ast.Node> arguments) {
5656 HInstruction rhs; 5800 HInstruction rhs;
5657 if (node.isPrefix || node.isPostfix) { 5801 if (node.isPrefix || node.isPostfix) {
5658 rhs = graph.addConstantInt(1, compiler); 5802 rhs = graph.addConstantInt(1, compiler);
5659 } else { 5803 } else {
5660 visit(arguments.head); 5804 visit(arguments.head);
5661 assert(arguments.tail.isEmpty); 5805 assert(arguments.tail.isEmpty);
5662 rhs = pop(); 5806 rhs = pop();
5663 } 5807 }
5664 visitBinarySend(receiver, rhs, 5808 visitBinarySend(
5665 elements.getOperatorSelectorInComplexSendSet(node), 5809 receiver,
5666 elements.getOperatorTypeMaskInComplexSendSet(node), 5810 rhs,
5667 node, 5811 elements.getOperatorSelectorInComplexSendSet(node),
5668 location: node.assignmentOperator); 5812 elements.getOperatorTypeMaskInComplexSendSet(node),
5813 node,
5814 sourceInformation:
5815 sourceInformationBuilder.buildGeneric(node.assignmentOperator));
5669 } 5816 }
5670 5817
5671 void handleSuperSendSet(ast.SendSet node) { 5818 void handleSuperSendSet(ast.SendSet node) {
5672 Element element = elements[node]; 5819 Element element = elements[node];
5673 List<HInstruction> setterInputs = <HInstruction>[]; 5820 List<HInstruction> setterInputs = <HInstruction>[];
5674 void generateSuperSendSet() { 5821 void generateSuperSendSet() {
5675 Selector setterSelector = elements.getSelector(node); 5822 Selector setterSelector = elements.getSelector(node);
5676 if (Elements.isUnresolved(element) 5823 if (Elements.isUnresolved(element)
5677 || !setterSelector.applies(element, compiler.world)) { 5824 || !setterSelector.applies(element, compiler.world)) {
5678 generateSuperNoSuchMethodSend( 5825 generateSuperNoSuchMethodSend(
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
6518 6665
6519 if (getter.isErroneous) { 6666 if (getter.isErroneous) {
6520 generateStaticUnresolvedGet(node, getter); 6667 generateStaticUnresolvedGet(node, getter);
6521 } else if (getter.isField) { 6668 } else if (getter.isField) {
6522 generateStaticFieldGet(node, getter); 6669 generateStaticFieldGet(node, getter);
6523 } else if (getter.isGetter) { 6670 } else if (getter.isGetter) {
6524 generateStaticGetterGet(node, getter); 6671 generateStaticGetterGet(node, getter);
6525 } else if (getter.isFunction) { 6672 } else if (getter.isFunction) {
6526 generateStaticFunctionGet(node, getter); 6673 generateStaticFunctionGet(node, getter);
6527 } else if (getter.isLocal) { 6674 } else if (getter.isLocal) {
6528 handleLocalGet(getter); 6675 handleLocalGet(node, getter);
6529 } else { 6676 } else {
6530 internalError(node, "Unexpected getter: $getter"); 6677 internalError(node, "Unexpected getter: $getter");
6531 } 6678 }
6532 HInstruction getterInstruction = pop(); 6679 HInstruction getterInstruction = pop();
6533 if (node.isIfNullAssignment) { 6680 if (node.isIfNullAssignment) {
6534 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); 6681 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node);
6535 brancher.handleIfNull(() => stack.add(getterInstruction), 6682 brancher.handleIfNull(() => stack.add(getterInstruction),
6536 () { 6683 () {
6537 visit(node.arguments.head); 6684 visit(node.arguments.head);
6538 generateNonInstanceSetter(node, element, pop()); 6685 generateNonInstanceSetter(node, element, pop());
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
6658 } 6805 }
6659 6806
6660 visitRethrow(ast.Rethrow node) { 6807 visitRethrow(ast.Rethrow node) {
6661 HInstruction exception = rethrowableException; 6808 HInstruction exception = rethrowableException;
6662 if (exception == null) { 6809 if (exception == null) {
6663 exception = graph.addConstantNull(compiler); 6810 exception = graph.addConstantNull(compiler);
6664 compiler.internalError(node, 6811 compiler.internalError(node,
6665 'rethrowableException should not be null.'); 6812 'rethrowableException should not be null.');
6666 } 6813 }
6667 handleInTryStatement(); 6814 handleInTryStatement();
6668 closeAndGotoExit(new HThrow(exception, isRethrow: true)); 6815 closeAndGotoExit(
6816 new HThrow(exception,
6817 sourceInformationBuilder.buildThrow(node),
6818 isRethrow: true));
6669 } 6819 }
6670 6820
6671 visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { 6821 visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
6672 ConstructorElement targetConstructor = 6822 ConstructorElement targetConstructor =
6673 elements.getRedirectingTargetConstructor(node).implementation; 6823 elements.getRedirectingTargetConstructor(node).implementation;
6674 ConstructorElement redirectingConstructor = sourceElement.implementation; 6824 ConstructorElement redirectingConstructor = sourceElement.implementation;
6675 List<HInstruction> inputs = <HInstruction>[]; 6825 List<HInstruction> inputs = <HInstruction>[];
6676 FunctionSignature targetSignature = targetConstructor.functionSignature; 6826 FunctionSignature targetSignature = targetConstructor.functionSignature;
6677 FunctionSignature redirectingSignature = 6827 FunctionSignature redirectingSignature =
6678 redirectingConstructor.functionSignature; 6828 redirectingConstructor.functionSignature;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
6755 } 6905 }
6756 6906
6757 handleInTryStatement(); 6907 handleInTryStatement();
6758 emitReturn(value, node); 6908 emitReturn(value, node);
6759 } 6909 }
6760 6910
6761 visitThrow(ast.Throw node) { 6911 visitThrow(ast.Throw node) {
6762 visitThrowExpression(node.expression); 6912 visitThrowExpression(node.expression);
6763 if (isReachable) { 6913 if (isReachable) {
6764 handleInTryStatement(); 6914 handleInTryStatement();
6765 push(new HThrowExpression(pop())); 6915 push(new HThrowExpression(
6916 pop(), sourceInformationBuilder.buildThrow(node)));
6766 isReachable = false; 6917 isReachable = false;
6767 } 6918 }
6768 } 6919 }
6769 6920
6770 visitYield(ast.Yield node) { 6921 visitYield(ast.Yield node) {
6771 visit(node.expression); 6922 visit(node.expression);
6772 HInstruction yielded = pop(); 6923 HInstruction yielded = pop();
6773 add(new HYield(yielded, node.hasStar)); 6924 add(new HYield(yielded, node.hasStar));
6774 } 6925 }
6775 6926
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
7529 // If the switch statement has no default case, surround the loop with 7680 // If the switch statement has no default case, surround the loop with
7530 // a test of the target. 7681 // a test of the target.
7531 void buildCondition() { 7682 void buildCondition() {
7532 js.Template code = js.js.parseForeignJS('#'); 7683 js.Template code = js.js.parseForeignJS('#');
7533 push(new HForeignCode( 7684 push(new HForeignCode(
7534 code, 7685 code,
7535 backend.boolType, 7686 backend.boolType,
7536 [localsHandler.readLocal(switchTarget)], 7687 [localsHandler.readLocal(switchTarget)],
7537 nativeBehavior: native.NativeBehavior.PURE)); 7688 nativeBehavior: native.NativeBehavior.PURE));
7538 } 7689 }
7539 handleIf(node, buildCondition, buildLoop, () => {}); 7690 handleIf(node,
7691 visitCondition: buildCondition,
7692 visitThen: buildLoop,
7693 visitElse: () => {});
7540 } 7694 }
7541 } 7695 }
7542 7696
7543 /** 7697 /**
7544 * Creates a switch statement. 7698 * Creates a switch statement.
7545 * 7699 *
7546 * [jumpHandler] is the [JumpHandler] for the created switch statement. 7700 * [jumpHandler] is the [JumpHandler] for the created switch statement.
7547 * [buildExpression] creates the switch expression. 7701 * [buildExpression] creates the switch expression.
7548 * [switchCases] must be either an [Iterable] of [ast.SwitchCase] nodes or 7702 * [switchCases] must be either an [Iterable] of [ast.SwitchCase] nodes or
7549 * a [Link] or a [ast.NodeList] of [ast.SwitchCase] nodes. 7703 * a [Link] or a [ast.NodeList] of [ast.SwitchCase] nodes.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
7592 expressionEnd.addSuccessor(block); 7746 expressionEnd.addSuccessor(block);
7593 hasDefault = true; 7747 hasDefault = true;
7594 } 7748 }
7595 open(block); 7749 open(block);
7596 localsHandler = new LocalsHandler.from(savedLocals); 7750 localsHandler = new LocalsHandler.from(savedLocals);
7597 buildSwitchCase(switchCase); 7751 buildSwitchCase(switchCase);
7598 if (!isAborted()) { 7752 if (!isAborted()) {
7599 if (caseIterator.hasNext) { 7753 if (caseIterator.hasNext) {
7600 pushInvokeStatic(switchCase, getFallThroughErrorElement, []); 7754 pushInvokeStatic(switchCase, getFallThroughErrorElement, []);
7601 HInstruction error = pop(); 7755 HInstruction error = pop();
7602 closeAndGotoExit(new HThrow(error)); 7756 closeAndGotoExit(new HThrow(error, error.sourceInformation));
7603 } else if (!isDefaultCase(switchCase)) { 7757 } else if (!isDefaultCase(switchCase)) {
7604 // If there is no default, we will add one later to avoid 7758 // If there is no default, we will add one later to avoid
7605 // the critical edge. So we generate a break statement to make 7759 // the critical edge. So we generate a break statement to make
7606 // sure the last case does not fall through to the default case. 7760 // sure the last case does not fall through to the default case.
7607 jumpHandler.generateBreak(); 7761 jumpHandler.generateBreak();
7608 } 7762 }
7609 } 7763 }
7610 statements.add( 7764 statements.add(
7611 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); 7765 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock)));
7612 } 7766 }
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
7868 pushInvokeStatic(trace, backend.getTraceFromException(), [exception]); 8022 pushInvokeStatic(trace, backend.getTraceFromException(), [exception]);
7869 HInstruction traceInstruction = pop(); 8023 HInstruction traceInstruction = pop();
7870 LocalVariableElement traceVariable = elements[trace]; 8024 LocalVariableElement traceVariable = elements[trace];
7871 localsHandler.updateLocal(traceVariable, traceInstruction); 8025 localsHandler.updateLocal(traceVariable, traceInstruction);
7872 } 8026 }
7873 visit(catchBlock); 8027 visit(catchBlock);
7874 } 8028 }
7875 8029
7876 void visitElse() { 8030 void visitElse() {
7877 if (link.isEmpty) { 8031 if (link.isEmpty) {
7878 closeAndGotoExit(new HThrow(exception, isRethrow: true)); 8032 closeAndGotoExit(
8033 new HThrow(exception,
8034 exception.sourceInformation,
8035 isRethrow: true));
7879 } else { 8036 } else {
7880 ast.CatchBlock newBlock = link.head; 8037 ast.CatchBlock newBlock = link.head;
7881 handleIf(node, 8038 handleIf(node,
7882 () { pushCondition(newBlock); }, 8039 visitCondition: () { pushCondition(newBlock); },
7883 visitThen, visitElse); 8040 visitThen: visitThen,
8041 visitElse: visitElse);
7884 } 8042 }
7885 } 8043 }
7886 8044
7887 ast.CatchBlock firstBlock = link.head; 8045 ast.CatchBlock firstBlock = link.head;
7888 handleIf(node, () { pushCondition(firstBlock); }, visitThen, visitElse); 8046 handleIf(node,
8047 visitCondition: () { pushCondition(firstBlock); },
8048 visitThen: visitThen,
8049 visitElse: visitElse);
7889 if (!isAborted()) endCatchBlock = close(new HGoto()); 8050 if (!isAborted()) endCatchBlock = close(new HGoto());
7890 8051
7891 rethrowableException = oldRethrowableException; 8052 rethrowableException = oldRethrowableException;
7892 tryInstruction.catchBlock = startCatchBlock; 8053 tryInstruction.catchBlock = startCatchBlock;
7893 catchGraph = new SubGraph(startCatchBlock, lastOpenedBlock); 8054 catchGraph = new SubGraph(startCatchBlock, lastOpenedBlock);
7894 } 8055 }
7895 8056
7896 SubGraph finallyGraph = null; 8057 SubGraph finallyGraph = null;
7897 if (node.finallyBlock != null) { 8058 if (node.finallyBlock != null) {
7898 localsHandler = new LocalsHandler.from(savedLocals); 8059 localsHandler = new LocalsHandler.from(savedLocals);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
8009 restoreState(state); 8170 restoreState(state);
8010 stack.add(result); 8171 stack.add(result);
8011 } 8172 }
8012 8173
8013 void doInline(FunctionElement function) { 8174 void doInline(FunctionElement function) {
8014 visitInlinedFunction(function); 8175 visitInlinedFunction(function);
8015 } 8176 }
8016 8177
8017 void emitReturn(HInstruction value, ast.Node node) { 8178 void emitReturn(HInstruction value, ast.Node node) {
8018 if (inliningStack.isEmpty) { 8179 if (inliningStack.isEmpty) {
8019 closeAndGotoExit(attachPosition(new HReturn(value), node)); 8180 closeAndGotoExit(new HReturn(value,
8181 sourceInformationBuilder.buildReturn(node)));
8020 } else { 8182 } else {
8021 localsHandler.updateLocal(returnLocal, value); 8183 localsHandler.updateLocal(returnLocal, value);
8022 } 8184 }
8023 } 8185 }
8024 8186
8025 @override 8187 @override
8026 void handleTypeLiteralConstantCompounds( 8188 void handleTypeLiteralConstantCompounds(
8027 ast.SendSet node, 8189 ast.SendSet node,
8028 ConstantExpression constant, 8190 ConstantExpression constant,
8029 CompoundRhs rhs, 8191 CompoundRhs rhs,
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
8368 8530
8369 void checkNotAborted() { 8531 void checkNotAborted() {
8370 if (builder.isAborted()) { 8532 if (builder.isAborted()) {
8371 compiler.unimplemented(diagnosticNode, "aborted control flow"); 8533 compiler.unimplemented(diagnosticNode, "aborted control flow");
8372 } 8534 }
8373 } 8535 }
8374 8536
8375 void buildCondition(void visitCondition(), 8537 void buildCondition(void visitCondition(),
8376 SsaBranch conditionBranch, 8538 SsaBranch conditionBranch,
8377 SsaBranch thenBranch, 8539 SsaBranch thenBranch,
8378 SsaBranch elseBranch) { 8540 SsaBranch elseBranch,
8541 SourceInformation sourceInformation) {
8379 startBranch(conditionBranch); 8542 startBranch(conditionBranch);
8380 visitCondition(); 8543 visitCondition();
8381 checkNotAborted(); 8544 checkNotAborted();
8382 assert(identical(builder.current, builder.lastOpenedBlock)); 8545 assert(identical(builder.current, builder.lastOpenedBlock));
8383 HInstruction conditionValue = builder.popBoolified(); 8546 HInstruction conditionValue = builder.popBoolified();
8384 HIf branch = new HIf(conditionValue); 8547 HIf branch = new HIf(conditionValue)..sourceInformation = sourceInformation;
8385 HBasicBlock conditionExitBlock = builder.current; 8548 HBasicBlock conditionExitBlock = builder.current;
8386 builder.close(branch); 8549 builder.close(branch);
8387 conditionBranch.exitLocals = builder.localsHandler; 8550 conditionBranch.exitLocals = builder.localsHandler;
8388 conditionExitBlock.addSuccessor(thenBranch.block); 8551 conditionExitBlock.addSuccessor(thenBranch.block);
8389 conditionExitBlock.addSuccessor(elseBranch.block); 8552 conditionExitBlock.addSuccessor(elseBranch.block);
8390 bool conditionBranchLocalsCanBeReused = 8553 bool conditionBranchLocalsCanBeReused =
8391 mergeLocals(conditionBranch, thenBranch, mayReuseFromLocals: true); 8554 mergeLocals(conditionBranch, thenBranch, mayReuseFromLocals: true);
8392 mergeLocals(conditionBranch, elseBranch, 8555 mergeLocals(conditionBranch, elseBranch,
8393 mayReuseFromLocals: conditionBranchLocalsCanBeReused); 8556 mayReuseFromLocals: conditionBranchLocalsCanBeReused);
8394 8557
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
8435 builder.goto(builder.current, joinBranch.block); 8598 builder.goto(builder.current, joinBranch.block);
8436 mergeLocals(branch, joinBranch, mayReuseFromLocals: true); 8599 mergeLocals(branch, joinBranch, mayReuseFromLocals: true);
8437 } 8600 }
8438 if (isExpression) { 8601 if (isExpression) {
8439 checkNotAborted(); 8602 checkNotAborted();
8440 return builder.pop(); 8603 return builder.pop();
8441 } 8604 }
8442 return null; 8605 return null;
8443 } 8606 }
8444 8607
8445 handleIf(void visitCondition(), void visitThen(), void visitElse()) { 8608 handleIf(void visitCondition(),
8609 void visitThen(),
8610 void visitElse(),
8611 {SourceInformation sourceInformation}) {
8446 if (visitElse == null) { 8612 if (visitElse == null) {
8447 // Make sure to have an else part to avoid a critical edge. A 8613 // Make sure to have an else part to avoid a critical edge. A
8448 // critical edge is an edge that connects a block with multiple 8614 // critical edge is an edge that connects a block with multiple
8449 // successors to a block with multiple predecessors. We avoid 8615 // successors to a block with multiple predecessors. We avoid
8450 // such edges because they prevent inserting copies during code 8616 // such edges because they prevent inserting copies during code
8451 // generation of phi instructions. 8617 // generation of phi instructions.
8452 visitElse = () {}; 8618 visitElse = () {};
8453 } 8619 }
8454 8620
8455 _handleDiamondBranch(visitCondition, visitThen, visitElse, false); 8621 _handleDiamondBranch(
8622 visitCondition, visitThen, visitElse, isExpression: false,
8623 sourceInformation: sourceInformation);
8456 } 8624 }
8457 8625
8458 handleConditional(void visitCondition(), void visitThen(), void visitElse()) { 8626 handleConditional(void visitCondition(),
8627 void visitThen(),
8628 void visitElse()) {
8459 assert(visitElse != null); 8629 assert(visitElse != null);
8460 _handleDiamondBranch(visitCondition, visitThen, visitElse, true); 8630 _handleDiamondBranch(
8631 visitCondition, visitThen, visitElse, isExpression: true);
8461 } 8632 }
8462 8633
8463 handleIfNull(void left(), void right()) { 8634 handleIfNull(void left(), void right()) {
8464 // x ?? y is transformed into: x == null ? y : x 8635 // x ?? y is transformed into: x == null ? y : x
8465 HInstruction leftExpression; 8636 HInstruction leftExpression;
8466 handleConditional( 8637 handleConditional(
8467 () { 8638 () {
8468 left(); 8639 left();
8469 leftExpression = builder.pop(); 8640 leftExpression = builder.pop();
8470 builder.pushCheckNull(leftExpression); 8641 builder.pushCheckNull(leftExpression);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
8545 isAnd: isAnd), 8716 isAnd: isAnd),
8546 isAnd: isAnd); 8717 isAnd: isAnd);
8547 } else { 8718 } else {
8548 handleLogicalAndOr(() => builder.visit(left), visitRight, isAnd: isAnd); 8719 handleLogicalAndOr(() => builder.visit(left), visitRight, isAnd: isAnd);
8549 } 8720 }
8550 } 8721 }
8551 8722
8552 void _handleDiamondBranch(void visitCondition(), 8723 void _handleDiamondBranch(void visitCondition(),
8553 void visitThen(), 8724 void visitThen(),
8554 void visitElse(), 8725 void visitElse(),
8555 bool isExpression) { 8726 {bool isExpression,
8727 SourceInformation sourceInformation}) {
8556 SsaBranch conditionBranch = new SsaBranch(this); 8728 SsaBranch conditionBranch = new SsaBranch(this);
8557 SsaBranch thenBranch = new SsaBranch(this); 8729 SsaBranch thenBranch = new SsaBranch(this);
8558 SsaBranch elseBranch = new SsaBranch(this); 8730 SsaBranch elseBranch = new SsaBranch(this);
8559 SsaBranch joinBranch = new SsaBranch(this); 8731 SsaBranch joinBranch = new SsaBranch(this);
8560 8732
8561 conditionBranch.startLocals = builder.localsHandler; 8733 conditionBranch.startLocals = builder.localsHandler;
8562 builder.goto(builder.current, conditionBranch.block); 8734 builder.goto(builder.current, conditionBranch.block);
8563 8735
8564 buildCondition(visitCondition, conditionBranch, thenBranch, elseBranch); 8736 buildCondition(visitCondition, conditionBranch, thenBranch, elseBranch,
8737 sourceInformation);
8565 HInstruction thenValue = 8738 HInstruction thenValue =
8566 buildBranch(thenBranch, visitThen, joinBranch, isExpression); 8739 buildBranch(thenBranch, visitThen, joinBranch, isExpression);
8567 HInstruction elseValue = 8740 HInstruction elseValue =
8568 buildBranch(elseBranch, visitElse, joinBranch, isExpression); 8741 buildBranch(elseBranch, visitElse, joinBranch, isExpression);
8569 8742
8570 if (isExpression) { 8743 if (isExpression) {
8571 assert(thenValue != null && elseValue != null); 8744 assert(thenValue != null && elseValue != null);
8572 JavaScriptBackend backend = builder.backend; 8745 JavaScriptBackend backend = builder.backend;
8573 HPhi phi = new HPhi.manyInputs( 8746 HPhi phi = new HPhi.manyInputs(
8574 null, <HInstruction>[thenValue, elseValue], backend.dynamicType); 8747 null, <HInstruction>[thenValue, elseValue], backend.dynamicType);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
8684 if (unaliased is TypedefType) throw 'unable to unalias $type'; 8857 if (unaliased is TypedefType) throw 'unable to unalias $type';
8685 unaliased.accept(this, builder); 8858 unaliased.accept(this, builder);
8686 } 8859 }
8687 8860
8688 void visitDynamicType(DynamicType type, SsaBuilder builder) { 8861 void visitDynamicType(DynamicType type, SsaBuilder builder) {
8689 JavaScriptBackend backend = builder.compiler.backend; 8862 JavaScriptBackend backend = builder.compiler.backend;
8690 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 8863 ClassElement cls = backend.findHelper('DynamicRuntimeType');
8691 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 8864 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
8692 } 8865 }
8693 } 8866 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/source_file_provider.dart ('k') | pkg/compiler/lib/src/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698