| 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 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 | 10 |
| (...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 updateBody.statements.add(new js.Continue(null)); | 893 updateBody.statements.add(new js.Continue(null)); |
| 894 body.statements.add( | 894 body.statements.add( |
| 895 new js.If(jsCondition, updateBody, new js.Break(null))); | 895 new js.If(jsCondition, updateBody, new js.Break(null))); |
| 896 jsCondition = newLiteralBool(true); | 896 jsCondition = newLiteralBool(true); |
| 897 } | 897 } |
| 898 loop = new js.Do(unwrapStatement(body), jsCondition); | 898 loop = new js.Do(unwrapStatement(body), jsCondition); |
| 899 } | 899 } |
| 900 currentContainer = oldContainer; | 900 currentContainer = oldContainer; |
| 901 break; | 901 break; |
| 902 default: | 902 default: |
| 903 compiler.internalError( | 903 compiler.internalError(condition.conditionExpression, |
| 904 'Unexpected loop kind: ${info.kind}', | 904 'Unexpected loop kind: ${info.kind}.'); |
| 905 instruction: condition.conditionExpression); | |
| 906 } | 905 } |
| 907 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition); | 906 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition); |
| 908 js.Statement result = loop; | 907 js.Statement result = loop; |
| 909 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) { | 908 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) { |
| 910 String continueLabelString = | 909 String continueLabelString = |
| 911 backend.namer.implicitContinueLabelName(info.target); | 910 backend.namer.implicitContinueLabelName(info.target); |
| 912 result = new js.LabeledStatement(continueLabelString, result); | 911 result = new js.LabeledStatement(continueLabelString, result); |
| 913 } | 912 } |
| 914 pushStatement(wrapIntoLabels(result, info.labels)); | 913 pushStatement(wrapIntoLabels(result, info.labels)); |
| 915 return true; | 914 return true; |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 HBasicBlock block = node.block; | 1272 HBasicBlock block = node.block; |
| 1274 assert(block.successors.length == 1); | 1273 assert(block.successors.length == 1); |
| 1275 List<HBasicBlock> dominated = block.dominatedBlocks; | 1274 List<HBasicBlock> dominated = block.dominatedBlocks; |
| 1276 // With the exception of the entry-node which dominates its successor | 1275 // With the exception of the entry-node which dominates its successor |
| 1277 // and the exit node, no block finishing with a 'goto' can have more than | 1276 // and the exit node, no block finishing with a 'goto' can have more than |
| 1278 // one dominated block (since it has only one successor). | 1277 // one dominated block (since it has only one successor). |
| 1279 // If the successor is dominated by another block, then the other block | 1278 // If the successor is dominated by another block, then the other block |
| 1280 // is responsible for visiting the successor. | 1279 // is responsible for visiting the successor. |
| 1281 if (dominated.isEmpty) return; | 1280 if (dominated.isEmpty) return; |
| 1282 if (dominated.length > 2) { | 1281 if (dominated.length > 2) { |
| 1283 compiler.internalError('dominated.length = ${dominated.length}', | 1282 compiler.internalError(node, 'dominated.length = ${dominated.length}'); |
| 1284 instruction: node); | |
| 1285 } | 1283 } |
| 1286 if (dominated.length == 2 && block != currentGraph.entry) { | 1284 if (dominated.length == 2 && block != currentGraph.entry) { |
| 1287 compiler.internalError('node.block != currentGraph.entry', | 1285 compiler.internalError(node, 'node.block != currentGraph.entry'); |
| 1288 instruction: node); | |
| 1289 } | 1286 } |
| 1290 assert(dominated[0] == block.successors[0]); | 1287 assert(dominated[0] == block.successors[0]); |
| 1291 visitBasicBlock(dominated[0]); | 1288 visitBasicBlock(dominated[0]); |
| 1292 } | 1289 } |
| 1293 | 1290 |
| 1294 visitLoopBranch(HLoopBranch node) { | 1291 visitLoopBranch(HLoopBranch node) { |
| 1295 assert(node.block == subGraph.end); | 1292 assert(node.block == subGraph.end); |
| 1296 // We are generating code for a loop condition. | 1293 // We are generating code for a loop condition. |
| 1297 // If we are generating the subgraph as an expression, the | 1294 // If we are generating the subgraph as an expression, the |
| 1298 // condition will be generated as the expression. | 1295 // condition will be generated as the expression. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 // try/catch block, ie the try body is always a predecessor | 1359 // try/catch block, ie the try body is always a predecessor |
| 1363 // of the catch and finally. Here, we continue visiting the try | 1360 // of the catch and finally. Here, we continue visiting the try |
| 1364 // body by visiting the block that contains the user-level control | 1361 // body by visiting the block that contains the user-level control |
| 1365 // flow instruction. | 1362 // flow instruction. |
| 1366 visitBasicBlock(node.bodyTrySuccessor); | 1363 visitBasicBlock(node.bodyTrySuccessor); |
| 1367 } | 1364 } |
| 1368 | 1365 |
| 1369 visitTry(HTry node) { | 1366 visitTry(HTry node) { |
| 1370 // We should never get here. Try/catch/finally is always handled using block | 1367 // We should never get here. Try/catch/finally is always handled using block |
| 1371 // information in [visitTryInfo]. | 1368 // information in [visitTryInfo]. |
| 1372 compiler.internalError('visitTry should not be called', instruction: node); | 1369 compiler.internalError(node, 'visitTry should not be called.'); |
| 1373 } | 1370 } |
| 1374 | 1371 |
| 1375 bool tryControlFlowOperation(HIf node) { | 1372 bool tryControlFlowOperation(HIf node) { |
| 1376 if (!controlFlowOperators.contains(node)) return false; | 1373 if (!controlFlowOperators.contains(node)) return false; |
| 1377 HPhi phi = node.joinBlock.phis.first; | 1374 HPhi phi = node.joinBlock.phis.first; |
| 1378 bool atUseSite = isGenerateAtUseSite(phi); | 1375 bool atUseSite = isGenerateAtUseSite(phi); |
| 1379 // Don't generate a conditional operator in this situation: | 1376 // Don't generate a conditional operator in this situation: |
| 1380 // i = condition ? bar() : i; | 1377 // i = condition ? bar() : i; |
| 1381 // But generate this instead: | 1378 // But generate this instead: |
| 1382 // if (condition) i = bar(); | 1379 // if (condition) i = bar(); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1692 if (type is DartType) { | 1689 if (type is DartType) { |
| 1693 world.registerInstantiatedType(type, work.resolutionTree); | 1690 world.registerInstantiatedType(type, work.resolutionTree); |
| 1694 } | 1691 } |
| 1695 }); | 1692 }); |
| 1696 } | 1693 } |
| 1697 | 1694 |
| 1698 visitForeign(HForeign node) { | 1695 visitForeign(HForeign node) { |
| 1699 List<HInstruction> inputs = node.inputs; | 1696 List<HInstruction> inputs = node.inputs; |
| 1700 if (node.isJsStatement()) { | 1697 if (node.isJsStatement()) { |
| 1701 if (!inputs.isEmpty) { | 1698 if (!inputs.isEmpty) { |
| 1702 compiler.internalError("foreign statement with inputs", | 1699 compiler.internalError(node, "Foreign statement with inputs."); |
| 1703 instruction: node); | |
| 1704 } | 1700 } |
| 1705 pushStatement(node.codeAst, node); | 1701 pushStatement(node.codeAst, node); |
| 1706 } else { | 1702 } else { |
| 1707 if (!inputs.isEmpty) { | 1703 if (!inputs.isEmpty) { |
| 1708 List<js.Expression> interpolatedExpressions = <js.Expression>[]; | 1704 List<js.Expression> interpolatedExpressions = <js.Expression>[]; |
| 1709 for (int i = 0; i < inputs.length; i++) { | 1705 for (int i = 0; i < inputs.length; i++) { |
| 1710 use(inputs[i]); | 1706 use(inputs[i]); |
| 1711 interpolatedExpressions.add(pop()); | 1707 interpolatedExpressions.add(pop()); |
| 1712 } | 1708 } |
| 1713 var visitor = new js.UninterpolateJSExpression(interpolatedExpressions); | 1709 var visitor = new js.UninterpolateJSExpression(interpolatedExpressions); |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2493 checkArray(input, '!=='); | 2489 checkArray(input, '!=='); |
| 2494 js.Expression arrayTest = pop(); | 2490 js.Expression arrayTest = pop(); |
| 2495 | 2491 |
| 2496 js.Binary notIndexingTest = checkIndexingBehavior(input, negative: true) | 2492 js.Binary notIndexingTest = checkIndexingBehavior(input, negative: true) |
| 2497 ? new js.Binary('&&', arrayTest, pop()) | 2493 ? new js.Binary('&&', arrayTest, pop()) |
| 2498 : arrayTest; | 2494 : arrayTest; |
| 2499 js.Binary notObjectOrIndexingTest = | 2495 js.Binary notObjectOrIndexingTest = |
| 2500 new js.Binary('||', objectTest, notIndexingTest); | 2496 new js.Binary('||', objectTest, notIndexingTest); |
| 2501 test = new js.Binary('&&', stringTest, notObjectOrIndexingTest); | 2497 test = new js.Binary('&&', stringTest, notObjectOrIndexingTest); |
| 2502 } else { | 2498 } else { |
| 2503 compiler.internalError('Unexpected check', instruction: input); | 2499 compiler.internalError(input, 'Unexpected check.'); |
| 2504 } | 2500 } |
| 2505 return test; | 2501 return test; |
| 2506 } | 2502 } |
| 2507 | 2503 |
| 2508 void visitTypeConversion(HTypeConversion node) { | 2504 void visitTypeConversion(HTypeConversion node) { |
| 2509 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { | 2505 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { |
| 2510 // An int check if the input is not int or null, is not | 2506 // An int check if the input is not int or null, is not |
| 2511 // sufficient for doing a argument or receiver check. | 2507 // sufficient for doing a argument or receiver check. |
| 2512 assert(!node.checkedType.containsOnlyInt(compiler) || | 2508 assert(!node.checkedType.containsOnlyInt(compiler) || |
| 2513 node.checkedInput.isIntegerOrNull(compiler)); | 2509 node.checkedInput.isIntegerOrNull(compiler)); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2659 js.PropertyAccess accessHelper(String name) { | 2655 js.PropertyAccess accessHelper(String name) { |
| 2660 Element helper = compiler.findHelper(name); | 2656 Element helper = compiler.findHelper(name); |
| 2661 if (helper == null) { | 2657 if (helper == null) { |
| 2662 // For mocked-up tests. | 2658 // For mocked-up tests. |
| 2663 return js.js('(void 0).$name'); | 2659 return js.js('(void 0).$name'); |
| 2664 } | 2660 } |
| 2665 world.registerStaticUse(helper); | 2661 world.registerStaticUse(helper); |
| 2666 return backend.namer.elementAccess(helper); | 2662 return backend.namer.elementAccess(helper); |
| 2667 } | 2663 } |
| 2668 } | 2664 } |
| OLD | NEW |