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

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

Issue 1198293002: dart2js: Use an abstract Name class for names in the generated JavaScript ast. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix new emitter. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 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 SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 final SourceInformationFactory sourceInformationFactory; 10 final SourceInformationFactory sourceInformationFactory;
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 if (node.isConditionalConstantInterceptor) { 1486 if (node.isConditionalConstantInterceptor) {
1487 assert(node.inputs.length == 2); 1487 assert(node.inputs.length == 2);
1488 use(node.receiver); 1488 use(node.receiver);
1489 js.Expression receiverExpression = pop(); 1489 js.Expression receiverExpression = pop();
1490 use(node.conditionalConstantInterceptor); 1490 use(node.conditionalConstantInterceptor);
1491 js.Expression constant = pop(); 1491 js.Expression constant = pop();
1492 push(js.js('# && #', [receiverExpression, constant])); 1492 push(js.js('# && #', [receiverExpression, constant]));
1493 } else { 1493 } else {
1494 assert(node.inputs.length == 1); 1494 assert(node.inputs.length == 1);
1495 registry.registerSpecializedGetInterceptor(node.interceptedClasses); 1495 registry.registerSpecializedGetInterceptor(node.interceptedClasses);
1496 String name = 1496 js.Name name =
1497 backend.namer.nameForGetInterceptor(node.interceptedClasses); 1497 backend.namer.nameForGetInterceptor(node.interceptedClasses);
1498 var isolate = new js.VariableUse( 1498 var isolate = new js.VariableUse(
1499 backend.namer.globalObjectFor(backend.interceptorsLibrary)); 1499 backend.namer.globalObjectFor(backend.interceptorsLibrary));
1500 use(node.receiver); 1500 use(node.receiver);
1501 List<js.Expression> arguments = <js.Expression>[pop()]; 1501 List<js.Expression> arguments = <js.Expression>[pop()];
1502 push(js.propertyCall(isolate, name, arguments), node); 1502 push(js.propertyCall(isolate, name, arguments), node);
1503 registry.registerUseInterceptor(); 1503 registry.registerUseInterceptor();
1504 } 1504 }
1505 } 1505 }
1506 1506
1507 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { 1507 visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
1508 use(node.receiver); 1508 use(node.receiver);
1509 js.Expression object = pop(); 1509 js.Expression object = pop();
1510 String methodName; 1510 String methodName;
1511 List<js.Expression> arguments = visitArguments(node.inputs); 1511 List<js.Expression> arguments = visitArguments(node.inputs);
1512 Element target = node.element; 1512 Element target = node.element;
1513 1513
1514 // TODO(herhut): The namer should return the appropriate backendname here.
1514 if (target != null && !node.isInterceptedCall) { 1515 if (target != null && !node.isInterceptedCall) {
1515 if (target == backend.jsArrayAdd) { 1516 if (target == backend.jsArrayAdd) {
1516 methodName = 'push'; 1517 methodName = 'push';
1517 } else if (target == backend.jsArrayRemoveLast) { 1518 } else if (target == backend.jsArrayRemoveLast) {
1518 methodName = 'pop'; 1519 methodName = 'pop';
1519 } else if (target == backend.jsStringSplit) { 1520 } else if (target == backend.jsStringSplit) {
1520 methodName = 'split'; 1521 methodName = 'split';
1521 // Split returns a List, so we make sure the backend knows the 1522 // Split returns a List, so we make sure the backend knows the
1522 // list class is instantiated. 1523 // list class is instantiated.
1523 registry.registerInstantiatedClass(compiler.listClass); 1524 registry.registerInstantiatedClass(compiler.listClass);
1524 } else if (target.isNative && target.isFunction 1525 } else if (target.isNative && target.isFunction
1525 && !node.isInterceptedCall) { 1526 && !node.isInterceptedCall) {
1526 // A direct (i.e. non-interceptor) native call is the result of 1527 // A direct (i.e. non-interceptor) native call is the result of
1527 // optimization. The optimization ensures any type checks or 1528 // optimization. The optimization ensures any type checks or
1528 // conversions have been satisified. 1529 // conversions have been satisified.
1529 methodName = target.fixedBackendName; 1530 methodName = target.fixedBackendName;
1530 } 1531 }
1531 } 1532 }
1532 1533
1534 js.Name methodLiteral;
1533 if (methodName == null) { 1535 if (methodName == null) {
1534 methodName = backend.namer.invocationName(node.selector); 1536 methodLiteral = backend.namer.invocationName(node.selector);
1535 registerMethodInvoke(node); 1537 registerMethodInvoke(node);
1538 } else {
1539 methodLiteral = backend.namer.asName(methodName);
1536 } 1540 }
1537 push(js.propertyCall(object, methodName, arguments), node); 1541 push(js.propertyCall(object, methodLiteral, arguments), node);
1538 } 1542 }
1539 1543
1540 void visitInvokeConstructorBody(HInvokeConstructorBody node) { 1544 void visitInvokeConstructorBody(HInvokeConstructorBody node) {
1541 use(node.inputs[0]); 1545 use(node.inputs[0]);
1542 js.Expression object = pop(); 1546 js.Expression object = pop();
1543 String methodName = backend.namer.instanceMethodName(node.element); 1547 js.Name methodName = backend.namer.instanceMethodName(node.element);
1544 List<js.Expression> arguments = visitArguments(node.inputs); 1548 List<js.Expression> arguments = visitArguments(node.inputs);
1545 push(js.propertyCall(object, methodName, arguments), node); 1549 push(js.propertyCall(object, methodName, arguments), node);
1546 registry.registerStaticUse(node.element); 1550 registry.registerStaticUse(node.element);
1547 } 1551 }
1548 1552
1549 void visitOneShotInterceptor(HOneShotInterceptor node) { 1553 void visitOneShotInterceptor(HOneShotInterceptor node) {
1550 List<js.Expression> arguments = visitArguments(node.inputs); 1554 List<js.Expression> arguments = visitArguments(node.inputs);
1551 var isolate = new js.VariableUse( 1555 var isolate = new js.VariableUse(
1552 backend.namer.globalObjectFor(backend.interceptorsLibrary)); 1556 backend.namer.globalObjectFor(backend.interceptorsLibrary));
1553 Selector selector = node.selector; 1557 Selector selector = node.selector;
1554 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask); 1558 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
1555 String methodName = backend.registerOneShotInterceptor(selector); 1559 js.Name methodName = backend.registerOneShotInterceptor(selector);
1556 push(js.propertyCall(isolate, methodName, arguments), node); 1560 push(js.propertyCall(isolate, methodName, arguments), node);
1557 if (selector.isGetter) { 1561 if (selector.isGetter) {
1558 registerGetter(node); 1562 registerGetter(node);
1559 } else if (selector.isSetter) { 1563 } else if (selector.isSetter) {
1560 registerSetter(node); 1564 registerSetter(node);
1561 } else { 1565 } else {
1562 registerMethodInvoke(node); 1566 registerMethodInvoke(node);
1563 } 1567 }
1564 registry.registerUseInterceptor(); 1568 registry.registerUseInterceptor();
1565 } 1569 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 1614
1611 void registerGetter(HInvokeDynamic node) { 1615 void registerGetter(HInvokeDynamic node) {
1612 Selector selector = node.selector; 1616 Selector selector = node.selector;
1613 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask); 1617 TypeMask mask = getOptimizedSelectorFor(node, selector, node.mask);
1614 registry.registerDynamicGetter( 1618 registry.registerDynamicGetter(
1615 new UniverseSelector(selector, mask)); 1619 new UniverseSelector(selector, mask));
1616 } 1620 }
1617 1621
1618 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { 1622 visitInvokeDynamicSetter(HInvokeDynamicSetter node) {
1619 use(node.receiver); 1623 use(node.receiver);
1620 String name = backend.namer.invocationName(node.selector); 1624 js.Name name = backend.namer.invocationName(node.selector);
1621 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node); 1625 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node);
1622 registerSetter(node); 1626 registerSetter(node);
1623 } 1627 }
1624 1628
1625 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { 1629 visitInvokeDynamicGetter(HInvokeDynamicGetter node) {
1626 use(node.receiver); 1630 use(node.receiver);
1627 String name = backend.namer.invocationName(node.selector); 1631 js.Name name = backend.namer.invocationName(node.selector);
1628 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node); 1632 push(js.propertyCall(pop(), name, visitArguments(node.inputs)), node);
1629 registerGetter(node); 1633 registerGetter(node);
1630 } 1634 }
1631 1635
1632 visitInvokeClosure(HInvokeClosure node) { 1636 visitInvokeClosure(HInvokeClosure node) {
1633 Selector call = new Selector.callClosureFrom(node.selector); 1637 Selector call = new Selector.callClosureFrom(node.selector);
1634 use(node.receiver); 1638 use(node.receiver);
1635 push(js.propertyCall(pop(), 1639 push(js.propertyCall(pop(),
1636 backend.namer.invocationName(call), 1640 backend.namer.invocationName(call),
1637 visitArguments(node.inputs)), 1641 visitArguments(node.inputs)),
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 push(new js.Call(pop(), arguments), node); 1684 push(new js.Call(pop(), arguments), node);
1681 } 1685 }
1682 1686
1683 } 1687 }
1684 1688
1685 visitInvokeSuper(HInvokeSuper node) { 1689 visitInvokeSuper(HInvokeSuper node) {
1686 Element superMethod = node.element; 1690 Element superMethod = node.element;
1687 registry.registerSuperInvocation(superMethod); 1691 registry.registerSuperInvocation(superMethod);
1688 ClassElement superClass = superMethod.enclosingClass; 1692 ClassElement superClass = superMethod.enclosingClass;
1689 if (superMethod.kind == ElementKind.FIELD) { 1693 if (superMethod.kind == ElementKind.FIELD) {
1690 String fieldName = backend.namer.instanceFieldPropertyName(superMethod); 1694 js.Name fieldName =
1695 backend.namer.instanceFieldPropertyName(superMethod);
1691 use(node.inputs[0]); 1696 use(node.inputs[0]);
1692 js.PropertyAccess access = 1697 js.PropertyAccess access = new js.PropertyAccess(pop(), fieldName);
1693 new js.PropertyAccess.field(pop(), fieldName);
1694 if (node.isSetter) { 1698 if (node.isSetter) {
1695 use(node.value); 1699 use(node.value);
1696 push(new js.Assignment(access, pop()), node); 1700 push(new js.Assignment(access, pop()), node);
1697 } else { 1701 } else {
1698 push(access, node); 1702 push(access, node);
1699 } 1703 }
1700 } else { 1704 } else {
1701 Selector selector = node.selector; 1705 Selector selector = node.selector;
1702 1706
1703 if (!backend.maybeRegisterAliasedSuperMember(superMethod, selector)) { 1707 if (!backend.maybeRegisterAliasedSuperMember(superMethod, selector)) {
1704 String methodName; 1708 js.Name methodName;
1705 if (selector.isGetter) { 1709 if (selector.isGetter) {
1706 // If the selector we need to register a typed getter to the 1710 // If the selector we need to register a typed getter to the
1707 // [world]. The emitter needs to know if it needs to emit a 1711 // [world]. The emitter needs to know if it needs to emit a
1708 // bound closure for a method. 1712 // bound closure for a method.
1709 TypeMask receiverType = 1713 TypeMask receiverType =
1710 new TypeMask.nonNullExact(superClass, compiler.world); 1714 new TypeMask.nonNullExact(superClass, compiler.world);
1711 // TODO(floitsch): we know the target. We shouldn't register a 1715 // TODO(floitsch): we know the target. We shouldn't register a
1712 // dynamic getter. 1716 // dynamic getter.
1713 registry.registerDynamicGetter( 1717 registry.registerDynamicGetter(
1714 new UniverseSelector(selector, receiverType)); 1718 new UniverseSelector(selector, receiverType));
(...skipping 26 matching lines...) Expand all
1741 // We access a JavaScript member we know all objects besides 1745 // We access a JavaScript member we know all objects besides
1742 // null and undefined have: V8 does not like accessing a member 1746 // null and undefined have: V8 does not like accessing a member
1743 // that does not exist. 1747 // that does not exist.
1744 push(new js.PropertyAccess.field(pop(), 'toString'), node); 1748 push(new js.PropertyAccess.field(pop(), 'toString'), node);
1745 } else if (element == backend.jsIndexableLength) { 1749 } else if (element == backend.jsIndexableLength) {
1746 // We're accessing a native JavaScript property called 'length' 1750 // We're accessing a native JavaScript property called 'length'
1747 // on a JS String or a JS array. Therefore, the name of that 1751 // on a JS String or a JS array. Therefore, the name of that
1748 // property should not be mangled. 1752 // property should not be mangled.
1749 push(new js.PropertyAccess.field(pop(), 'length'), node); 1753 push(new js.PropertyAccess.field(pop(), 'length'), node);
1750 } else { 1754 } else {
1751 String name = backend.namer.instanceFieldPropertyName(element); 1755 js.Name name = backend.namer.instanceFieldPropertyName(element);
1752 push(new js.PropertyAccess.field(pop(), name), node); 1756 push(new js.PropertyAccess(pop(), name), node);
1753 registry.registerFieldGetter(element); 1757 registry.registerFieldGetter(element);
1754 } 1758 }
1755 } 1759 }
1756 1760
1757 visitFieldSet(HFieldSet node) { 1761 visitFieldSet(HFieldSet node) {
1758 Element element = node.element; 1762 Element element = node.element;
1759 registry.registerFieldSetter(element); 1763 registry.registerFieldSetter(element);
1760 String name = backend.namer.instanceFieldPropertyName(element); 1764 js.Name name = backend.namer.instanceFieldPropertyName(element);
1761 use(node.receiver); 1765 use(node.receiver);
1762 js.Expression receiver = pop(); 1766 js.Expression receiver = pop();
1763 use(node.value); 1767 use(node.value);
1764 push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()), 1768 push(new js.Assignment(new js.PropertyAccess(receiver, name), pop()),
1765 node); 1769 node);
1766 } 1770 }
1767 1771
1768 visitReadModifyWrite(HReadModifyWrite node) { 1772 visitReadModifyWrite(HReadModifyWrite node) {
1769 Element element = node.element; 1773 Element element = node.element;
1770 registry.registerFieldSetter(element); 1774 registry.registerFieldSetter(element);
1771 String name = backend.namer.instanceFieldPropertyName(element); 1775 js.Name name = backend.namer.instanceFieldPropertyName(element);
1772 use(node.receiver); 1776 use(node.receiver);
1773 js.Expression fieldReference = new js.PropertyAccess.field(pop(), name); 1777 js.Expression fieldReference = new js.PropertyAccess(pop(), name);
1774 if (node.isPreOp) { 1778 if (node.isPreOp) {
1775 push(new js.Prefix(node.jsOp, fieldReference), node); 1779 push(new js.Prefix(node.jsOp, fieldReference), node);
1776 } else if (node.isPostOp) { 1780 } else if (node.isPostOp) {
1777 push(new js.Postfix(node.jsOp, fieldReference), node); 1781 push(new js.Postfix(node.jsOp, fieldReference), node);
1778 } else { 1782 } else {
1779 use(node.value); 1783 use(node.value);
1780 push(new js.Assignment.compound(fieldReference, node.jsOp, pop()), node); 1784 push(new js.Assignment.compound(fieldReference, node.jsOp, pop()), node);
1781 } 1785 }
1782 } 1786 }
1783 1787
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
2357 checkTypeViaProperty(input, type, negative); 2361 checkTypeViaProperty(input, type, negative);
2358 } 2362 }
2359 } 2363 }
2360 2364
2361 void checkTypeViaProperty(HInstruction input, DartType type, bool negative) { 2365 void checkTypeViaProperty(HInstruction input, DartType type, bool negative) {
2362 registry.registerIsCheck(type); 2366 registry.registerIsCheck(type);
2363 2367
2364 use(input); 2368 use(input);
2365 2369
2366 js.PropertyAccess field = 2370 js.PropertyAccess field =
2367 new js.PropertyAccess.field(pop(), backend.namer.operatorIsType(type)); 2371 new js.PropertyAccess(pop(), backend.namer.operatorIsType(type));
2368 // We always negate at least once so that the result is boolified. 2372 // We always negate at least once so that the result is boolified.
2369 push(new js.Prefix('!', field)); 2373 push(new js.Prefix('!', field));
2370 // If the result is not negated, put another '!' in front. 2374 // If the result is not negated, put another '!' in front.
2371 if (!negative) push(new js.Prefix('!', pop())); 2375 if (!negative) push(new js.Prefix('!', pop()));
2372 } 2376 }
2373 2377
2374 void checkTypeViaInstanceof( 2378 void checkTypeViaInstanceof(
2375 HInstruction input, DartType type, bool negative) { 2379 HInstruction input, DartType type, bool negative) {
2376 registry.registerIsCheck(type); 2380 registry.registerIsCheck(type);
2377 2381
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 node.checkedInput.isIntegerOrNull(compiler)); 2592 node.checkedInput.isIntegerOrNull(compiler));
2589 js.Expression test = generateReceiverOrArgumentTypeTest( 2593 js.Expression test = generateReceiverOrArgumentTypeTest(
2590 node.checkedInput, node.checkedType); 2594 node.checkedInput, node.checkedType);
2591 js.Block oldContainer = currentContainer; 2595 js.Block oldContainer = currentContainer;
2592 js.Statement body = new js.Block.empty(); 2596 js.Statement body = new js.Block.empty();
2593 currentContainer = body; 2597 currentContainer = body;
2594 if (node.isArgumentTypeCheck) { 2598 if (node.isArgumentTypeCheck) {
2595 generateThrowWithHelper('iae', node.checkedInput); 2599 generateThrowWithHelper('iae', node.checkedInput);
2596 } else if (node.isReceiverTypeCheck) { 2600 } else if (node.isReceiverTypeCheck) {
2597 use(node.checkedInput); 2601 use(node.checkedInput);
2598 String methodName = 2602 js.Name methodName =
2599 backend.namer.invocationName(node.receiverTypeCheckSelector); 2603 backend.namer.invocationName(node.receiverTypeCheckSelector);
2600 js.Expression call = js.propertyCall(pop(), methodName, []); 2604 js.Expression call = js.propertyCall(pop(), methodName, []);
2601 pushStatement(new js.Return(call)); 2605 pushStatement(new js.Return(call));
2602 } 2606 }
2603 currentContainer = oldContainer; 2607 currentContainer = oldContainer;
2604 body = unwrapStatement(body); 2608 body = unwrapStatement(body);
2605 pushStatement(new js.If.noElse(test, body), node); 2609 pushStatement(new js.If.noElse(test, body), node);
2606 return; 2610 return;
2607 } 2611 }
2608 2612
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2735 js.PropertyAccess accessHelper(String name) { 2739 js.PropertyAccess accessHelper(String name) {
2736 Element helper = backend.findHelper(name); 2740 Element helper = backend.findHelper(name);
2737 if (helper == null) { 2741 if (helper == null) {
2738 // For mocked-up tests. 2742 // For mocked-up tests.
2739 return js.js('(void 0).$name'); 2743 return js.js('(void 0).$name');
2740 } 2744 }
2741 registry.registerStaticUse(helper); 2745 registry.registerStaticUse(helper);
2742 return backend.emitter.staticFunctionAccess(helper); 2746 return backend.emitter.staticFunctionAccess(helper);
2743 } 2747 }
2744 } 2748 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698