| 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 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1122 use(node.right, operatorPrecedences.right); | 1122 use(node.right, operatorPrecedences.right); |
| 1123 endExpression(operatorPrecedences.precedence); | 1123 endExpression(operatorPrecedences.precedence); |
| 1124 } else { | 1124 } else { |
| 1125 visitInvokeStatic(node); | 1125 visitInvokeStatic(node); |
| 1126 } | 1126 } |
| 1127 } | 1127 } |
| 1128 | 1128 |
| 1129 // We want the outcome of bit-operations to be positive. We use the unsigned | 1129 // We want the outcome of bit-operations to be positive. We use the unsigned |
| 1130 // shift operator to achieve this. | 1130 // shift operator to achieve this. |
| 1131 visitBitInvokeBinary(HBinaryBitOp node, String op) { | 1131 visitBitInvokeBinary(HBinaryBitOp node, String op) { |
| 1132 if (node.builtin){ | 1132 if (node.builtin) { |
| 1133 beginExpression(unsignedShiftPrecedences.precedence); | 1133 beginExpression(unsignedShiftPrecedences.precedence); |
| 1134 int oldPrecedence = this.expectedPrecedence; | 1134 int oldPrecedence = this.expectedPrecedence; |
| 1135 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; | 1135 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; |
| 1136 visitInvokeBinary(node, op); | 1136 visitInvokeBinary(node, op); |
| 1137 buffer.add(' >>> 0'); | 1137 buffer.add(' >>> 0'); |
| 1138 this.expectedPrecedence = oldPrecedence; | 1138 this.expectedPrecedence = oldPrecedence; |
| 1139 endExpression(unsignedShiftPrecedences.precedence); | 1139 endExpression(unsignedShiftPrecedences.precedence); |
| 1140 } else { | 1140 } else { |
| 1141 visitInvokeBinary(node, op); | 1141 visitInvokeBinary(node, op); |
| 1142 } | 1142 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1195 visitSubtract(HSubtract node) => visitInvokeBinary(node, '-'); | 1195 visitSubtract(HSubtract node) => visitInvokeBinary(node, '-'); |
| 1196 // Truncating divide does not have a JS equivalent. | 1196 // Truncating divide does not have a JS equivalent. |
| 1197 visitTruncatingDivide(HTruncatingDivide node) => visitInvokeStatic(node); | 1197 visitTruncatingDivide(HTruncatingDivide node) => visitInvokeStatic(node); |
| 1198 // Modulo cannot be mapped to the native operator (different semantics). | 1198 // Modulo cannot be mapped to the native operator (different semantics). |
| 1199 visitModulo(HModulo node) => visitInvokeStatic(node); | 1199 visitModulo(HModulo node) => visitInvokeStatic(node); |
| 1200 | 1200 |
| 1201 visitBitAnd(HBitAnd node) => visitBitInvokeBinary(node, '&'); | 1201 visitBitAnd(HBitAnd node) => visitBitInvokeBinary(node, '&'); |
| 1202 visitBitNot(HBitNot node) => visitBitInvokeUnary(node, '~'); | 1202 visitBitNot(HBitNot node) => visitBitInvokeUnary(node, '~'); |
| 1203 visitBitOr(HBitOr node) => visitBitInvokeBinary(node, '|'); | 1203 visitBitOr(HBitOr node) => visitBitInvokeBinary(node, '|'); |
| 1204 visitBitXor(HBitXor node) => visitBitInvokeBinary(node, '^'); | 1204 visitBitXor(HBitXor node) => visitBitInvokeBinary(node, '^'); |
| 1205 | 1205 visitShiftRight(HShiftRight node) => visitBitInvokeBinary(node, '>>'); |
| 1206 // We need to check if the left operand is negative in order to use | 1206 visitShiftLeft(HShiftLeft node) => visitBitInvokeBinary(node, '<<'); |
| 1207 // the native operator. | |
| 1208 visitShiftRight(HShiftRight node) => visitInvokeStatic(node); | |
| 1209 | |
| 1210 // Shift left cannot be mapped to the native operator (different semantics). | |
| 1211 visitShiftLeft(HShiftLeft node) => visitInvokeStatic(node); | |
| 1212 | 1207 |
| 1213 visitNegate(HNegate node) => visitInvokeUnary(node, '-'); | 1208 visitNegate(HNegate node) => visitInvokeUnary(node, '-'); |
| 1214 | 1209 |
| 1215 visitIdentity(HIdentity node) => visitInvokeBinary(node, '==='); | 1210 visitIdentity(HIdentity node) => visitInvokeBinary(node, '==='); |
| 1216 visitLess(HLess node) => visitInvokeBinary(node, '<'); | 1211 visitLess(HLess node) => visitInvokeBinary(node, '<'); |
| 1217 visitLessEqual(HLessEqual node) => visitInvokeBinary(node, '<='); | 1212 visitLessEqual(HLessEqual node) => visitInvokeBinary(node, '<='); |
| 1218 visitGreater(HGreater node) => visitInvokeBinary(node, '>'); | 1213 visitGreater(HGreater node) => visitInvokeBinary(node, '>'); |
| 1219 visitGreaterEqual(HGreaterEqual node) => visitInvokeBinary(node, '>='); | 1214 visitGreaterEqual(HGreaterEqual node) => visitInvokeBinary(node, '>='); |
| 1220 | 1215 |
| 1221 visitBoolify(HBoolify node) { | 1216 visitBoolify(HBoolify node) { |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2001 buffer.add(' >= '); | 1996 buffer.add(' >= '); |
| 2002 use(node.length, JSPrecedence.SHIFT_PRECEDENCE); | 1997 use(node.length, JSPrecedence.SHIFT_PRECEDENCE); |
| 2003 buffer.add(") "); | 1998 buffer.add(") "); |
| 2004 } | 1999 } |
| 2005 generateThrowWithHelper('ioore', node.index); | 2000 generateThrowWithHelper('ioore', node.index); |
| 2006 } | 2001 } |
| 2007 | 2002 |
| 2008 visitIntegerCheck(HIntegerCheck node) { | 2003 visitIntegerCheck(HIntegerCheck node) { |
| 2009 if (!node.alwaysFalse) { | 2004 if (!node.alwaysFalse) { |
| 2010 buffer.add('if ('); | 2005 buffer.add('if ('); |
| 2011 use(node.value, JSPrecedence.EQUALITY_PRECEDENCE); | 2006 checkInt(node.value, '!=='); |
| 2012 buffer.add(' !== ('); | 2007 buffer.add(') '); |
| 2013 use(node.value, JSPrecedence.BITWISE_OR_PRECEDENCE); | |
| 2014 buffer.add(" | 0)) "); | |
| 2015 } | 2008 } |
| 2016 generateThrowWithHelper('iae', node.value); | 2009 generateThrowWithHelper('iae', node.value); |
| 2017 } | 2010 } |
| 2018 | 2011 |
| 2019 void generateThrowWithHelper(String helperName, HInstruction argument) { | 2012 void generateThrowWithHelper(String helperName, HInstruction argument) { |
| 2020 Element helper = compiler.findHelper(new SourceString(helperName)); | 2013 Element helper = compiler.findHelper(new SourceString(helperName)); |
| 2021 world.registerStaticUse(helper); | 2014 world.registerStaticUse(helper); |
| 2022 buffer.add('throw '); | 2015 buffer.add('throw '); |
| 2023 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE); | 2016 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE); |
| 2024 beginExpression(JSPrecedence.CALL_PRECEDENCE); | 2017 beginExpression(JSPrecedence.CALL_PRECEDENCE); |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 buffer.add(".${name.slowToString()} === '${arguments.head}'"); | 2401 buffer.add(".${name.slowToString()} === '${arguments.head}'"); |
| 2409 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); | 2402 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); |
| 2410 }); | 2403 }); |
| 2411 } | 2404 } |
| 2412 if (node.nullOk) { | 2405 if (node.nullOk) { |
| 2413 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); | 2406 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); |
| 2414 } | 2407 } |
| 2415 } | 2408 } |
| 2416 | 2409 |
| 2417 void visitTypeConversion(HTypeConversion node) { | 2410 void visitTypeConversion(HTypeConversion node) { |
| 2418 if (node.checked) { | 2411 if (node.isChecked()) { |
| 2419 Element element = node.type.computeType(compiler).element; | 2412 Element element = node.type.computeType(compiler).element; |
| 2420 world.registerIsCheck(element); | 2413 world.registerIsCheck(element); |
| 2421 SourceString helper; | 2414 SourceString helper; |
| 2422 String additionalArgument; | 2415 String additionalArgument; |
| 2423 bool nativeCheck = | 2416 bool nativeCheck = |
| 2424 backend.emitter.nativeEmitter.requiresNativeIsCheck(element); | 2417 backend.emitter.nativeEmitter.requiresNativeIsCheck(element); |
| 2425 beginExpression(JSPrecedence.CALL_PRECEDENCE); | 2418 beginExpression(JSPrecedence.CALL_PRECEDENCE); |
| 2426 | 2419 |
| 2420 if (node.isArgumentTypeCheck()) { |
| 2421 buffer.add('if ('); |
| 2422 if (element == compiler.intClass) { |
| 2423 checkInt(node.checkedInput, '!=='); |
| 2424 } else { |
| 2425 assert(element == compiler.numClass); |
| 2426 checkNum(node.checkedInput, '!=='); |
| 2427 } |
| 2428 buffer.add(') '); |
| 2429 generateThrowWithHelper('iae', node.checkedInput); |
| 2430 return; |
| 2431 } |
| 2432 |
| 2433 assert(node.isCheckedModeCheck()); |
| 2427 if (element == compiler.stringClass) { | 2434 if (element == compiler.stringClass) { |
| 2428 helper = const SourceString('stringTypeCheck'); | 2435 helper = const SourceString('stringTypeCheck'); |
| 2429 } else if (element == compiler.doubleClass) { | 2436 } else if (element == compiler.doubleClass) { |
| 2430 helper = const SourceString('doubleTypeCheck'); | 2437 helper = const SourceString('doubleTypeCheck'); |
| 2431 } else if (element == compiler.numClass) { | 2438 } else if (element == compiler.numClass) { |
| 2432 helper = const SourceString('numTypeCheck'); | 2439 helper = const SourceString('numTypeCheck'); |
| 2433 } else if (element == compiler.boolClass) { | 2440 } else if (element == compiler.boolClass) { |
| 2434 helper = const SourceString('boolTypeCheck'); | 2441 helper = const SourceString('boolTypeCheck'); |
| 2435 } else if (element == compiler.functionClass || element.isTypedef()) { | 2442 } else if (element == compiler.functionClass || element.isTypedef()) { |
| 2436 helper = const SourceString('functionTypeCheck'); | 2443 helper = const SourceString('functionTypeCheck'); |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2908 startBailoutSwitch(); | 2915 startBailoutSwitch(); |
| 2909 } | 2916 } |
| 2910 } | 2917 } |
| 2911 | 2918 |
| 2912 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2919 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2913 if (labeledBlockInfo.body.start.hasGuards()) { | 2920 if (labeledBlockInfo.body.start.hasGuards()) { |
| 2914 endBailoutSwitch(); | 2921 endBailoutSwitch(); |
| 2915 } | 2922 } |
| 2916 } | 2923 } |
| 2917 } | 2924 } |
| OLD | NEW |