| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library tree_ir_builder; | 5 library tree_ir_builder; |
| 6 | 6 |
| 7 import 'package:js_ast/js_ast.dart' as js; |
| 8 |
| 7 import '../common.dart'; | 9 import '../common.dart'; |
| 8 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; | 11 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; |
| 10 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
| 11 import 'package:js_ast/js_ast.dart' as js; | 13 import '../io/source_information.dart'; |
| 12 import '../js_backend/codegen/glue.dart'; | 14 import '../js_backend/codegen/glue.dart'; |
| 13 | 15 |
| 14 import 'tree_ir_nodes.dart'; | 16 import 'tree_ir_nodes.dart'; |
| 15 | 17 |
| 16 typedef Statement NodeCallback(Statement next); | 18 typedef Statement NodeCallback(Statement next); |
| 17 | 19 |
| 18 /** | 20 /** |
| 19 * Builder translates from CPS-based IR to direct-style Tree. | 21 * Builder translates from CPS-based IR to direct-style Tree. |
| 20 * | 22 * |
| 21 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced | 23 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 Variable variable = new Variable(currentElement, irVariable.hint); | 80 Variable variable = new Variable(currentElement, irVariable.hint); |
| 79 mutable2variable[irVariable] = variable; | 81 mutable2variable[irVariable] = variable; |
| 80 return variable; | 82 return variable; |
| 81 } | 83 } |
| 82 | 84 |
| 83 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) { | 85 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) { |
| 84 return mutable2variable[mutableVariable]; | 86 return mutable2variable[mutableVariable]; |
| 85 } | 87 } |
| 86 | 88 |
| 87 VariableUse getMutableVariableUse( | 89 VariableUse getMutableVariableUse( |
| 88 cps_ir.Reference<cps_ir.MutableVariable> reference) { | 90 cps_ir.Reference<cps_ir.MutableVariable> reference, |
| 91 SourceInformation sourceInformation) { |
| 89 Variable variable = getMutableVariable(reference.definition); | 92 Variable variable = getMutableVariable(reference.definition); |
| 90 return new VariableUse(variable); | 93 return new VariableUse(variable, sourceInformation: sourceInformation); |
| 91 } | 94 } |
| 92 | 95 |
| 93 /// Obtains the variable representing the given primitive. Returns null for | 96 /// Obtains the variable representing the given primitive. Returns null for |
| 94 /// primitives that have no reference and do not need a variable. | 97 /// primitives that have no reference and do not need a variable. |
| 95 Variable getVariable(cps_ir.Primitive primitive) { | 98 Variable getVariable(cps_ir.Primitive primitive) { |
| 96 primitive = primitive.effectiveDefinition; | 99 primitive = primitive.effectiveDefinition; |
| 97 return primitive2variable.putIfAbsent(primitive, | 100 return primitive2variable.putIfAbsent(primitive, |
| 98 () => new Variable(currentElement, primitive.hint)); | 101 () => new Variable(currentElement, primitive.hint)); |
| 99 } | 102 } |
| 100 | 103 |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 | 479 |
| 477 | 480 |
| 478 /************************** PRIMITIVES **************************/ | 481 /************************** PRIMITIVES **************************/ |
| 479 // | 482 // |
| 480 // Visit methods for primitives must return an expression. | 483 // Visit methods for primitives must return an expression. |
| 481 // | 484 // |
| 482 | 485 |
| 483 Expression visitSetField(cps_ir.SetField node) { | 486 Expression visitSetField(cps_ir.SetField node) { |
| 484 return new SetField(getVariableUse(node.objectRef), | 487 return new SetField(getVariableUse(node.objectRef), |
| 485 node.field, | 488 node.field, |
| 486 getVariableUse(node.valueRef)); | 489 getVariableUse(node.valueRef), |
| 490 node.sourceInformation); |
| 487 } | 491 } |
| 488 | 492 |
| 489 Expression visitInterceptor(cps_ir.Interceptor node) { | 493 Expression visitInterceptor(cps_ir.Interceptor node) { |
| 490 return new Interceptor(getVariableUse(node.inputRef), | 494 return new Interceptor(getVariableUse(node.inputRef), |
| 491 node.interceptedClasses, | 495 node.interceptedClasses, |
| 492 node.sourceInformation); | 496 node.sourceInformation); |
| 493 } | 497 } |
| 494 | 498 |
| 495 Expression visitCreateInstance(cps_ir.CreateInstance node) { | 499 Expression visitCreateInstance(cps_ir.CreateInstance node) { |
| 496 return new CreateInstance( | 500 return new CreateInstance( |
| 497 node.classElement, | 501 node.classElement, |
| 498 translateArguments(node.argumentRefs), | 502 translateArguments(node.argumentRefs), |
| 499 getVariableUseOrNull(node.typeInformationRef), | 503 getVariableUseOrNull(node.typeInformationRef), |
| 500 node.sourceInformation); | 504 node.sourceInformation); |
| 501 } | 505 } |
| 502 | 506 |
| 503 Expression visitGetField(cps_ir.GetField node) { | 507 Expression visitGetField(cps_ir.GetField node) { |
| 504 return new GetField(getVariableUse(node.objectRef), node.field, | 508 return new GetField(getVariableUse(node.objectRef), node.field, |
| 505 objectIsNotNull: !node.object.type.isNullable); | 509 node.sourceInformation, objectIsNotNull: !node.object.type.isNullable); |
| 506 } | 510 } |
| 507 | 511 |
| 508 Expression visitCreateBox(cps_ir.CreateBox node) { | 512 Expression visitCreateBox(cps_ir.CreateBox node) { |
| 509 return new CreateBox(); | 513 return new CreateBox(); |
| 510 } | 514 } |
| 511 | 515 |
| 512 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) { | 516 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) { |
| 513 return new CreateInvocationMirror( | 517 return new CreateInvocationMirror( |
| 514 node.selector, | 518 node.selector, |
| 515 translateArguments(node.argumentRefs)); | 519 translateArguments(node.argumentRefs)); |
| 516 } | 520 } |
| 517 | 521 |
| 518 Expression visitGetMutable(cps_ir.GetMutable node) { | 522 Expression visitGetMutable(cps_ir.GetMutable node) { |
| 519 return getMutableVariableUse(node.variableRef); | 523 return getMutableVariableUse(node.variableRef, node.sourceInformation); |
| 520 } | 524 } |
| 521 | 525 |
| 522 Expression visitSetMutable(cps_ir.SetMutable node) { | 526 Expression visitSetMutable(cps_ir.SetMutable node) { |
| 523 Variable variable = getMutableVariable(node.variable); | 527 Variable variable = getMutableVariable(node.variable); |
| 524 Expression value = getVariableUse(node.valueRef); | 528 Expression value = getVariableUse(node.valueRef); |
| 525 return new Assign(variable, value); | 529 return new Assign( |
| 530 variable, value, sourceInformation: node.sourceInformation); |
| 526 } | 531 } |
| 527 | 532 |
| 528 Expression visitConstant(cps_ir.Constant node) { | 533 Expression visitConstant(cps_ir.Constant node) { |
| 529 return new Constant(node.value, sourceInformation: node.sourceInformation); | 534 return new Constant(node.value, sourceInformation: node.sourceInformation); |
| 530 } | 535 } |
| 531 | 536 |
| 532 Expression visitLiteralList(cps_ir.LiteralList node) { | 537 Expression visitLiteralList(cps_ir.LiteralList node) { |
| 533 return new LiteralList( | 538 return new LiteralList( |
| 534 node.dartType, | 539 node.dartType, |
| 535 translateArguments(node.valueRefs)); | 540 translateArguments(node.valueRefs)); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 List<bool> nullableArguments = node.argumentRefs | 722 List<bool> nullableArguments = node.argumentRefs |
| 718 .map((argument) => argument.definition.type.isNullable) | 723 .map((argument) => argument.definition.type.isNullable) |
| 719 .toList(growable: false); | 724 .toList(growable: false); |
| 720 if (node.codeTemplate.isExpression) { | 725 if (node.codeTemplate.isExpression) { |
| 721 return new ForeignExpression( | 726 return new ForeignExpression( |
| 722 node.codeTemplate, | 727 node.codeTemplate, |
| 723 node.type, | 728 node.type, |
| 724 arguments, | 729 arguments, |
| 725 node.nativeBehavior, | 730 node.nativeBehavior, |
| 726 nullableArguments, | 731 nullableArguments, |
| 727 node.dependency); | 732 node.dependency, |
| 733 node.sourceInformation); |
| 728 } else { | 734 } else { |
| 729 return (Statement next) { | 735 return (Statement next) { |
| 730 assert(next is Unreachable); // We are not using the `next` statement. | 736 assert(next is Unreachable); // We are not using the `next` statement. |
| 731 return new ForeignStatement( | 737 return new ForeignStatement( |
| 732 node.codeTemplate, | 738 node.codeTemplate, |
| 733 node.type, | 739 node.type, |
| 734 arguments, | 740 arguments, |
| 735 node.nativeBehavior, | 741 node.nativeBehavior, |
| 736 nullableArguments, | 742 nullableArguments, |
| 737 node.dependency); | 743 node.dependency, |
| 744 node.sourceInformation); |
| 738 }; | 745 }; |
| 739 } | 746 } |
| 740 } | 747 } |
| 741 | 748 |
| 742 visitReceiverCheck(cps_ir.ReceiverCheck node) => (Statement next) { | 749 visitReceiverCheck(cps_ir.ReceiverCheck node) => (Statement next) { |
| 743 // The CPS IR uses 'isNullCheck' because the semantics are important. | 750 // The CPS IR uses 'isNullCheck' because the semantics are important. |
| 744 // In the Tree IR, syntax is more important, so the receiver check uses | 751 // In the Tree IR, syntax is more important, so the receiver check uses |
| 745 // "useInvoke" to denote if an invocation should be emitted. | 752 // "useInvoke" to denote if an invocation should be emitted. |
| 746 return new ReceiverCheck( | 753 return new ReceiverCheck( |
| 747 condition: getVariableUseOrNull(node.conditionRef), | 754 condition: getVariableUseOrNull(node.conditionRef), |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 | 789 |
| 783 visitFunctionDefinition(cps_ir.FunctionDefinition node) { | 790 visitFunctionDefinition(cps_ir.FunctionDefinition node) { |
| 784 unexpectedNode(node); | 791 unexpectedNode(node); |
| 785 } | 792 } |
| 786 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); | 793 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); |
| 787 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); | 794 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); |
| 788 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); | 795 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); |
| 789 visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node); | 796 visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node); |
| 790 visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node); | 797 visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node); |
| 791 } | 798 } |
| OLD | NEW |