| 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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 final JavaScriptBackend backend; | 6 final JavaScriptBackend backend; |
| 7 SsaCodeGeneratorTask(JavaScriptBackend backend) | 7 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 8 : this.backend = backend, | 8 : this.backend = backend, |
| 9 super(backend.compiler); | 9 super(backend.compiler); |
| 10 String get name() => 'SSA code generator'; | 10 String get name() => 'SSA code generator'; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 static final int STATE_EXPRESSION = 3; | 116 static final int STATE_EXPRESSION = 3; |
| 117 static final int STATE_DECLARATION = 4; | 117 static final int STATE_DECLARATION = 4; |
| 118 | 118 |
| 119 /** | 119 /** |
| 120 * When analyzing a [HStatementGraph] we try to recognize if it has | 120 * When analyzing a [HStatementGraph] we try to recognize if it has |
| 121 * the following properties. | 121 * the following properties. |
| 122 */ | 122 */ |
| 123 static final int ONE_STATEMENT = 0; | 123 static final int ONE_STATEMENT = 0; |
| 124 static final int ONE_EXPRESSION = 1; | 124 static final int ONE_EXPRESSION = 1; |
| 125 static final int EMPTY = 2; | 125 static final int EMPTY = 2; |
| 126 static final int IF_STATEMENT = 3; | 126 static final int MULTIPLE_STATEMENTS = 3; |
| 127 static final int MULTIPLE_STATEMENTS = 4; | |
| 128 | 127 |
| 129 /** | 128 /** |
| 130 * Returned by [expressionType] to tell how code can be generated for | 129 * Returned by [expressionType] to tell how code can be generated for |
| 131 * a subgraph. | 130 * a subgraph. |
| 132 * - [TYPE_STATEMENT] means that the graph must be generated as a statement, | 131 * - [TYPE_STATEMENT] means that the graph must be generated as a statement, |
| 133 * which is always possible. | 132 * which is always possible. |
| 134 * - [TYPE_EXPRESSION] means that the graph can be generated as an expression, | 133 * - [TYPE_EXPRESSION] means that the graph can be generated as an expression, |
| 135 * or possibly several comma-separated expressions. | 134 * or possibly several comma-separated expressions. |
| 136 * - [TYPE_DECLARATION] means that the graph can be generated as an | 135 * - [TYPE_DECLARATION] means that the graph can be generated as an |
| 137 * expression, and that it only generates expressions of the form | 136 * expression, and that it only generates expressions of the form |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 * Set of variables that have already been declared. | 168 * Set of variables that have already been declared. |
| 170 */ | 169 */ |
| 171 final Set<String> declaredVariables; | 170 final Set<String> declaredVariables; |
| 172 | 171 |
| 173 Element equalsNullElement; | 172 Element equalsNullElement; |
| 174 Element boolifiedEqualsNullElement; | 173 Element boolifiedEqualsNullElement; |
| 175 int indent = 0; | 174 int indent = 0; |
| 176 int expectedPrecedence = JSPrecedence.STATEMENT_PRECEDENCE; | 175 int expectedPrecedence = JSPrecedence.STATEMENT_PRECEDENCE; |
| 177 JSBinaryOperatorPrecedence unsignedShiftPrecedences; | 176 JSBinaryOperatorPrecedence unsignedShiftPrecedences; |
| 178 HGraph currentGraph; | 177 HGraph currentGraph; |
| 179 | |
| 180 /** | 178 /** |
| 181 * Whether the code-generation should try to generate an expression | 179 * Whether the code-generation should try to generate an expression |
| 182 * instead of a sequence of statements. | 180 * instead of a sequence of statements. |
| 183 */ | 181 */ |
| 184 int generationState = STATE_STATEMENT; | 182 int generationState = STATE_STATEMENT; |
| 185 | |
| 186 /** | |
| 187 * Whether we are generating a statement that does not need | |
| 188 * indentation (e.g. an 'if' in an 'else if'). | |
| 189 */ | |
| 190 bool generatingInlineStatement = false; | |
| 191 | |
| 192 HBasicBlock currentBlock; | 183 HBasicBlock currentBlock; |
| 193 | 184 |
| 194 // Records a block-information that is being handled specially. | 185 // Records a block-information that is being handled specially. |
| 195 // Used to break bad recursion. | 186 // Used to break bad recursion. |
| 196 HBlockInformation currentBlockInformation; | 187 HBlockInformation currentBlockInformation; |
| 197 // The subgraph is used to delimit traversal for some constructions, e.g., | 188 // The subgraph is used to delimit traversal for some constructions, e.g., |
| 198 // if branches. | 189 // if branches. |
| 199 SubGraph subGraph; | 190 SubGraph subGraph; |
| 200 | 191 |
| 201 LibraryElement get currentLibrary() => work.element.getLibrary(); | 192 LibraryElement get currentLibrary() => work.element.getLibrary(); |
| (...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1330 // information in [visitTryInfo], or not at all, in the case of the bailout | 1321 // information in [visitTryInfo], or not at all, in the case of the bailout |
| 1331 // generator. | 1322 // generator. |
| 1332 compiler.internalError('visitTry should not be called', instruction: node); | 1323 compiler.internalError('visitTry should not be called', instruction: node); |
| 1333 } | 1324 } |
| 1334 | 1325 |
| 1335 /** | 1326 /** |
| 1336 * Analyzes the given [graph] to know whether it is empty, or | 1327 * Analyzes the given [graph] to know whether it is empty, or |
| 1337 * contains one statement, one expression, or multiple statements. | 1328 * contains one statement, one expression, or multiple statements. |
| 1338 */ | 1329 */ |
| 1339 int analyzeGraphForCodegen(HStatementInformation graph) { | 1330 int analyzeGraphForCodegen(HStatementInformation graph) { |
| 1340 return analyzeBlocksForCodegen(graph.start, graph.end); | 1331 HBasicBlock start = graph.start; |
| 1341 } | 1332 HBasicBlock end = graph.end; |
| 1333 // Only deal with single blocks for now. TODO(ngeoffray): analyze |
| 1334 // all blocks. |
| 1335 if (start !== end) return MULTIPLE_STATEMENTS; |
| 1342 | 1336 |
| 1343 int analyzeBlocksForCodegen(HBasicBlock start, HBasicBlock end) { | |
| 1344 int kind = EMPTY; | 1337 int kind = EMPTY; |
| 1345 bool updateKind(int newKind) { | 1338 bool updateKind(int newKind) { |
| 1346 if (kind != EMPTY) return false; | 1339 if (kind != EMPTY) return false; |
| 1347 kind = newKind; | 1340 kind = newKind; |
| 1348 return true; | 1341 return true; |
| 1349 } | 1342 } |
| 1350 | 1343 |
| 1351 for (HInstruction instruction = start.first; | 1344 for (HInstruction instruction = start.first; |
| 1352 instruction != start.last; | 1345 instruction != start.last; |
| 1353 instruction = instruction.next) { | 1346 instruction = instruction.next) { |
| 1354 if (instruction.isStatement()) { | 1347 if (instruction.isStatement()) { |
| 1355 if (!updateKind(ONE_STATEMENT)) return MULTIPLE_STATEMENTS; | 1348 if (!updateKind(ONE_STATEMENT)) return MULTIPLE_STATEMENTS; |
| 1356 } else if (!isGenerateAtUseSite(instruction)) { | 1349 } else if (!isGenerateAtUseSite(instruction)) { |
| 1357 if (!updateKind(ONE_EXPRESSION)) return MULTIPLE_STATEMENTS; | 1350 if (!updateKind(ONE_EXPRESSION)) return MULTIPLE_STATEMENTS; |
| 1358 } | 1351 } |
| 1359 } | 1352 } |
| 1360 | 1353 |
| 1361 HInstruction last = start.last; | 1354 HInstruction last = start.last; |
| 1362 if (last is HGoto) { | 1355 if (last is !HGoto) { |
| 1363 if (start !== end) { | 1356 if (!updateKind(last.isStatement() ? ONE_STATEMENT : ONE_EXPRESSION)) { |
| 1364 int nextKind = analyzeBlocksForCodegen(start.successors[0], end); | |
| 1365 if (!updateKind(nextKind)) return MULTIPLE_STATEMENTS; | |
| 1366 } | |
| 1367 } else if (last is HIf) { | |
| 1368 HIf ifInstruction = last; | |
| 1369 if (ifInstruction.joinBlock !== null | |
| 1370 && analyzeBlocksForCodegen(ifInstruction.joinBlock, end) != EMPTY) { | |
| 1371 return MULTIPLE_STATEMENTS; | 1357 return MULTIPLE_STATEMENTS; |
| 1372 } | 1358 } |
| 1373 int ifKind = controlFlowOperators.contains(ifInstruction) | |
| 1374 ? ONE_EXPRESSION | |
| 1375 : IF_STATEMENT; | |
| 1376 if (!updateKind(ifKind)) return MULTIPLE_STATEMENTS; | |
| 1377 } else if (start !== end) { | |
| 1378 return MULTIPLE_STATEMENTS; | |
| 1379 } else if (!updateKind( | |
| 1380 last.isStatement() ? ONE_STATEMENT : ONE_EXPRESSION)) { | |
| 1381 return MULTIPLE_STATEMENTS; | |
| 1382 } | 1359 } |
| 1383 | 1360 |
| 1384 CopyHandler handler = variableNames.getCopyHandler(start); | 1361 CopyHandler handler = variableNames.getCopyHandler(start); |
| 1385 if (handler !== null && !handler.isEmpty()) { | 1362 if (handler !== null && !handler.isEmpty()) { |
| 1386 if (handler.assignments.length > 1) return MULTIPLE_STATEMENTS; | 1363 if (handler.assignments.length > 1) return MULTIPLE_STATEMENTS; |
| 1387 if (handler.assignments.length == 1) { | 1364 if (handler.assignments.length == 1) { |
| 1388 if (!updateKind(ONE_STATEMENT)) return MULTIPLE_STATEMENTS; | 1365 if (!updateKind(ONE_STATEMENT)) return MULTIPLE_STATEMENTS; |
| 1389 } | 1366 } |
| 1390 // If the block has a copy where the destination and source are | 1367 // If the block has a copy where the destination and source are |
| 1391 // different, we will emit that copy, and therefore the block is | 1368 // different, we will emit that copy, and therefore the block is |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1405 if (!controlFlowOperators.contains(node)) return false; | 1382 if (!controlFlowOperators.contains(node)) return false; |
| 1406 HPhi phi = node.joinBlock.phis.first; | 1383 HPhi phi = node.joinBlock.phis.first; |
| 1407 bool atUseSite = isGenerateAtUseSite(phi); | 1384 bool atUseSite = isGenerateAtUseSite(phi); |
| 1408 // Don't generate a conditional operator in this situation: | 1385 // Don't generate a conditional operator in this situation: |
| 1409 // i = condition ? bar() : i; | 1386 // i = condition ? bar() : i; |
| 1410 // But generate this instead: | 1387 // But generate this instead: |
| 1411 // if (condition) i = bar(); | 1388 // if (condition) i = bar(); |
| 1412 // Usually, the variable name is longer than 'if' and it takes up | 1389 // Usually, the variable name is longer than 'if' and it takes up |
| 1413 // more space to duplicate the name. | 1390 // more space to duplicate the name. |
| 1414 if (!atUseSite | 1391 if (!atUseSite |
| 1415 && !generatingInlineStatement | |
| 1416 && variableNames.getName(phi) == variableNames.getName(phi.inputs[1])) { | 1392 && variableNames.getName(phi) == variableNames.getName(phi.inputs[1])) { |
| 1417 return false; | 1393 return false; |
| 1418 } | 1394 } |
| 1419 if (!atUseSite) define(phi); | 1395 if (!atUseSite) define(phi); |
| 1420 visitBasicBlock(node.joinBlock); | 1396 visitBasicBlock(node.joinBlock); |
| 1421 return true; | 1397 return true; |
| 1422 } | 1398 } |
| 1423 | 1399 |
| 1424 void generateIf(HIf node, HIfBlockInformation info) { | 1400 void generateIf(HIf node, HIfBlockInformation info) { |
| 1425 HStatementInformation thenGraph = info.thenGraph; | 1401 HStatementInformation thenGraph = info.thenGraph; |
| 1426 HStatementInformation elseGraph = info.elseGraph; | 1402 HStatementInformation elseGraph = info.elseGraph; |
| 1427 int thenKind = analyzeGraphForCodegen(thenGraph); | 1403 int thenKind = analyzeGraphForCodegen(thenGraph); |
| 1428 int elseKind = analyzeGraphForCodegen(elseGraph); | 1404 int elseKind = analyzeGraphForCodegen(elseGraph); |
| 1429 | 1405 |
| 1430 void visitWithoutIndent(HStatementInformation toVisit) { | 1406 void visitWithoutIndent(HStatementInformation toVisit) { |
| 1431 generatingInlineStatement = true; | 1407 int oldIndent = indent; |
| 1432 visitSubGraph(new SubGraph(toVisit.start, toVisit.end)); | 1408 indent = 0; |
| 1409 generateStatements(toVisit); |
| 1410 indent = oldIndent; |
| 1433 } | 1411 } |
| 1434 | 1412 |
| 1435 void visitWithIndent(HStatementInformation toVisit) { | 1413 void visitWithIndent(HStatementInformation toVisit) { |
| 1436 buffer.add('{\n'); | 1414 buffer.add('{\n'); |
| 1437 indent++; | 1415 indent++; |
| 1438 visitSubGraph(new SubGraph(toVisit.start, toVisit.end)); | 1416 generateStatements(toVisit); |
| 1439 indent--; | 1417 indent--; |
| 1440 addIndented('}'); | 1418 addIndented('}'); |
| 1441 } | 1419 } |
| 1442 | 1420 |
| 1443 void emitIf() { | 1421 void emitIf() { |
| 1444 addIndented('if ('); | 1422 addIndented('if ('); |
| 1445 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); | 1423 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); |
| 1446 buffer.add(') '); | 1424 buffer.add(') '); |
| 1447 } | 1425 } |
| 1448 | 1426 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1472 use(node.inputs[0], JSPrecedence.STATEMENT_PRECEDENCE); | 1450 use(node.inputs[0], JSPrecedence.STATEMENT_PRECEDENCE); |
| 1473 buffer.add(';\n'); | 1451 buffer.add(';\n'); |
| 1474 } | 1452 } |
| 1475 break; | 1453 break; |
| 1476 | 1454 |
| 1477 case ONE_EXPRESSION: | 1455 case ONE_EXPRESSION: |
| 1478 generateAnd(elseGraph, () { generateNot(node.inputs[0]); }); | 1456 generateAnd(elseGraph, () { generateNot(node.inputs[0]); }); |
| 1479 break; | 1457 break; |
| 1480 | 1458 |
| 1481 case ONE_STATEMENT: | 1459 case ONE_STATEMENT: |
| 1482 case IF_STATEMENT: | |
| 1483 addIndented('if ('); | 1460 addIndented('if ('); |
| 1484 generateNot(node.inputs[0]); | 1461 generateNot(node.inputs[0]); |
| 1485 buffer.add(') '); | 1462 buffer.add(') '); |
| 1486 visitWithoutIndent(elseGraph); | 1463 visitWithoutIndent(elseGraph); |
| 1487 break; | 1464 break; |
| 1488 | 1465 |
| 1489 case MULTIPLE_STATEMENTS: | 1466 case MULTIPLE_STATEMENTS: |
| 1490 addIndented('if ('); | 1467 addIndented('if ('); |
| 1491 generateNot(node.inputs[0]); | 1468 generateNot(node.inputs[0]); |
| 1492 buffer.add(') '); | 1469 buffer.add(') '); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1505 int precedence = operatorPrecedence.left; | 1482 int precedence = operatorPrecedence.left; |
| 1506 generateAnd(thenGraph, () { use(node.inputs[0], precedence); }); | 1483 generateAnd(thenGraph, () { use(node.inputs[0], precedence); }); |
| 1507 } else { | 1484 } else { |
| 1508 emitIf(); | 1485 emitIf(); |
| 1509 visitWithoutIndent(thenGraph); | 1486 visitWithoutIndent(thenGraph); |
| 1510 } | 1487 } |
| 1511 break; | 1488 break; |
| 1512 | 1489 |
| 1513 case ONE_EXPRESSION: | 1490 case ONE_EXPRESSION: |
| 1514 case ONE_STATEMENT: | 1491 case ONE_STATEMENT: |
| 1515 case IF_STATEMENT: | |
| 1516 // TODO(ngeoffray): Generate a conditional. | 1492 // TODO(ngeoffray): Generate a conditional. |
| 1517 emitIf(); | 1493 emitIf(); |
| 1518 visitWithoutIndent(thenGraph); | 1494 visitWithoutIndent(thenGraph); |
| 1519 if (thenGraphHasSuccessor) { | 1495 if (thenGraphHasSuccessor) { |
| 1520 addIndented('else '); | 1496 addIndented('else '); |
| 1521 visitWithoutIndent(elseGraph); | 1497 visitWithoutIndent(elseGraph); |
| 1522 } else { | 1498 } else { |
| 1523 generateStatements(elseGraph); | 1499 generateStatements(elseGraph); |
| 1524 } | 1500 } |
| 1525 break; | 1501 break; |
| 1526 | 1502 |
| 1527 case MULTIPLE_STATEMENTS: | 1503 case MULTIPLE_STATEMENTS: |
| 1528 emitIf(); | 1504 emitIf(); |
| 1529 visitWithoutIndent(thenGraph); | 1505 visitWithoutIndent(thenGraph); |
| 1530 if (thenGraphHasSuccessor) { | 1506 if (thenGraphHasSuccessor) { |
| 1531 addIndented('else '); | 1507 addIndented('else '); |
| 1532 visitWithIndent(elseGraph); | 1508 visitWithIndent(elseGraph); |
| 1533 buffer.add('\n'); | 1509 buffer.add('\n'); |
| 1534 } else { | 1510 } else { |
| 1535 generateStatements(elseGraph); | 1511 generateStatements(elseGraph); |
| 1536 } | 1512 } |
| 1537 break; | 1513 break; |
| 1538 } | 1514 } |
| 1539 break; | 1515 break; |
| 1540 | 1516 |
| 1541 case MULTIPLE_STATEMENTS: | 1517 case MULTIPLE_STATEMENTS: |
| 1542 case IF_STATEMENT: | |
| 1543 emitIf(); | 1518 emitIf(); |
| 1544 visitWithIndent(thenGraph); | 1519 visitWithIndent(thenGraph); |
| 1545 | 1520 |
| 1546 switch (elseKind) { | 1521 switch (elseKind) { |
| 1547 case EMPTY: | 1522 case EMPTY: |
| 1548 buffer.add('\n'); | 1523 buffer.add('\n'); |
| 1549 break; | 1524 break; |
| 1550 | 1525 |
| 1551 case ONE_EXPRESSION: | 1526 case ONE_EXPRESSION: |
| 1552 case ONE_STATEMENT: | 1527 case ONE_STATEMENT: |
| 1553 case IF_STATEMENT: | |
| 1554 if (thenGraphHasSuccessor) { | 1528 if (thenGraphHasSuccessor) { |
| 1555 buffer.add(' else '); | 1529 buffer.add(' else '); |
| 1556 visitWithoutIndent(elseGraph); | 1530 visitWithoutIndent(elseGraph); |
| 1557 } else { | 1531 } else { |
| 1558 buffer.add('\n'); | 1532 buffer.add('\n'); |
| 1559 generateStatements(elseGraph); | 1533 generateStatements(elseGraph); |
| 1560 } | 1534 } |
| 1561 break; | 1535 break; |
| 1562 | 1536 |
| 1563 case MULTIPLE_STATEMENTS: | 1537 case MULTIPLE_STATEMENTS: |
| 1564 if (thenGraphHasSuccessor) { | 1538 if (thenGraphHasSuccessor) { |
| 1565 buffer.add(' else '); | 1539 buffer.add(' else '); |
| 1566 visitWithIndent(elseGraph); | 1540 visitWithIndent(elseGraph); |
| 1567 buffer.add('\n'); | 1541 buffer.add('\n'); |
| 1568 } else { | 1542 } else { |
| 1569 buffer.add('\n'); | 1543 buffer.add('\n'); |
| 1570 generateStatements(elseGraph); | 1544 generateStatements(elseGraph); |
| 1571 } | 1545 } |
| 1572 break; | 1546 break; |
| 1573 } | 1547 } |
| 1574 break; | 1548 break; |
| 1575 } | 1549 } |
| 1576 } | 1550 } |
| 1577 | 1551 |
| 1552 |
| 1578 visitIf(HIf node) { | 1553 visitIf(HIf node) { |
| 1579 if (tryControlFlowOperation(node)) return; | 1554 if (tryControlFlowOperation(node)) return; |
| 1580 | 1555 |
| 1581 if (subGraph !== null && node.block === subGraph.end) { | 1556 if (subGraph !== null && node.block === subGraph.end) { |
| 1582 if (isGeneratingExpression()) { | 1557 if (isGeneratingExpression()) { |
| 1583 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); | 1558 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); |
| 1584 } | 1559 } |
| 1585 return; | 1560 return; |
| 1586 } | 1561 } |
| 1587 | 1562 |
| 1588 HInstruction condition = node.inputs[0]; | 1563 HInstruction condition = node.inputs[0]; |
| 1589 HIfBlockInformation info = node.blockInformation.body; | 1564 HIfBlockInformation info = node.blockInformation.body; |
| 1590 | 1565 |
| 1591 if (condition.isConstant()) { | 1566 if (condition.isConstant()) { |
| 1592 HConstant constant = condition; | 1567 HConstant constant = condition; |
| 1593 if (constant.constant.isTrue()) { | 1568 if (constant.constant.isTrue()) { |
| 1594 generateStatements(info.thenGraph); | 1569 generateStatements(info.thenGraph); |
| 1595 int thenKind = analyzeGraphForCodegen(info.thenGraph); | |
| 1596 if (thenKind == EMPTY && generatingInlineStatement) { | |
| 1597 // If we are generating an inline statement, but that | |
| 1598 // statement is actually empty, still emit a ';' (one | |
| 1599 // statement) to emit valid syntax (e.g. 'else;'). | |
| 1600 generatingInlineStatement = false; | |
| 1601 buffer.add(';\n'); | |
| 1602 } | |
| 1603 } else { | 1570 } else { |
| 1604 generateStatements(info.elseGraph); | 1571 generateStatements(info.elseGraph); |
| 1605 int elseKind = analyzeGraphForCodegen(info.elseGraph); | |
| 1606 if (elseKind == EMPTY && generatingInlineStatement) { | |
| 1607 generatingInlineStatement = false; | |
| 1608 buffer.add(';\n'); | |
| 1609 } | |
| 1610 } | 1572 } |
| 1611 } else { | 1573 } else { |
| 1612 generateIf(node, info); | 1574 generateIf(node, info); |
| 1613 } | 1575 } |
| 1614 | 1576 |
| 1615 HBasicBlock joinBlock = node.joinBlock; | 1577 HBasicBlock joinBlock = node.joinBlock; |
| 1616 if (joinBlock !== null && joinBlock.dominator !== node.block) { | 1578 if (joinBlock !== null && joinBlock.dominator !== node.block) { |
| 1617 // The join block is dominated by a block in one of the branches. | 1579 // The join block is dominated by a block in one of the branches. |
| 1618 // The subgraph traversal never reached it, so we visit it here | 1580 // The subgraph traversal never reached it, so we visit it here |
| 1619 // instead. | 1581 // instead. |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 buffer.add('throw '); | 2022 buffer.add('throw '); |
| 2061 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE); | 2023 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE); |
| 2062 beginExpression(JSPrecedence.CALL_PRECEDENCE); | 2024 beginExpression(JSPrecedence.CALL_PRECEDENCE); |
| 2063 buffer.add(compiler.namer.isolateAccess(helper)); | 2025 buffer.add(compiler.namer.isolateAccess(helper)); |
| 2064 visitArguments([null, argument]); | 2026 visitArguments([null, argument]); |
| 2065 endExpression(JSPrecedence.CALL_PRECEDENCE); | 2027 endExpression(JSPrecedence.CALL_PRECEDENCE); |
| 2066 endExpression(JSPrecedence.EXPRESSION_PRECEDENCE); | 2028 endExpression(JSPrecedence.EXPRESSION_PRECEDENCE); |
| 2067 } | 2029 } |
| 2068 | 2030 |
| 2069 void addIndentation() { | 2031 void addIndentation() { |
| 2070 if (generatingInlineStatement) { | 2032 for (int i = 0; i < indent; i++) { |
| 2071 generatingInlineStatement = false; | 2033 buffer.add(' '); |
| 2072 } else { | |
| 2073 for (int i = 0; i < indent; i++) { | |
| 2074 buffer.add(' '); | |
| 2075 } | |
| 2076 } | 2034 } |
| 2077 } | 2035 } |
| 2078 | 2036 |
| 2079 void addIndented(String text) { | 2037 void addIndented(String text) { |
| 2080 addIndentation(); | 2038 addIndentation(); |
| 2081 buffer.add(text); | 2039 buffer.add(text); |
| 2082 } | 2040 } |
| 2083 | 2041 |
| 2084 void visitSwitch(HSwitch node) { | 2042 void visitSwitch(HSwitch node) { |
| 2085 // Switches are handled using [visitSwitchInfo]. | 2043 // Switches are handled using [visitSwitchInfo]. |
| (...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2950 startBailoutSwitch(); | 2908 startBailoutSwitch(); |
| 2951 } | 2909 } |
| 2952 } | 2910 } |
| 2953 | 2911 |
| 2954 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2912 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2955 if (labeledBlockInfo.body.start.hasGuards()) { | 2913 if (labeledBlockInfo.body.start.hasGuards()) { |
| 2956 endBailoutSwitch(); | 2914 endBailoutSwitch(); |
| 2957 } | 2915 } |
| 2958 } | 2916 } |
| 2959 } | 2917 } |
| OLD | NEW |