| 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 import 'dart:collection'; |
| 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart'; |
| 8 |
| 9 import '../closure.dart'; |
| 10 import '../common.dart'; |
| 11 import '../common/codegen.dart' show |
| 12 CodegenRegistry, |
| 13 CodegenWorkItem; |
| 14 import '../common/names.dart' show |
| 15 Identifiers, |
| 16 Selectors; |
| 17 import '../common/tasks.dart' show |
| 18 CompilerTask; |
| 19 import '../compiler.dart' show |
| 20 Compiler; |
| 21 import '../constants/constant_system.dart'; |
| 22 import '../constants/expressions.dart'; |
| 23 import '../constants/values.dart'; |
| 24 import '../core_types.dart' show |
| 25 CoreClasses; |
| 26 import '../dart_types.dart'; |
| 27 import '../diagnostics/messages.dart' show |
| 28 Message, |
| 29 MessageTemplate; |
| 30 import '../elements/elements.dart'; |
| 31 import '../elements/modelx.dart' show |
| 32 ConstructorBodyElementX, |
| 33 ElementX, |
| 34 VariableElementX; |
| 35 import '../io/source_information.dart'; |
| 36 import '../js/js.dart' as js; |
| 37 import '../js_backend/backend_helpers.dart' show |
| 38 BackendHelpers; |
| 39 import '../js_backend/js_backend.dart'; |
| 40 import '../js_emitter/js_emitter.dart' show |
| 41 CodeEmitterTask, |
| 42 NativeEmitter; |
| 43 import '../native/native.dart' as native; |
| 44 import '../resolution/operators.dart'; |
| 45 import '../resolution/semantic_visitor.dart'; |
| 46 import '../resolution/tree_elements.dart' show |
| 47 TreeElements; |
| 48 import '../tree/tree.dart' as ast; |
| 49 import '../types/types.dart'; |
| 50 import '../universe/call_structure.dart' show |
| 51 CallStructure; |
| 52 import '../universe/selector.dart' show |
| 53 Selector; |
| 54 import '../universe/side_effects.dart' show |
| 55 SideEffects; |
| 56 import '../universe/use.dart' show |
| 57 DynamicUse, |
| 58 StaticUse, |
| 59 TypeUse; |
| 60 import '../util/util.dart'; |
| 61 import '../world.dart' show |
| 62 ClassWorld, |
| 63 World; |
| 64 import '../dump_info.dart' show InfoReporter; |
| 65 |
| 66 import 'nodes.dart'; |
| 67 import 'codegen.dart'; |
| 68 import 'optimize.dart'; |
| 69 import 'types.dart'; |
| 6 | 70 |
| 7 class SsaFunctionCompiler implements FunctionCompiler { | 71 class SsaFunctionCompiler implements FunctionCompiler { |
| 8 final SsaCodeGeneratorTask generator; | 72 final SsaCodeGeneratorTask generator; |
| 9 final SsaBuilderTask builder; | 73 final SsaBuilderTask builder; |
| 10 final SsaOptimizerTask optimizer; | 74 final SsaOptimizerTask optimizer; |
| 11 final JavaScriptBackend backend; | 75 final JavaScriptBackend backend; |
| 12 | 76 |
| 13 SsaFunctionCompiler(JavaScriptBackend backend, | 77 SsaFunctionCompiler(JavaScriptBackend backend, |
| 14 SourceInformationStrategy sourceInformationFactory) | 78 SourceInformationStrategy sourceInformationFactory) |
| 15 : generator = new SsaCodeGeneratorTask(backend, sourceInformationFactory), | 79 : generator = new SsaCodeGeneratorTask(backend, sourceInformationFactory), |
| (...skipping 2946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2962 HBasicBlock conditionExitBlock = addNewBlock(); | 3026 HBasicBlock conditionExitBlock = addNewBlock(); |
| 2963 open(conditionExitBlock); | 3027 open(conditionExitBlock); |
| 2964 close(new HGoto()); | 3028 close(new HGoto()); |
| 2965 conditionEndBlock.addSuccessor(conditionExitBlock); | 3029 conditionEndBlock.addSuccessor(conditionExitBlock); |
| 2966 | 3030 |
| 2967 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); | 3031 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| 2968 | 3032 |
| 2969 conditionBlock.postProcessLoopHeader(); | 3033 conditionBlock.postProcessLoopHeader(); |
| 2970 HLoopBlockInformation info = | 3034 HLoopBlockInformation info = |
| 2971 new HLoopBlockInformation( | 3035 new HLoopBlockInformation( |
| 2972 HLoopBlockInformation.loopType(loop), | 3036 _loopKind(loop), |
| 2973 wrapExpressionGraph(initializerGraph), | 3037 wrapExpressionGraph(initializerGraph), |
| 2974 wrapExpressionGraph(conditionExpression), | 3038 wrapExpressionGraph(conditionExpression), |
| 2975 wrapStatementGraph(bodyGraph), | 3039 wrapStatementGraph(bodyGraph), |
| 2976 wrapExpressionGraph(updateGraph), | 3040 wrapExpressionGraph(updateGraph), |
| 2977 conditionBlock.loopInformation.target, | 3041 conditionBlock.loopInformation.target, |
| 2978 conditionBlock.loopInformation.labels, | 3042 conditionBlock.loopInformation.labels, |
| 2979 sourceInformationBuilder.buildLoop(loop)); | 3043 sourceInformationBuilder.buildLoop(loop)); |
| 2980 | 3044 |
| 2981 startBlock.setBlockFlow(info, current); | 3045 startBlock.setBlockFlow(info, current); |
| 2982 loopInfo.loopBlockInformation = info; | 3046 loopInfo.loopBlockInformation = info; |
| (...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4180 ..sourceInformation = sourceInformation); | 4244 ..sourceInformation = sourceInformation); |
| 4181 } | 4245 } |
| 4182 } | 4246 } |
| 4183 | 4247 |
| 4184 void handleJsStringConcat(ast.Send node) { | 4248 void handleJsStringConcat(ast.Send node) { |
| 4185 List<HInstruction> inputs = <HInstruction>[]; | 4249 List<HInstruction> inputs = <HInstruction>[]; |
| 4186 addGenericSendArgumentsToList(node.arguments, inputs); | 4250 addGenericSendArgumentsToList(node.arguments, inputs); |
| 4187 if (inputs.length != 2) { | 4251 if (inputs.length != 2) { |
| 4188 reporter.internalError(node.argumentsNode, 'Two arguments expected.'); | 4252 reporter.internalError(node.argumentsNode, 'Two arguments expected.'); |
| 4189 } | 4253 } |
| 4190 push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType)); | 4254 push(new HStringConcat(inputs[0], inputs[1], backend.stringType)); |
| 4191 } | 4255 } |
| 4192 | 4256 |
| 4193 void handleForeignJsCurrentIsolateContext(ast.Send node) { | 4257 void handleForeignJsCurrentIsolateContext(ast.Send node) { |
| 4194 if (!node.arguments.isEmpty) { | 4258 if (!node.arguments.isEmpty) { |
| 4195 reporter.internalError(node, | 4259 reporter.internalError(node, |
| 4196 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.'); | 4260 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.'); |
| 4197 } | 4261 } |
| 4198 | 4262 |
| 4199 if (!compiler.hasIsolateSupport) { | 4263 if (!compiler.hasIsolateSupport) { |
| 4200 // If the isolate library is not used, we just generate code | 4264 // If the isolate library is not used, we just generate code |
| (...skipping 4503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8704 void visitNodeList(ast.NodeList node) { | 8768 void visitNodeList(ast.NodeList node) { |
| 8705 node.visitChildren(this); | 8769 node.visitChildren(this); |
| 8706 } | 8770 } |
| 8707 | 8771 |
| 8708 void append(HInstruction expression) { | 8772 void append(HInstruction expression) { |
| 8709 result = (result == null) ? expression : concat(result, expression); | 8773 result = (result == null) ? expression : concat(result, expression); |
| 8710 } | 8774 } |
| 8711 | 8775 |
| 8712 HInstruction concat(HInstruction left, HInstruction right) { | 8776 HInstruction concat(HInstruction left, HInstruction right) { |
| 8713 HInstruction instruction = new HStringConcat( | 8777 HInstruction instruction = new HStringConcat( |
| 8714 left, right, diagnosticNode, builder.backend.stringType); | 8778 left, right, builder.backend.stringType); |
| 8715 builder.add(instruction); | 8779 builder.add(instruction); |
| 8716 return instruction; | 8780 return instruction; |
| 8717 } | 8781 } |
| 8718 | 8782 |
| 8719 HInstruction stringify(ast.Node node, HInstruction expression) { | 8783 HInstruction stringify(ast.Node node, HInstruction expression) { |
| 8720 HInstruction instruction = | 8784 HInstruction instruction = |
| 8721 new HStringify(expression, node, builder.backend.stringType); | 8785 new HStringify(expression, builder.backend.stringType); |
| 8722 builder.add(instruction); | 8786 builder.add(instruction); |
| 8723 return instruction; | 8787 return instruction; |
| 8724 } | 8788 } |
| 8725 } | 8789 } |
| 8726 | 8790 |
| 8727 /** | 8791 /** |
| 8728 * This class visits the method that is a candidate for inlining and | 8792 * This class visits the method that is a candidate for inlining and |
| 8729 * finds whether it is too difficult to inline. | 8793 * finds whether it is too difficult to inline. |
| 8730 */ | 8794 */ |
| 8731 // TODO(karlklose): refactor to make it possible to distinguish between | 8795 // TODO(karlklose): refactor to make it possible to distinguish between |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9239 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 9303 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 9240 unaliased.accept(this, builder); | 9304 unaliased.accept(this, builder); |
| 9241 } | 9305 } |
| 9242 | 9306 |
| 9243 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 9307 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 9244 JavaScriptBackend backend = builder.compiler.backend; | 9308 JavaScriptBackend backend = builder.compiler.backend; |
| 9245 ClassElement cls = backend.helpers.DynamicRuntimeType; | 9309 ClassElement cls = backend.helpers.DynamicRuntimeType; |
| 9246 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 9310 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 9247 } | 9311 } |
| 9248 } | 9312 } |
| 9313 |
| 9314 /// Determine what kind of loop [node] represents. The result is one of the |
| 9315 /// kinds defined in [HLoopBlockInformation]. |
| 9316 int _loopKind(ast.Node node) => node.accept(const _LoopTypeVisitor()); |
| 9317 |
| 9318 class _LoopTypeVisitor extends ast.Visitor { |
| 9319 const _LoopTypeVisitor(); |
| 9320 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
| 9321 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
| 9322 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
| 9323 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 9324 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 9325 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 9326 int visitSwitchStatement(ast.SwitchStatement node) => |
| 9327 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
| 9328 } |
| OLD | NEW |