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

Side by Side Diff: lib/compiler/implementation/ssa/codegen.dart

Issue 10915104: Move namer into javascript backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
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 class SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 6
7 final JavaScriptBackend backend; 7 final JavaScriptBackend backend;
8 8
9 SsaCodeGeneratorTask(JavaScriptBackend backend) 9 SsaCodeGeneratorTask(JavaScriptBackend backend)
10 : this.backend = backend, 10 : this.backend = backend,
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 visitStatement(HInstruction node) { 670 visitStatement(HInstruction node) {
671 assert(!isGeneratingExpression); 671 assert(!isGeneratingExpression);
672 visit(node); 672 visit(node);
673 if (!expressionStack.isEmpty()) { 673 if (!expressionStack.isEmpty()) {
674 assert(expressionStack.length == 1); 674 assert(expressionStack.length == 1);
675 pushExpressionAsStatement(pop()); 675 pushExpressionAsStatement(pop());
676 } 676 }
677 } 677 }
678 678
679 void continueAsBreak(LabelElement target) { 679 void continueAsBreak(LabelElement target) {
680 pushStatement(new js.Break(compiler.namer.continueLabelName(target))); 680 pushStatement(new js.Break(backend.namer.continueLabelName(target)));
681 } 681 }
682 682
683 void implicitContinueAsBreak(TargetElement target) { 683 void implicitContinueAsBreak(TargetElement target) {
684 pushStatement(new js.Break( 684 pushStatement(new js.Break(
685 compiler.namer.implicitContinueLabelName(target))); 685 backend.namer.implicitContinueLabelName(target)));
686 } 686 }
687 687
688 void implicitBreakWithLabel(TargetElement target) { 688 void implicitBreakWithLabel(TargetElement target) {
689 pushStatement(new js.Break(compiler.namer.implicitBreakLabelName(target))); 689 pushStatement(new js.Break(backend.namer.implicitBreakLabelName(target)));
690 } 690 }
691 691
692 js.Statement wrapIntoLabels(js.Statement result, List<LabelElement> labels) { 692 js.Statement wrapIntoLabels(js.Statement result, List<LabelElement> labels) {
693 for (LabelElement label in labels) { 693 for (LabelElement label in labels) {
694 if (label.isTarget) { 694 if (label.isTarget) {
695 String breakLabelString = compiler.namer.breakLabelName(label); 695 String breakLabelString = backend.namer.breakLabelName(label);
696 result = new js.LabeledStatement(breakLabelString, result); 696 result = new js.LabeledStatement(breakLabelString, result);
697 } 697 }
698 } 698 }
699 return result; 699 return result;
700 } 700 }
701 701
702 702
703 // The regular [visitIf] method implements the needed logic. 703 // The regular [visitIf] method implements the needed logic.
704 bool visitIfInfo(HIfBlockInformation info) => false; 704 bool visitIfInfo(HIfBlockInformation info) => false;
705 705
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 945
946 currentContainer = body; 946 currentContainer = body;
947 947
948 // If [labeledBlockInfo.isContinue], the block is an artificial 948 // If [labeledBlockInfo.isContinue], the block is an artificial
949 // block around the body of a loop with an update block, so that 949 // block around the body of a loop with an update block, so that
950 // continues of the loop can be written as breaks of the body 950 // continues of the loop can be written as breaks of the body
951 // block. 951 // block.
952 if (labeledBlockInfo.isContinue) { 952 if (labeledBlockInfo.isContinue) {
953 for (LabelElement label in labeledBlockInfo.labels) { 953 for (LabelElement label in labeledBlockInfo.labels) {
954 if (label.isContinueTarget) { 954 if (label.isContinueTarget) {
955 String labelName = compiler.namer.continueLabelName(label); 955 String labelName = backend.namer.continueLabelName(label);
956 result = new js.LabeledStatement(labelName, result); 956 result = new js.LabeledStatement(labelName, result);
957 continueAction[label] = continueAsBreak; 957 continueAction[label] = continueAsBreak;
958 continueOverrides = continueOverrides.prepend(label); 958 continueOverrides = continueOverrides.prepend(label);
959 } 959 }
960 } 960 }
961 // For handling unlabeled continues from the body of a loop. 961 // For handling unlabeled continues from the body of a loop.
962 // TODO(lrn): Consider recording whether the target is in fact 962 // TODO(lrn): Consider recording whether the target is in fact
963 // a target of an unlabeled continue, and not generate this if it isn't. 963 // a target of an unlabeled continue, and not generate this if it isn't.
964 TargetElement target = labeledBlockInfo.target; 964 TargetElement target = labeledBlockInfo.target;
965 String labelName = compiler.namer.implicitContinueLabelName(target); 965 String labelName = backend.namer.implicitContinueLabelName(target);
966 result = new js.LabeledStatement(labelName, result); 966 result = new js.LabeledStatement(labelName, result);
967 continueAction[target] = implicitContinueAsBreak; 967 continueAction[target] = implicitContinueAsBreak;
968 continueOverrides = continueOverrides.prepend(target); 968 continueOverrides = continueOverrides.prepend(target);
969 } else { 969 } else {
970 for (LabelElement label in labeledBlockInfo.labels) { 970 for (LabelElement label in labeledBlockInfo.labels) {
971 if (label.isBreakTarget) { 971 if (label.isBreakTarget) {
972 String labelName = compiler.namer.breakLabelName(label); 972 String labelName = backend.namer.breakLabelName(label);
973 result = new js.LabeledStatement(labelName, result); 973 result = new js.LabeledStatement(labelName, result);
974 } 974 }
975 } 975 }
976 TargetElement target = labeledBlockInfo.target; 976 TargetElement target = labeledBlockInfo.target;
977 if (target.isSwitch) { 977 if (target.isSwitch) {
978 // This is an extra block around a switch that is generated 978 // This is an extra block around a switch that is generated
979 // as a nested if/else chain. We add an extra break target 979 // as a nested if/else chain. We add an extra break target
980 // so that case code can break. 980 // so that case code can break.
981 String labelName = compiler.namer.implicitBreakLabelName(target); 981 String labelName = backend.namer.implicitBreakLabelName(target);
982 result = new js.LabeledStatement(labelName, result); 982 result = new js.LabeledStatement(labelName, result);
983 breakAction[target] = implicitBreakWithLabel; 983 breakAction[target] = implicitBreakWithLabel;
984 } 984 }
985 } 985 }
986 986
987 currentContainer = body; 987 currentContainer = body;
988 startLabeledBlock(labeledBlockInfo); 988 startLabeledBlock(labeledBlockInfo);
989 generateStatements(labeledBlockInfo.body); 989 generateStatements(labeledBlockInfo.body);
990 endLabeledBlock(labeledBlockInfo); 990 endLabeledBlock(labeledBlockInfo);
991 991
(...skipping 15 matching lines...) Expand all
1007 // to (if necessary). 1007 // to (if necessary).
1008 void wrapLoopBodyForContinue(HLoopBlockInformation info) { 1008 void wrapLoopBodyForContinue(HLoopBlockInformation info) {
1009 TargetElement target = info.target; 1009 TargetElement target = info.target;
1010 if (target !== null && target.isContinueTarget) { 1010 if (target !== null && target.isContinueTarget) {
1011 js.Block oldContainer = currentContainer; 1011 js.Block oldContainer = currentContainer;
1012 js.Block body = new js.Block.empty(); 1012 js.Block body = new js.Block.empty();
1013 currentContainer = body; 1013 currentContainer = body;
1014 js.Statement result = body; 1014 js.Statement result = body;
1015 for (LabelElement label in info.labels) { 1015 for (LabelElement label in info.labels) {
1016 if (label.isContinueTarget) { 1016 if (label.isContinueTarget) {
1017 String labelName = compiler.namer.continueLabelName(label); 1017 String labelName = backend.namer.continueLabelName(label);
1018 result = new js.LabeledStatement(labelName, result); 1018 result = new js.LabeledStatement(labelName, result);
1019 continueAction[label] = continueAsBreak; 1019 continueAction[label] = continueAsBreak;
1020 } 1020 }
1021 } 1021 }
1022 String labelName = compiler.namer.implicitContinueLabelName(target); 1022 String labelName = backend.namer.implicitContinueLabelName(target);
1023 result = new js.LabeledStatement(labelName, result); 1023 result = new js.LabeledStatement(labelName, result);
1024 continueAction[info.target] = implicitContinueAsBreak; 1024 continueAction[info.target] = implicitContinueAsBreak;
1025 visitBodyIgnoreLabels(info); 1025 visitBodyIgnoreLabels(info);
1026 continueAction.remove(info.target); 1026 continueAction.remove(info.target);
1027 for (LabelElement label in info.labels) { 1027 for (LabelElement label in info.labels) {
1028 if (label.isContinueTarget) { 1028 if (label.isContinueTarget) {
1029 continueAction.remove(label); 1029 continueAction.remove(label);
1030 } 1030 }
1031 } 1031 }
1032 currentContainer = oldContainer; 1032 currentContainer = oldContainer;
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 if (action === null) return false; 1331 if (action === null) return false;
1332 action(element); 1332 action(element);
1333 return true; 1333 return true;
1334 } 1334 }
1335 1335
1336 visitBreak(HBreak node) { 1336 visitBreak(HBreak node) {
1337 assert(currentBlock.successors.length == 1); 1337 assert(currentBlock.successors.length == 1);
1338 if (node.label !== null) { 1338 if (node.label !== null) {
1339 LabelElement label = node.label; 1339 LabelElement label = node.label;
1340 if (!tryCallAction(breakAction, label)) { 1340 if (!tryCallAction(breakAction, label)) {
1341 pushStatement(new js.Break(compiler.namer.breakLabelName(label)), node); 1341 pushStatement(new js.Break(backend.namer.breakLabelName(label)), node);
1342 } 1342 }
1343 } else { 1343 } else {
1344 TargetElement target = node.target; 1344 TargetElement target = node.target;
1345 if (!tryCallAction(breakAction, target)) { 1345 if (!tryCallAction(breakAction, target)) {
1346 pushStatement(new js.Break(null), node); 1346 pushStatement(new js.Break(null), node);
1347 } 1347 }
1348 } 1348 }
1349 } 1349 }
1350 1350
1351 visitContinue(HContinue node) { 1351 visitContinue(HContinue node) {
1352 assert(currentBlock.successors.length == 1); 1352 assert(currentBlock.successors.length == 1);
1353 if (node.label !== null) { 1353 if (node.label !== null) {
1354 LabelElement label = node.label; 1354 LabelElement label = node.label;
1355 if (!tryCallAction(continueAction, label)) { 1355 if (!tryCallAction(continueAction, label)) {
1356 // TODO(floitsch): should this really be the breakLabelName? 1356 // TODO(floitsch): should this really be the breakLabelName?
1357 pushStatement(new js.Continue(compiler.namer.breakLabelName(label)), 1357 pushStatement(new js.Continue(backend.namer.breakLabelName(label)),
1358 node); 1358 node);
1359 } 1359 }
1360 } else { 1360 } else {
1361 TargetElement target = node.target; 1361 TargetElement target = node.target;
1362 if (!tryCallAction(continueAction, target)) { 1362 if (!tryCallAction(continueAction, target)) {
1363 pushStatement(new js.Continue(null), node); 1363 pushStatement(new js.Continue(null), node);
1364 } 1364 }
1365 } 1365 }
1366 } 1366 }
1367 1367
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 List<js.Expression> arguments; 1455 List<js.Expression> arguments;
1456 1456
1457 // Avoid adding the generative constructor name to the list of 1457 // Avoid adding the generative constructor name to the list of
1458 // seen selectors. 1458 // seen selectors.
1459 if (node.inputs[0] is HForeignNew) { 1459 if (node.inputs[0] is HForeignNew) {
1460 // TODO(ahe): The constructor name was statically resolved in 1460 // TODO(ahe): The constructor name was statically resolved in
1461 // SsaBuilder.buildFactory. Is there a cleaner way to do this? 1461 // SsaBuilder.buildFactory. Is there a cleaner way to do this?
1462 methodName = name.slowToString(); 1462 methodName = name.slowToString();
1463 arguments = visitArguments(node.inputs); 1463 arguments = visitArguments(node.inputs);
1464 } else { 1464 } else {
1465 methodName = compiler.namer.instanceMethodInvocationName( 1465 methodName = backend.namer.instanceMethodInvocationName(
1466 node.selector.library, name, node.selector); 1466 node.selector.library, name, node.selector);
1467 arguments = visitArguments(node.inputs); 1467 arguments = visitArguments(node.inputs);
1468 bool inLoop = node.block.enclosingLoopHeader !== null; 1468 bool inLoop = node.block.enclosingLoopHeader !== null;
1469 1469
1470 // Register this invocation to collect the types used at all call sites. 1470 // Register this invocation to collect the types used at all call sites.
1471 Selector selector = getOptimizedSelectorFor(node, node.selector); 1471 Selector selector = getOptimizedSelectorFor(node, node.selector);
1472 backend.registerDynamicInvocation(node, selector, types); 1472 backend.registerDynamicInvocation(node, selector, types);
1473 1473
1474 // If we don't know what we're calling or if we are calling a getter, 1474 // If we don't know what we're calling or if we are calling a getter,
1475 // we need to register that fact that we may be calling a closure 1475 // we need to register that fact that we may be calling a closure
(...skipping 29 matching lines...) Expand all
1505 if (receiverType !== null) { 1505 if (receiverType !== null) {
1506 return new TypedSelector(receiverType, defaultSelector); 1506 return new TypedSelector(receiverType, defaultSelector);
1507 } else { 1507 } else {
1508 return defaultSelector; 1508 return defaultSelector;
1509 } 1509 }
1510 } 1510 }
1511 1511
1512 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { 1512 visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
1513 use(node.receiver); 1513 use(node.receiver);
1514 Selector setter = node.selector; 1514 Selector setter = node.selector;
1515 String name = compiler.namer.setterName(setter.library, setter.name); 1515 String name = backend.namer.setterName(setter.library, setter.name);
1516 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); 1516 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node);
1517 world.registerDynamicSetter( 1517 world.registerDynamicSetter(
1518 setter.name, getOptimizedSelectorFor(node, setter)); 1518 setter.name, getOptimizedSelectorFor(node, setter));
1519 } 1519 }
1520 1520
1521 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { 1521 visitInvokeDynamicGetter(HInvokeDynamicGetter node) {
1522 use(node.receiver); 1522 use(node.receiver);
1523 Selector getter = node.selector; 1523 Selector getter = node.selector;
1524 String name = compiler.namer.getterName(getter.library, getter.name); 1524 String name = backend.namer.getterName(getter.library, getter.name);
1525 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); 1525 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node);
1526 world.registerDynamicGetter( 1526 world.registerDynamicGetter(
1527 getter.name, getOptimizedSelectorFor(node, getter)); 1527 getter.name, getOptimizedSelectorFor(node, getter));
1528 } 1528 }
1529 1529
1530 visitInvokeClosure(HInvokeClosure node) { 1530 visitInvokeClosure(HInvokeClosure node) {
1531 use(node.receiver); 1531 use(node.receiver);
1532 push(jsPropertyCall(pop(), 1532 push(jsPropertyCall(pop(),
1533 compiler.namer.closureInvocationName(node.selector), 1533 backend.namer.closureInvocationName(node.selector),
1534 visitArguments(node.inputs)), 1534 visitArguments(node.inputs)),
1535 node); 1535 node);
1536 Selector call = new Selector.callClosureFrom(node.selector); 1536 Selector call = new Selector.callClosureFrom(node.selector);
1537 world.registerDynamicInvocation(call.name, call); 1537 world.registerDynamicInvocation(call.name, call);
1538 } 1538 }
1539 1539
1540 visitInvokeStatic(HInvokeStatic node) { 1540 visitInvokeStatic(HInvokeStatic node) {
1541 if (true && 1541 if (true &&
1542 (node.typeCode() == HInstruction.INVOKE_STATIC_TYPECODE || 1542 (node.typeCode() == HInstruction.INVOKE_STATIC_TYPECODE ||
1543 node.typeCode() == HInstruction.INVOKE_INTERCEPTOR_TYPECODE)) { 1543 node.typeCode() == HInstruction.INVOKE_INTERCEPTOR_TYPECODE)) {
(...skipping 10 matching lines...) Expand all
1554 // Remove the element and 'this'. 1554 // Remove the element and 'this'.
1555 int argumentCount = node.inputs.length - 2; 1555 int argumentCount = node.inputs.length - 2;
1556 if (superMethod.kind == ElementKind.FIELD) { 1556 if (superMethod.kind == ElementKind.FIELD) {
1557 ClassElement currentClass = work.element.getEnclosingClass(); 1557 ClassElement currentClass = work.element.getEnclosingClass();
1558 if (currentClass.isClosure()) { 1558 if (currentClass.isClosure()) {
1559 ClosureClassElement closure = currentClass; 1559 ClosureClassElement closure = currentClass;
1560 currentClass = closure.methodElement.getEnclosingClass(); 1560 currentClass = closure.methodElement.getEnclosingClass();
1561 } 1561 }
1562 String fieldName; 1562 String fieldName;
1563 if (currentClass.isShadowedByField(superMethod)) { 1563 if (currentClass.isShadowedByField(superMethod)) {
1564 fieldName = compiler.namer.shadowedFieldName(superMethod); 1564 fieldName = backend.namer.shadowedFieldName(superMethod);
1565 } else { 1565 } else {
1566 LibraryElement library = superMethod.getLibrary(); 1566 LibraryElement library = superMethod.getLibrary();
1567 SourceString name = superMethod.name; 1567 SourceString name = superMethod.name;
1568 fieldName = compiler.namer.instanceFieldName(library, name); 1568 fieldName = backend.namer.instanceFieldName(library, name);
1569 } 1569 }
1570 use(node.inputs[1]); 1570 use(node.inputs[1]);
1571 js.PropertyAccess access = 1571 js.PropertyAccess access =
1572 new js.PropertyAccess.field(pop(), fieldName); 1572 new js.PropertyAccess.field(pop(), fieldName);
1573 if (node.isSetter) { 1573 if (node.isSetter) {
1574 use(node.value); 1574 use(node.value);
1575 push(new js.Assignment(access, pop()), node); 1575 push(new js.Assignment(access, pop()), node);
1576 } else { 1576 } else {
1577 push(access, node); 1577 push(access, node);
1578 } 1578 }
1579 } else { 1579 } else {
1580 String methodName; 1580 String methodName;
1581 if (superMethod.kind == ElementKind.FUNCTION || 1581 if (superMethod.kind == ElementKind.FUNCTION ||
1582 superMethod.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 1582 superMethod.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
1583 methodName = compiler.namer.instanceMethodName( 1583 methodName = backend.namer.instanceMethodName(
1584 currentLibrary, superMethod.name, argumentCount); 1584 currentLibrary, superMethod.name, argumentCount);
1585 } else if (superMethod.kind == ElementKind.GETTER) { 1585 } else if (superMethod.kind == ElementKind.GETTER) {
1586 methodName = 1586 methodName =
1587 compiler.namer.getterName(currentLibrary, superMethod.name); 1587 backend.namer.getterName(currentLibrary, superMethod.name);
1588 } else { 1588 } else {
1589 assert(superMethod.kind == ElementKind.SETTER); 1589 assert(superMethod.kind == ElementKind.SETTER);
1590 methodName = 1590 methodName =
1591 compiler.namer.setterName(currentLibrary, superMethod.name); 1591 backend.namer.setterName(currentLibrary, superMethod.name);
1592 } 1592 }
1593 String className = compiler.namer.isolateAccess(superClass); 1593 String className = backend.namer.isolateAccess(superClass);
1594 js.VariableUse classReference = new js.VariableUse(className); 1594 js.VariableUse classReference = new js.VariableUse(className);
1595 js.PropertyAccess prototype = 1595 js.PropertyAccess prototype =
1596 new js.PropertyAccess.field(classReference, "prototype"); 1596 new js.PropertyAccess.field(classReference, "prototype");
1597 js.PropertyAccess method = 1597 js.PropertyAccess method =
1598 new js.PropertyAccess.field(prototype, methodName); 1598 new js.PropertyAccess.field(prototype, methodName);
1599 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node); 1599 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node);
1600 } 1600 }
1601 world.registerStaticUse(superMethod); 1601 world.registerStaticUse(superMethod);
1602 } 1602 }
1603 1603
1604 visitFieldGet(HFieldGet node) { 1604 visitFieldGet(HFieldGet node) {
1605 String name = compiler.namer.getName(node.element); 1605 String name = backend.namer.getName(node.element);
1606 use(node.receiver); 1606 use(node.receiver);
1607 push(new js.PropertyAccess.field(pop(), name), node); 1607 push(new js.PropertyAccess.field(pop(), name), node);
1608 HType receiverHType = types[node.receiver]; 1608 HType receiverHType = types[node.receiver];
1609 DartType type = receiverHType.computeType(compiler); 1609 DartType type = receiverHType.computeType(compiler);
1610 if (type != null) { 1610 if (type != null) {
1611 world.registerFieldGetter( 1611 world.registerFieldGetter(
1612 node.element.name, node.element.getLibrary(), type); 1612 node.element.name, node.element.getLibrary(), type);
1613 } 1613 }
1614 } 1614 }
1615 1615
(...skipping 11 matching lines...) Expand all
1627 } 1627 }
1628 1628
1629 visitFieldSet(HFieldSet node) { 1629 visitFieldSet(HFieldSet node) {
1630 if (work.element.isGenerativeConstructorBody() && 1630 if (work.element.isGenerativeConstructorBody() &&
1631 node.element.isMember() && 1631 node.element.isMember() &&
1632 node.value.hasGuaranteedType() && 1632 node.value.hasGuaranteedType() &&
1633 node.block.dominates(currentGraph.exit)) { 1633 node.block.dominates(currentGraph.exit)) {
1634 backend.updateFieldConstructorSetters(node.element, 1634 backend.updateFieldConstructorSetters(node.element,
1635 node.value.guaranteedType); 1635 node.value.guaranteedType);
1636 } 1636 }
1637 String name = compiler.namer.getName(node.element); 1637 String name = backend.namer.getName(node.element);
1638 DartType type = types[node.receiver].computeType(compiler); 1638 DartType type = types[node.receiver].computeType(compiler);
1639 if (type != null) { 1639 if (type != null) {
1640 if (!work.element.isGenerativeConstructorBody()) { 1640 if (!work.element.isGenerativeConstructorBody()) {
1641 world.registerFieldSetter( 1641 world.registerFieldSetter(
1642 node.element.name, node.element.getLibrary(), type); 1642 node.element.name, node.element.getLibrary(), type);
1643 } 1643 }
1644 // Determine the types seen so far for the field. If only number 1644 // Determine the types seen so far for the field. If only number
1645 // types have been seen and the value of the field set is a 1645 // types have been seen and the value of the field set is a
1646 // simple number computation only depending on that field, we 1646 // simple number computation only depending on that field, we
1647 // can safely keep the number type for the field. 1647 // can safely keep the number type for the field.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 1693
1694 visitForeignNew(HForeignNew node) { 1694 visitForeignNew(HForeignNew node) {
1695 int j = 0; 1695 int j = 0;
1696 node.element.forEachInstanceField( 1696 node.element.forEachInstanceField(
1697 includeBackendMembers: true, 1697 includeBackendMembers: true,
1698 includeSuperMembers: true, 1698 includeSuperMembers: true,
1699 f: (ClassElement enclosingClass, Element member) { 1699 f: (ClassElement enclosingClass, Element member) {
1700 backend.updateFieldInitializers(member, types[node.inputs[j]]); 1700 backend.updateFieldInitializers(member, types[node.inputs[j]]);
1701 j++; 1701 j++;
1702 }); 1702 });
1703 String jsClassReference = compiler.namer.isolateAccess(node.element); 1703 String jsClassReference = backend.namer.isolateAccess(node.element);
1704 List<HInstruction> inputs = node.inputs; 1704 List<HInstruction> inputs = node.inputs;
1705 // We can't use 'visitArguments', since our arguments start at input[0]. 1705 // We can't use 'visitArguments', since our arguments start at input[0].
1706 List<js.Expression> arguments = <js.Expression>[]; 1706 List<js.Expression> arguments = <js.Expression>[];
1707 for (int i = 0; i < inputs.length; i++) { 1707 for (int i = 0; i < inputs.length; i++) {
1708 use(inputs[i]); 1708 use(inputs[i]);
1709 arguments.add(pop()); 1709 arguments.add(pop());
1710 } 1710 }
1711 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it 1711 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it
1712 // as if it was a string. 1712 // as if it was a string.
1713 push(new js.New(new js.VariableUse(jsClassReference), arguments), node); 1713 push(new js.New(new js.VariableUse(jsClassReference), arguments), node);
(...skipping 15 matching lines...) Expand all
1729 push(new js.LiteralNull()); 1729 push(new js.LiteralNull());
1730 } else if (constant.isString()) { 1730 } else if (constant.isString()) {
1731 // TODO(floitsch): get rid of the code buffer. 1731 // TODO(floitsch): get rid of the code buffer.
1732 CodeBuffer buffer = new CodeBuffer(); 1732 CodeBuffer buffer = new CodeBuffer();
1733 handler.writeConstant(buffer, constant); 1733 handler.writeConstant(buffer, constant);
1734 push(new js.LiteralString(buffer.toString())); 1734 push(new js.LiteralString(buffer.toString()));
1735 } else if (constant.isFunction()) { 1735 } else if (constant.isFunction()) {
1736 FunctionConstant function = constant; 1736 FunctionConstant function = constant;
1737 world.registerStaticUse(function.element); 1737 world.registerStaticUse(function.element);
1738 push(new js.VariableUse( 1738 push(new js.VariableUse(
1739 compiler.namer.isolateAccess(function.element))); 1739 backend.namer.isolateAccess(function.element)));
1740 } else if (constant.isSentinel()) { 1740 } else if (constant.isSentinel()) {
1741 // TODO(floitsch): get rid of the code buffer. 1741 // TODO(floitsch): get rid of the code buffer.
1742 CodeBuffer buffer = new CodeBuffer(); 1742 CodeBuffer buffer = new CodeBuffer();
1743 handler.writeConstant(buffer, constant); 1743 handler.writeConstant(buffer, constant);
1744 push(new js.VariableUse(buffer.toString())); 1744 push(new js.VariableUse(buffer.toString()));
1745 } else { 1745 } else {
1746 compiler.internalError( 1746 compiler.internalError(
1747 "The compiler does not know how generate code for " 1747 "The compiler does not know how generate code for "
1748 "constant $constant"); 1748 "constant $constant");
1749 } 1749 }
1750 } else { 1750 } else {
1751 js.VariableUse currentIsolateUse = 1751 js.VariableUse currentIsolateUse =
1752 new js.VariableUse(compiler.namer.CURRENT_ISOLATE); 1752 new js.VariableUse(backend.namer.CURRENT_ISOLATE);
1753 push(new js.PropertyAccess.field(currentIsolateUse, name)); 1753 push(new js.PropertyAccess.field(currentIsolateUse, name));
1754 } 1754 }
1755 } 1755 }
1756 1756
1757 visitConstant(HConstant node) { 1757 visitConstant(HConstant node) {
1758 assert(isGenerateAtUseSite(node)); 1758 assert(isGenerateAtUseSite(node));
1759 generateConstant(node.constant); 1759 generateConstant(node.constant);
1760 } 1760 }
1761 1761
1762 visitLoopBranch(HLoopBranch node) { 1762 visitLoopBranch(HLoopBranch node) {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1951 pushStatement(new js.If.noElse(test, thenBody), node); 1951 pushStatement(new js.If.noElse(test, thenBody), node);
1952 } else { 1952 } else {
1953 generateThrowWithHelper('iae', node.value); 1953 generateThrowWithHelper('iae', node.value);
1954 } 1954 }
1955 } 1955 }
1956 1956
1957 void generateThrowWithHelper(String helperName, HInstruction argument) { 1957 void generateThrowWithHelper(String helperName, HInstruction argument) {
1958 Element helper = compiler.findHelper(new SourceString(helperName)); 1958 Element helper = compiler.findHelper(new SourceString(helperName));
1959 world.registerStaticUse(helper); 1959 world.registerStaticUse(helper);
1960 js.VariableUse jsHelper = 1960 js.VariableUse jsHelper =
1961 new js.VariableUse(compiler.namer.isolateAccess(helper)); 1961 new js.VariableUse(backend.namer.isolateAccess(helper));
1962 js.Call value = new js.Call(jsHelper, visitArguments([null, argument])); 1962 js.Call value = new js.Call(jsHelper, visitArguments([null, argument]));
1963 attachLocation(value, argument); 1963 attachLocation(value, argument);
1964 // BUG(4906): Using throw here adds to the size of the generated code 1964 // BUG(4906): Using throw here adds to the size of the generated code
1965 // but it has the advantage of explicitly telling the JS engine that 1965 // but it has the advantage of explicitly telling the JS engine that
1966 // this code path will terminate abruptly. Needs more work. 1966 // this code path will terminate abruptly. Needs more work.
1967 pushStatement(new js.Throw(value)); 1967 pushStatement(new js.Throw(value));
1968 } 1968 }
1969 1969
1970 void visitSwitch(HSwitch node) { 1970 void visitSwitch(HSwitch node) {
1971 // Switches are handled using [visitSwitchInfo]. 1971 // Switches are handled using [visitSwitchInfo].
(...skipping 12 matching lines...) Expand all
1984 // which will also be non call static use. 1984 // which will also be non call static use.
1985 for (int i = 1; i < node.inputs.length; i++) { 1985 for (int i = 1; i < node.inputs.length; i++) {
1986 if (node.inputs === node) { 1986 if (node.inputs === node) {
1987 backend.registerNonCallStaticUse(node); 1987 backend.registerNonCallStaticUse(node);
1988 break; 1988 break;
1989 } 1989 }
1990 } 1990 }
1991 } 1991 }
1992 }); 1992 });
1993 world.registerStaticUse(node.element); 1993 world.registerStaticUse(node.element);
1994 push(new js.VariableUse(compiler.namer.isolateAccess(node.element))); 1994 push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
1995 } 1995 }
1996 1996
1997 void visitLazyStatic(HLazyStatic node) { 1997 void visitLazyStatic(HLazyStatic node) {
1998 Element element = node.element; 1998 Element element = node.element;
1999 world.registerStaticUse(element); 1999 world.registerStaticUse(element);
2000 String lazyGetter = compiler.namer.isolateLazyInitializerAccess(element); 2000 String lazyGetter = backend.namer.isolateLazyInitializerAccess(element);
2001 js.VariableUse target = new js.VariableUse(lazyGetter); 2001 js.VariableUse target = new js.VariableUse(lazyGetter);
2002 js.Call call = new js.Call(target, <js.Expression>[]); 2002 js.Call call = new js.Call(target, <js.Expression>[]);
2003 push(call, node); 2003 push(call, node);
2004 } 2004 }
2005 2005
2006 void visitStaticStore(HStaticStore node) { 2006 void visitStaticStore(HStaticStore node) {
2007 world.registerStaticUse(node.element); 2007 world.registerStaticUse(node.element);
2008 js.VariableUse variableUse = 2008 js.VariableUse variableUse =
2009 new js.VariableUse(compiler.namer.isolateAccess(node.element)); 2009 new js.VariableUse(backend.namer.isolateAccess(node.element));
2010 use(node.inputs[0]); 2010 use(node.inputs[0]);
2011 push(new js.Assignment(variableUse, pop()), node); 2011 push(new js.Assignment(variableUse, pop()), node);
2012 } 2012 }
2013 2013
2014 void visitStringConcat(HStringConcat node) { 2014 void visitStringConcat(HStringConcat node) {
2015 if (isEmptyString(node.left)) { 2015 if (isEmptyString(node.left)) {
2016 useStringified(node.right); 2016 useStringified(node.right);
2017 } else if (isEmptyString(node.right)) { 2017 } else if (isEmptyString(node.right)) {
2018 useStringified(node.left); 2018 useStringified(node.left);
2019 } else { 2019 } else {
(...skipping 11 matching lines...) Expand all
2031 return string.value.length == 0; 2031 return string.value.length == 0;
2032 } 2032 }
2033 2033
2034 void useStringified(HInstruction node) { 2034 void useStringified(HInstruction node) {
2035 if (node.isString(types)) { 2035 if (node.isString(types)) {
2036 use(node); 2036 use(node);
2037 } else { 2037 } else {
2038 Element convertToString = compiler.findHelper(const SourceString("S")); 2038 Element convertToString = compiler.findHelper(const SourceString("S"));
2039 world.registerStaticUse(convertToString); 2039 world.registerStaticUse(convertToString);
2040 js.VariableUse variableUse = 2040 js.VariableUse variableUse =
2041 new js.VariableUse(compiler.namer.isolateAccess(convertToString)); 2041 new js.VariableUse(backend.namer.isolateAccess(convertToString));
2042 use(node); 2042 use(node);
2043 push(new js.Call(variableUse, <js.Expression>[pop()]), node); 2043 push(new js.Call(variableUse, <js.Expression>[pop()]), node);
2044 } 2044 }
2045 } 2045 }
2046 2046
2047 void visitLiteralList(HLiteralList node) { 2047 void visitLiteralList(HLiteralList node) {
2048 generateArrayLiteral(node); 2048 generateArrayLiteral(node);
2049 } 2049 }
2050 2050
2051 void generateArrayLiteral(HLiteralList node) { 2051 void generateArrayLiteral(HLiteralList node) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2224 checkType(input, element); 2224 checkType(input, element);
2225 push(new js.Binary('||', 2225 push(new js.Binary('||',
2226 functionTest, 2226 functionTest,
2227 new js.Binary('&&', objectTest, pop()))); 2227 new js.Binary('&&', objectTest, pop())));
2228 } 2228 }
2229 2229
2230 void checkType(HInstruction input, Element element, [bool negative = false]) { 2230 void checkType(HInstruction input, Element element, [bool negative = false]) {
2231 world.registerIsCheck(element); 2231 world.registerIsCheck(element);
2232 use(input); 2232 use(input);
2233 js.PropertyAccess field = 2233 js.PropertyAccess field =
2234 new js.PropertyAccess.field(pop(), compiler.namer.operatorIs(element)); 2234 new js.PropertyAccess.field(pop(), backend.namer.operatorIs(element));
2235 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { 2235 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) {
2236 push(new js.Call(field, <js.Expression>[])); 2236 push(new js.Call(field, <js.Expression>[]));
2237 if (negative) push(new js.Prefix('!', pop())); 2237 if (negative) push(new js.Prefix('!', pop()));
2238 } else { 2238 } else {
2239 // We always negate at least once so that the result is boolified. 2239 // We always negate at least once so that the result is boolified.
2240 push(new js.Prefix('!', field)); 2240 push(new js.Prefix('!', field));
2241 // If the result is not negated, put another '!' in front. 2241 // If the result is not negated, put another '!' in front.
2242 if (!negative) push(new js.Prefix('!', pop())); 2242 if (!negative) push(new js.Prefix('!', pop()));
2243 } 2243 }
2244 } 2244 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 currentContainer = body; 2397 currentContainer = body;
2398 generateThrowWithHelper('iae', node.checkedInput); 2398 generateThrowWithHelper('iae', node.checkedInput);
2399 currentContainer = oldContainer; 2399 currentContainer = oldContainer;
2400 body = unwrapStatement(body); 2400 body = unwrapStatement(body);
2401 pushStatement(new js.If.noElse(test, body), node); 2401 pushStatement(new js.If.noElse(test, body), node);
2402 return; 2402 return;
2403 } 2403 }
2404 2404
2405 assert(node.isCheckedModeCheck || node.isCastTypeCheck); 2405 assert(node.isCheckedModeCheck || node.isCastTypeCheck);
2406 SourceString helper = backend.getCheckedModeHelper(type); 2406 SourceString helper = backend.getCheckedModeHelper(type);
2407 String additionalArgument = compiler.namer.operatorIs(element); 2407 String additionalArgument = backend.namer.operatorIs(element);
2408 if (node.isCastTypeCheck) { 2408 if (node.isCastTypeCheck) {
2409 helper = castNames[helper.stringValue]; 2409 helper = castNames[helper.stringValue];
2410 } 2410 }
2411 Element helperElement = compiler.findHelper(helper); 2411 Element helperElement = compiler.findHelper(helper);
2412 world.registerStaticUse(helperElement); 2412 world.registerStaticUse(helperElement);
2413 List<js.Expression> arguments = <js.Expression>[]; 2413 List<js.Expression> arguments = <js.Expression>[];
2414 use(node.checkedInput); 2414 use(node.checkedInput);
2415 arguments.add(pop()); 2415 arguments.add(pop());
2416 arguments.add(new js.LiteralString("'$additionalArgument'")); 2416 arguments.add(new js.LiteralString("'$additionalArgument'"));
2417 String helperName = compiler.namer.isolateAccess(helperElement); 2417 String helperName = backend.namer.isolateAccess(helperElement);
2418 push(new js.Call(new js.VariableUse(helperName), arguments)); 2418 push(new js.Call(new js.VariableUse(helperName), arguments));
2419 } else { 2419 } else {
2420 use(node.checkedInput); 2420 use(node.checkedInput);
2421 } 2421 }
2422 } 2422 }
2423 } 2423 }
2424 2424
2425 class SsaOptimizedCodeGenerator extends SsaCodeGenerator { 2425 class SsaOptimizedCodeGenerator extends SsaCodeGenerator {
2426 SsaOptimizedCodeGenerator(backend, work, parameters, parameterNames) 2426 SsaOptimizedCodeGenerator(backend, work, parameters, parameterNames)
2427 : super(backend, work, parameterNames) { 2427 : super(backend, work, parameterNames) {
(...skipping 15 matching lines...) Expand all
2443 work.guards.forEach((HTypeGuard workGuard) { 2443 work.guards.forEach((HTypeGuard workGuard) {
2444 HBailoutTarget target = workGuard.bailoutTarget; 2444 HBailoutTarget target = workGuard.bailoutTarget;
2445 int inputLength = target.inputs.length; 2445 int inputLength = target.inputs.length;
2446 if (inputLength > maxBailoutParameters) { 2446 if (inputLength > maxBailoutParameters) {
2447 maxBailoutParameters = inputLength; 2447 maxBailoutParameters = inputLength;
2448 } 2448 }
2449 }); 2449 });
2450 } 2450 }
2451 HInstruction input = guard.guarded; 2451 HInstruction input = guard.guarded;
2452 HBailoutTarget target = guard.bailoutTarget; 2452 HBailoutTarget target = guard.bailoutTarget;
2453 Namer namer = compiler.namer; 2453 Namer namer = backend.namer;
2454 Element element = work.element; 2454 Element element = work.element;
2455 List<js.Expression> arguments = <js.Expression>[]; 2455 List<js.Expression> arguments = <js.Expression>[];
2456 arguments.add(new js.LiteralNumber("${guard.state}")); 2456 arguments.add(new js.LiteralNumber("${guard.state}"));
2457 // TODO(ngeoffray): try to put a variable at a deterministic 2457 // TODO(ngeoffray): try to put a variable at a deterministic
2458 // location, so that multiple bailout calls put the variable at 2458 // location, so that multiple bailout calls put the variable at
2459 // the same parameter index. 2459 // the same parameter index.
2460 int i = 0; 2460 int i = 0;
2461 for (; i < target.inputs.length; i++) { 2461 for (; i < target.inputs.length; i++) {
2462 assert(guard.inputs.indexOf(target.inputs[i]) >= 0); 2462 assert(guard.inputs.indexOf(target.inputs[i]) >= 0);
2463 use(target.inputs[i]); 2463 use(target.inputs[i]);
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
2934 if (leftType.canBeNull() && rightType.canBeNull()) { 2934 if (leftType.canBeNull() && rightType.canBeNull()) {
2935 if (left.isConstantNull() || right.isConstantNull() || 2935 if (left.isConstantNull() || right.isConstantNull() ||
2936 (leftType.isPrimitive() && leftType == rightType)) { 2936 (leftType.isPrimitive() && leftType == rightType)) {
2937 return '=='; 2937 return '==';
2938 } 2938 }
2939 return null; 2939 return null;
2940 } else { 2940 } else {
2941 return '==='; 2941 return '===';
2942 } 2942 }
2943 } 2943 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698