| 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 code_generator; | 5 library code_generator; |
| 6 | 6 |
| 7 import 'glue.dart'; | 7 import 'glue.dart'; |
| 8 | 8 |
| 9 import '../../closure.dart' show | 9 import '../../closure.dart' show |
| 10 ClosureClassElement; | 10 ClosureClassElement; |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 DartType dartType = node.dartType; | 490 DartType dartType = node.dartType; |
| 491 assert(dartType.isInterfaceType); | 491 assert(dartType.isInterfaceType); |
| 492 registry.registerTypeUse(new TypeUse.isCheck(dartType)); | 492 registry.registerTypeUse(new TypeUse.isCheck(dartType)); |
| 493 //glue.registerIsCheck(dartType, registry); | 493 //glue.registerIsCheck(dartType, registry); |
| 494 js.Expression property = glue.getTypeTestTag(dartType); | 494 js.Expression property = glue.getTypeTestTag(dartType); |
| 495 return js.js(r'#.#', [object, property]); | 495 return js.js(r'#.#', [object, property]); |
| 496 } | 496 } |
| 497 | 497 |
| 498 @override | 498 @override |
| 499 js.Expression visitVariableUse(tree_ir.VariableUse node) { | 499 js.Expression visitVariableUse(tree_ir.VariableUse node) { |
| 500 return buildVariableAccess(node.variable); | 500 return buildVariableAccess(node.variable) |
| 501 .withSourceInformation(node.sourceInformation); |
| 501 } | 502 } |
| 502 | 503 |
| 503 js.Expression buildVariableAccess(tree_ir.Variable variable) { | 504 js.Expression buildVariableAccess(tree_ir.Variable variable) { |
| 504 return new js.VariableUse(getVariableName(variable)); | 505 return new js.VariableUse(getVariableName(variable)); |
| 505 } | 506 } |
| 506 | 507 |
| 507 /// Returns the JS operator for the given built-in operator for use in a | 508 /// Returns the JS operator for the given built-in operator for use in a |
| 508 /// compound assignment (not including the '=' sign). | 509 /// compound assignment (not including the '=' sign). |
| 509 String getAsCompoundOperator(BuiltinOperator operator) { | 510 String getAsCompoundOperator(BuiltinOperator operator) { |
| 510 switch (operator) { | 511 switch (operator) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 530 isCompoundableOperator(exp.operator); | 531 isCompoundableOperator(exp.operator); |
| 531 } | 532 } |
| 532 | 533 |
| 533 bool isOneConstant(tree_ir.Expression exp) { | 534 bool isOneConstant(tree_ir.Expression exp) { |
| 534 return exp is tree_ir.Constant && exp.value.isOne; | 535 return exp is tree_ir.Constant && exp.value.isOne; |
| 535 } | 536 } |
| 536 | 537 |
| 537 js.Expression makeAssignment( | 538 js.Expression makeAssignment( |
| 538 js.Expression leftHand, | 539 js.Expression leftHand, |
| 539 tree_ir.Expression value, | 540 tree_ir.Expression value, |
| 540 {BuiltinOperator compound}) { | 541 {SourceInformation sourceInformation, |
| 542 BuiltinOperator compound}) { |
| 541 if (isOneConstant(value)) { | 543 if (isOneConstant(value)) { |
| 542 if (compound == BuiltinOperator.NumAdd) { | 544 if (compound == BuiltinOperator.NumAdd) { |
| 543 return new js.Prefix('++', leftHand); | 545 return new js.Prefix('++', leftHand) |
| 546 .withSourceInformation(sourceInformation); |
| 544 } | 547 } |
| 545 if (compound == BuiltinOperator.NumSubtract) { | 548 if (compound == BuiltinOperator.NumSubtract) { |
| 546 return new js.Prefix('--', leftHand); | 549 return new js.Prefix('--', leftHand) |
| 550 .withSourceInformation(sourceInformation); |
| 547 } | 551 } |
| 548 } | 552 } |
| 549 if (compound != null) { | 553 if (compound != null) { |
| 550 return new js.Assignment.compound(leftHand, | 554 return new js.Assignment.compound(leftHand, |
| 551 getAsCompoundOperator(compound), visitExpression(value)); | 555 getAsCompoundOperator(compound), visitExpression(value)) |
| 556 .withSourceInformation(sourceInformation); |
| 552 } | 557 } |
| 553 return new js.Assignment(leftHand, visitExpression(value)); | 558 return new js.Assignment(leftHand, visitExpression(value)) |
| 559 .withSourceInformation(sourceInformation); |
| 554 } | 560 } |
| 555 | 561 |
| 556 @override | 562 @override |
| 557 js.Expression visitAssign(tree_ir.Assign node) { | 563 js.Expression visitAssign(tree_ir.Assign node) { |
| 558 js.Expression variable = buildVariableAccess(node.variable); | 564 js.Expression variable = buildVariableAccess(node.variable); |
| 559 if (isCompoundableBuiltin(node.value)) { | 565 if (isCompoundableBuiltin(node.value)) { |
| 560 tree_ir.ApplyBuiltinOperator rhs = node.value; | 566 tree_ir.ApplyBuiltinOperator rhs = node.value; |
| 561 tree_ir.Expression left = rhs.arguments[0]; | 567 tree_ir.Expression left = rhs.arguments[0]; |
| 562 tree_ir.Expression right = rhs.arguments[1]; | 568 tree_ir.Expression right = rhs.arguments[1]; |
| 563 if (left is tree_ir.VariableUse && left.variable == node.variable) { | 569 if (left is tree_ir.VariableUse && left.variable == node.variable) { |
| 564 return makeAssignment(variable, right, compound: rhs.operator); | 570 return makeAssignment(variable, right, compound: rhs.operator, |
| 571 sourceInformation: node.sourceInformation); |
| 565 } | 572 } |
| 566 } | 573 } |
| 567 return makeAssignment(variable, node.value); | 574 return makeAssignment( |
| 575 variable, node.value, sourceInformation: node.sourceInformation); |
| 568 } | 576 } |
| 569 | 577 |
| 570 @override | 578 @override |
| 571 void visitContinue(tree_ir.Continue node) { | 579 void visitContinue(tree_ir.Continue node) { |
| 572 tree_ir.Statement next = fallthrough.target; | 580 tree_ir.Statement next = fallthrough.target; |
| 573 if (node.target.binding == next || | 581 if (node.target.binding == next || |
| 574 next is tree_ir.Continue && node.target == next.target) { | 582 next is tree_ir.Continue && node.target == next.target) { |
| 575 // Fall through to continue target or to equivalent continue. | 583 // Fall through to continue target or to equivalent continue. |
| 576 fallthrough.use(); | 584 fallthrough.use(); |
| 577 } else if (node.target.binding == shortContinue.target) { | 585 } else if (node.target.binding == shortContinue.target) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 } else { | 621 } else { |
| 614 accumulator.add(new js.Break(makeLabel(node.target))); | 622 accumulator.add(new js.Break(makeLabel(node.target))); |
| 615 } | 623 } |
| 616 } | 624 } |
| 617 | 625 |
| 618 @override | 626 @override |
| 619 visitExpressionStatement(tree_ir.ExpressionStatement node) { | 627 visitExpressionStatement(tree_ir.ExpressionStatement node) { |
| 620 js.Expression exp = visitExpression(node.expression); | 628 js.Expression exp = visitExpression(node.expression); |
| 621 if (node.next is tree_ir.Unreachable && emitUnreachableAsReturn.last) { | 629 if (node.next is tree_ir.Unreachable && emitUnreachableAsReturn.last) { |
| 622 // Emit as 'return exp' to assist local analysis in the VM. | 630 // Emit as 'return exp' to assist local analysis in the VM. |
| 623 accumulator.add(new js.Return(exp)); | 631 SourceInformation sourceInformation = node.expression.sourceInformation; |
| 632 accumulator.add( |
| 633 new js.Return(exp).withSourceInformation(sourceInformation)); |
| 624 return null; | 634 return null; |
| 625 } else { | 635 } else { |
| 626 accumulator.add(new js.ExpressionStatement(exp)); | 636 accumulator.add(new js.ExpressionStatement(exp)); |
| 627 return node.next; | 637 return node.next; |
| 628 } | 638 } |
| 629 } | 639 } |
| 630 | 640 |
| 631 bool isNullReturn(tree_ir.Statement node) { | 641 bool isNullReturn(tree_ir.Statement node) { |
| 632 return node is tree_ir.Return && isNull(node.value); | 642 return node is tree_ir.Return && isNull(node.value); |
| 633 } | 643 } |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 return js.js('#.#(#)', | 883 return js.js('#.#(#)', |
| 874 [globalHolder, helperName, visitExpression(node.input)]) | 884 [globalHolder, helperName, visitExpression(node.input)]) |
| 875 .withSourceInformation(node.sourceInformation); | 885 .withSourceInformation(node.sourceInformation); |
| 876 } | 886 } |
| 877 | 887 |
| 878 @override | 888 @override |
| 879 js.Expression visitGetField(tree_ir.GetField node) { | 889 js.Expression visitGetField(tree_ir.GetField node) { |
| 880 registry.registerStaticUse(new StaticUse.fieldGet(node.field)); | 890 registry.registerStaticUse(new StaticUse.fieldGet(node.field)); |
| 881 return new js.PropertyAccess( | 891 return new js.PropertyAccess( |
| 882 visitExpression(node.object), | 892 visitExpression(node.object), |
| 883 glue.instanceFieldPropertyName(node.field)); | 893 glue.instanceFieldPropertyName(node.field)) |
| 894 .withSourceInformation(node.sourceInformation); |
| 884 } | 895 } |
| 885 | 896 |
| 886 @override | 897 @override |
| 887 js.Expression visitSetField(tree_ir.SetField node) { | 898 js.Expression visitSetField(tree_ir.SetField node) { |
| 888 registry.registerStaticUse(new StaticUse.fieldSet(node.field)); | 899 registry.registerStaticUse(new StaticUse.fieldSet(node.field)); |
| 889 js.PropertyAccess field = | 900 js.PropertyAccess field = |
| 890 new js.PropertyAccess( | 901 new js.PropertyAccess( |
| 891 visitExpression(node.object), | 902 visitExpression(node.object), |
| 892 glue.instanceFieldPropertyName(node.field)); | 903 glue.instanceFieldPropertyName(node.field)); |
| 893 return makeAssignment(field, node.value, compound: node.compound); | 904 return makeAssignment(field, node.value, compound: node.compound, |
| 905 sourceInformation: node.sourceInformation); |
| 894 } | 906 } |
| 895 | 907 |
| 896 @override | 908 @override |
| 897 js.Expression visitGetStatic(tree_ir.GetStatic node) { | 909 js.Expression visitGetStatic(tree_ir.GetStatic node) { |
| 898 assert(node.element is FieldElement || node.element is FunctionElement); | 910 assert(node.element is FieldElement || node.element is FunctionElement); |
| 899 if (node.element is FunctionElement) { | 911 if (node.element is FunctionElement) { |
| 900 // Tear off a method. | 912 // Tear off a method. |
| 901 registry.registerStaticUse( | 913 registry.registerStaticUse( |
| 902 new StaticUse.staticTearOff(node.element.declaration)); | 914 new StaticUse.staticTearOff(node.element.declaration)); |
| 903 return glue.isolateStaticClosureAccess(node.element); | 915 return glue.isolateStaticClosureAccess(node.element) |
| 916 .withSourceInformation(node.sourceInformation); |
| 904 } | 917 } |
| 905 if (node.useLazyGetter) { | 918 if (node.useLazyGetter) { |
| 906 // Read a lazily initialized field. | 919 // Read a lazily initialized field. |
| 907 registry.registerStaticUse( | 920 registry.registerStaticUse( |
| 908 new StaticUse.staticInit(node.element.declaration)); | 921 new StaticUse.staticInit(node.element.declaration)); |
| 909 js.Expression getter = glue.isolateLazyInitializerAccess(node.element); | 922 js.Expression getter = glue.isolateLazyInitializerAccess(node.element); |
| 910 return new js.Call(getter, <js.Expression>[], | 923 return new js.Call(getter, <js.Expression>[], |
| 911 sourceInformation: node.sourceInformation); | 924 sourceInformation: node.sourceInformation); |
| 912 } | 925 } |
| 913 // Read an eagerly initialized field. | 926 // Read an eagerly initialized field. |
| 914 registry.registerStaticUse( | 927 registry.registerStaticUse( |
| 915 new StaticUse.staticGet(node.element.declaration)); | 928 new StaticUse.staticGet(node.element.declaration)); |
| 916 return glue.staticFieldAccess(node.element); | 929 return glue.staticFieldAccess(node.element) |
| 930 .withSourceInformation(node.sourceInformation); |
| 917 } | 931 } |
| 918 | 932 |
| 919 @override | 933 @override |
| 920 js.Expression visitSetStatic(tree_ir.SetStatic node) { | 934 js.Expression visitSetStatic(tree_ir.SetStatic node) { |
| 921 assert(node.element is FieldElement); | 935 assert(node.element is FieldElement); |
| 922 registry.registerStaticUse( | 936 registry.registerStaticUse( |
| 923 new StaticUse.staticSet(node.element.declaration)); | 937 new StaticUse.staticSet(node.element.declaration)); |
| 924 js.Expression field = glue.staticFieldAccess(node.element); | 938 js.Expression field = glue.staticFieldAccess(node.element); |
| 925 return makeAssignment(field, node.value, compound: node.compound); | 939 return makeAssignment(field, node.value, compound: node.compound, |
| 940 sourceInformation: node.sourceInformation); |
| 926 } | 941 } |
| 927 | 942 |
| 928 @override | 943 @override |
| 929 js.Expression visitGetLength(tree_ir.GetLength node) { | 944 js.Expression visitGetLength(tree_ir.GetLength node) { |
| 930 return new js.PropertyAccess.field(visitExpression(node.object), 'length'); | 945 return new js.PropertyAccess.field(visitExpression(node.object), 'length'); |
| 931 } | 946 } |
| 932 | 947 |
| 933 @override | 948 @override |
| 934 js.Expression visitGetIndex(tree_ir.GetIndex node) { | 949 js.Expression visitGetIndex(tree_ir.GetIndex node) { |
| 935 return new js.PropertyAccess( | 950 return new js.PropertyAccess( |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 if (node.dependency != null) { | 1019 if (node.dependency != null) { |
| 1005 // Dependency is only used if [node] calls a Dart function. Currently only | 1020 // Dependency is only used if [node] calls a Dart function. Currently only |
| 1006 // through foreign function `RAW_DART_FUNCTION_REF`. | 1021 // through foreign function `RAW_DART_FUNCTION_REF`. |
| 1007 registry.registerStaticUse( | 1022 registry.registerStaticUse( |
| 1008 new StaticUse.staticInvoke( | 1023 new StaticUse.staticInvoke( |
| 1009 node.dependency, | 1024 node.dependency, |
| 1010 new CallStructure.unnamed(node.arguments.length))); | 1025 new CallStructure.unnamed(node.arguments.length))); |
| 1011 } | 1026 } |
| 1012 // TODO(sra,johnniwinther): Should this be in CodegenRegistry? | 1027 // TODO(sra,johnniwinther): Should this be in CodegenRegistry? |
| 1013 glue.registerNativeBehavior(node.nativeBehavior, node); | 1028 glue.registerNativeBehavior(node.nativeBehavior, node); |
| 1014 return node.codeTemplate.instantiate(visitExpressionList(node.arguments)); | 1029 return node.codeTemplate.instantiate(visitExpressionList(node.arguments)) |
| 1030 .withSourceInformation(node.sourceInformation); |
| 1015 } | 1031 } |
| 1016 | 1032 |
| 1017 @override | 1033 @override |
| 1018 js.Expression visitForeignExpression(tree_ir.ForeignExpression node) { | 1034 js.Expression visitForeignExpression(tree_ir.ForeignExpression node) { |
| 1019 return handleForeignCode(node); | 1035 return handleForeignCode(node); |
| 1020 } | 1036 } |
| 1021 | 1037 |
| 1022 @override | 1038 @override |
| 1023 void visitForeignStatement(tree_ir.ForeignStatement node) { | 1039 void visitForeignStatement(tree_ir.ForeignStatement node) { |
| 1024 accumulator.add(handleForeignCode(node)); | 1040 accumulator.add(handleForeignCode(node)); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 void registerDefaultParameterValues(ExecutableElement element) { | 1260 void registerDefaultParameterValues(ExecutableElement element) { |
| 1245 if (element is! FunctionElement) return; | 1261 if (element is! FunctionElement) return; |
| 1246 FunctionElement function = element; | 1262 FunctionElement function = element; |
| 1247 if (function.isStatic) return; // Defaults are inlined at call sites. | 1263 if (function.isStatic) return; // Defaults are inlined at call sites. |
| 1248 function.functionSignature.forEachOptionalParameter((param) { | 1264 function.functionSignature.forEachOptionalParameter((param) { |
| 1249 ConstantValue constant = glue.getDefaultParameterValue(param); | 1265 ConstantValue constant = glue.getDefaultParameterValue(param); |
| 1250 registry.registerCompileTimeConstant(constant); | 1266 registry.registerCompileTimeConstant(constant); |
| 1251 }); | 1267 }); |
| 1252 } | 1268 } |
| 1253 } | 1269 } |
| OLD | NEW |