| OLD | NEW |
| 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 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
| 8 | 8 |
| 9 import '../closure.dart'; | 9 import '../closure.dart'; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1517 isAssignable: false)); | 1517 isAssignable: false)); |
| 1518 for (int i = 0; i < fields.length; i++) { | 1518 for (int i = 0; i < fields.length; i++) { |
| 1519 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); | 1519 add(new HFieldSet(fields[i], newObject, constructorArguments[i])); |
| 1520 } | 1520 } |
| 1521 } | 1521 } |
| 1522 removeInlinedInstantiation(type); | 1522 removeInlinedInstantiation(type); |
| 1523 // Create the runtime type information, if needed. | 1523 // Create the runtime type information, if needed. |
| 1524 if (classElement.typeVariables.isNotEmpty && | 1524 if (classElement.typeVariables.isNotEmpty && |
| 1525 backend.classNeedsRti(classElement)) { | 1525 backend.classNeedsRti(classElement)) { |
| 1526 // Read the values of the type arguments and create a HTypeInfoExpression | 1526 // Read the values of the type arguments and create a HTypeInfoExpression |
| 1527 // to set on the newly create object. We can identify the case where the | 1527 // to set on the newly create object. |
| 1528 // expression would be of the form: | |
| 1529 // | |
| 1530 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] | |
| 1531 // | |
| 1532 // and k is the number of type arguments of this. If this is the case, | |
| 1533 // we can simply copy the list from this. | |
| 1534 | |
| 1535 // These locals are modified by [isIndexedTypeArgumentGet]. | |
| 1536 HThis source; // The source of the type arguments. | |
| 1537 bool allIndexed = true; | |
| 1538 int expectedIndex = 0; | |
| 1539 ClassElement contextClass; // The class of `this`. | |
| 1540 int remainingTypeVariables; // The number of 'remaining type variables' | |
| 1541 // of `this`. | |
| 1542 | |
| 1543 /// Helper to identify instructions that read a type variable without | |
| 1544 /// substitution (that is, directly use the index). These are | |
| 1545 /// HTypeInfoReadVariable instructions that require no substitution. | |
| 1546 /// | |
| 1547 /// Return `true` if [instruction] is of that form and the index is the | |
| 1548 /// next index in the sequence (held in [expectedIndex]). | |
| 1549 | |
| 1550 /// TODO: Move this to a simplifier optimization of HTypeInfoExpression. | |
| 1551 bool isIndexedTypeArgumentGet(HInstruction instruction) { | |
| 1552 if (instruction is HTypeInfoReadVariable) { | |
| 1553 HInstruction newSource = instruction.inputs[0]; | |
| 1554 if (newSource is! HThis) { | |
| 1555 return false; | |
| 1556 } | |
| 1557 if (source == null) { | |
| 1558 // This is the first match. Extract the context class for the type | |
| 1559 // variables and get the list of type variables to keep track of how | |
| 1560 // many arguments we need to process. | |
| 1561 source = newSource; | |
| 1562 contextClass = source.sourceElement.enclosingClass; | |
| 1563 if (needsSubstitutionForTypeVariableAccess(contextClass)) { | |
| 1564 return false; | |
| 1565 } | |
| 1566 remainingTypeVariables = contextClass.typeVariables.length; | |
| 1567 } else { | |
| 1568 assert(source == newSource); | |
| 1569 } | |
| 1570 // If there are no more type variables, then there are more type | |
| 1571 // arguments for the new object than the source has, and it can't be | |
| 1572 // a copy. Otherwise remove one argument. | |
| 1573 if (remainingTypeVariables == 0) return false; | |
| 1574 remainingTypeVariables--; | |
| 1575 // Check that the index is the one we expect. | |
| 1576 int index = instruction.variable.element.index; | |
| 1577 return index == expectedIndex++; | |
| 1578 } | |
| 1579 return false; | |
| 1580 } | |
| 1581 | |
| 1582 List<HInstruction> typeArguments = <HInstruction>[]; | 1528 List<HInstruction> typeArguments = <HInstruction>[]; |
| 1583 classElement.typeVariables.forEach((TypeVariableType typeVariable) { | 1529 classElement.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1584 HInstruction argument = localsHandler | 1530 HInstruction argument = localsHandler |
| 1585 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable)); | 1531 .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable)); |
| 1586 if (allIndexed && !isIndexedTypeArgumentGet(argument)) { | |
| 1587 allIndexed = false; | |
| 1588 } | |
| 1589 typeArguments.add(argument); | 1532 typeArguments.add(argument); |
| 1590 }); | 1533 }); |
| 1591 | 1534 |
| 1592 if (source != null && allIndexed && remainingTypeVariables == 0) { | 1535 HInstruction typeInfo = new HTypeInfoExpression( |
| 1593 HInstruction typeInfo = | 1536 TypeInfoExpressionKind.INSTANCE, |
| 1594 new HTypeInfoReadRaw(source, backend.dynamicType); | 1537 classElement.thisType, |
| 1595 add(typeInfo); | 1538 typeArguments, |
| 1596 newObject = callSetRuntimeTypeInfo(typeInfo, newObject); | 1539 backend.dynamicType); |
| 1597 } else { | 1540 add(typeInfo); |
| 1598 HInstruction typeInfo = new HTypeInfoExpression( | 1541 newObject = callSetRuntimeTypeInfo(typeInfo, newObject); |
| 1599 TypeInfoExpressionKind.INSTANCE, | |
| 1600 classElement.thisType, | |
| 1601 typeArguments, | |
| 1602 backend.dynamicType); | |
| 1603 add(typeInfo); | |
| 1604 newObject = callSetRuntimeTypeInfo(typeInfo, newObject); | |
| 1605 } | |
| 1606 } | 1542 } |
| 1607 | 1543 |
| 1608 // Generate calls to the constructor bodies. | 1544 // Generate calls to the constructor bodies. |
| 1609 HInstruction interceptor = null; | 1545 HInstruction interceptor = null; |
| 1610 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { | 1546 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) { |
| 1611 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index]; | 1547 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index]; |
| 1612 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst); | 1548 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst); |
| 1613 if (body == null) continue; | 1549 if (body == null) continue; |
| 1614 | 1550 |
| 1615 List bodyCallInputs = <HInstruction>[]; | 1551 List bodyCallInputs = <HInstruction>[]; |
| (...skipping 6207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7823 const _LoopTypeVisitor(); | 7759 const _LoopTypeVisitor(); |
| 7824 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 7760 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
| 7825 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; | 7761 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
| 7826 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 7762 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
| 7827 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 7763 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 7828 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 7764 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 7829 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 7765 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 7830 int visitSwitchStatement(ast.SwitchStatement node) => | 7766 int visitSwitchStatement(ast.SwitchStatement node) => |
| 7831 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 7767 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
| 7832 } | 7768 } |
| OLD | NEW |