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'; |
11 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; | 11 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; |
12 | 12 |
13 | 13 |
14 CodeBuffer buildJavaScriptFunction(FunctionElement element, | 14 CodeBuffer buildJavaScriptFunction(FunctionElement element, |
15 String parameters, | 15 String parameters, |
16 String body) { | 16 CodeBuffer body) { |
17 String extraSpace = ""; | 17 String extraSpace = ""; |
18 // Members are emitted inside a JavaScript object literal. To line up the | 18 // Members are emitted inside a JavaScript object literal. To line up the |
19 // indentation we want the closing curly brace to be indented by one space. | 19 // indentation we want the closing curly brace to be indented by one space. |
20 // Example: | 20 // Example: |
21 // defineClass("A", "B", ... , { | 21 // defineClass("A", "B", ... , { |
22 // foo$1: function(..) { | 22 // foo$1: function(..) { |
23 // }, /* <========== indent by 1. */ | 23 // }, /* <========== indent by 1. */ |
24 // bar$2: function(..) { | 24 // bar$2: function(..) { |
25 // }, /* <========== indent by 1. */ | 25 // }, /* <========== indent by 1. */ |
26 // | 26 // |
(...skipping 23 matching lines...) Expand all Loading... |
50 Map<Element, String> parameterNames = getParameterNames(work); | 50 Map<Element, String> parameterNames = getParameterNames(work); |
51 parameterNames.forEach((element, name) { | 51 parameterNames.forEach((element, name) { |
52 compiler.enqueuer.codegen.addToWorkList(element); | 52 compiler.enqueuer.codegen.addToWorkList(element); |
53 }); | 53 }); |
54 String parameters = Strings.join(parameterNames.getValues(), ', '); | 54 String parameters = Strings.join(parameterNames.getValues(), ', '); |
55 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( | 55 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( |
56 backend, work, parameters, parameterNames); | 56 backend, work, parameters, parameterNames); |
57 codegen.visitGraph(graph); | 57 codegen.visitGraph(graph); |
58 | 58 |
59 FunctionElement element = work.element; | 59 FunctionElement element = work.element; |
60 String code; | 60 CodeBuffer code; |
61 if (element.isInstanceMember() | 61 if (element.isInstanceMember() |
62 && element.enclosingElement.isClass() | 62 && element.enclosingElement.isClass() |
63 && element.enclosingElement.isNative() | 63 && element.enclosingElement.isNative() |
64 && native.isOverriddenMethod( | 64 && native.isOverriddenMethod( |
65 element, element.enclosingElement, nativeEmitter)) { | 65 element, element.enclosingElement, nativeEmitter)) { |
66 // Record that this method is overridden. In case of optional | 66 // Record that this method is overridden. In case of optional |
67 // arguments, the emitter will generate stubs to handle them, | 67 // arguments, the emitter will generate stubs to handle them, |
68 // and needs to know if the method is overridden. | 68 // and needs to know if the method is overridden. |
69 nativeEmitter.overriddenMethods.add(element); | 69 nativeEmitter.overriddenMethods.add(element); |
70 StringBuffer buffer = new StringBuffer(); | 70 StringBuffer buffer = new StringBuffer(); |
71 native.generateMethodWithPrototypeCheckForElement( | 71 native.generateMethodWithPrototypeCheckForElement( |
72 compiler, buffer, element, '${codegen.buffer}', parameters); | 72 compiler, buffer, element, '${codegen.buffer}', parameters); |
73 code = buffer.toString(); | 73 code = new CodeBuffer(); |
| 74 code.add(buffer); |
74 } else { | 75 } else { |
75 code = codegen.buffer.toString(); | 76 code = codegen.buffer; |
76 } | 77 } |
77 return buildJavaScriptFunction(element, parameters, code); | 78 return buildJavaScriptFunction(element, parameters, code); |
78 }); | 79 }); |
79 } | 80 } |
80 | 81 |
81 CodeBuffer generateBailoutMethod(WorkItem work, HGraph graph) { | 82 CodeBuffer generateBailoutMethod(WorkItem work, HGraph graph) { |
82 return measure(() { | 83 return measure(() { |
83 compiler.tracer.traceGraph("codegen-bailout", graph); | 84 compiler.tracer.traceGraph("codegen-bailout", graph); |
84 | 85 |
85 Map<Element, String> parameterNames = getParameterNames(work); | 86 Map<Element, String> parameterNames = getParameterNames(work); |
86 String parameters = Strings.join(parameterNames.getValues(), ', '); | 87 String parameters = Strings.join(parameterNames.getValues(), ', '); |
87 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( | 88 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( |
88 backend, work, parameters, parameterNames); | 89 backend, work, parameters, parameterNames); |
89 codegen.visitGraph(graph); | 90 codegen.visitGraph(graph); |
90 | 91 |
91 String body = '${codegen.setup}${codegen.buffer}'; | 92 CodeBuffer code = new CodeBuffer(); |
| 93 code.add(codegen.setup); |
| 94 code.add(codegen.buffer); |
92 return buildJavaScriptFunction( | 95 return buildJavaScriptFunction( |
93 work.element, codegen.newParameters.toString(), body); | 96 work.element, codegen.newParameters.toString(), code); |
94 }); | 97 }); |
95 } | 98 } |
96 | 99 |
97 Map<Element, String> getParameterNames(WorkItem work) { | 100 Map<Element, String> getParameterNames(WorkItem work) { |
98 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>(); | 101 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>(); |
99 FunctionElement function = work.element; | 102 FunctionElement function = work.element; |
100 | 103 |
101 // The dom/html libraries have inline JS code that reference | 104 // The dom/html libraries have inline JS code that reference |
102 // parameter names directly. Long-term such code will be rejected. | 105 // parameter names directly. Long-term such code will be rejected. |
103 // Now, just don't mangle the parameter name. | 106 // Now, just don't mangle the parameter name. |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 HCheck check = argument; | 651 HCheck check = argument; |
649 use(check.checkedInput, expectedPrecedenceForArgument); | 652 use(check.checkedInput, expectedPrecedenceForArgument); |
650 } else { | 653 } else { |
651 buffer.add(variableNames.getName(argument)); | 654 buffer.add(variableNames.getName(argument)); |
652 } | 655 } |
653 } | 656 } |
654 | 657 |
655 visit(HInstruction node, int expectedPrecedenceForNode) { | 658 visit(HInstruction node, int expectedPrecedenceForNode) { |
656 int oldPrecedence = this.expectedPrecedence; | 659 int oldPrecedence = this.expectedPrecedence; |
657 this.expectedPrecedence = expectedPrecedenceForNode; | 660 this.expectedPrecedence = expectedPrecedenceForNode; |
| 661 if (node.sourcePosition !== null) { |
| 662 buffer.setSourceLocation(work.element, node.sourcePosition); |
| 663 } |
658 node.accept(this); | 664 node.accept(this); |
659 this.expectedPrecedence = oldPrecedence; | 665 this.expectedPrecedence = oldPrecedence; |
660 } | 666 } |
661 | 667 |
662 void continueAsBreak(LabelElement target) { | 668 void continueAsBreak(LabelElement target) { |
663 addIndented("break "); | 669 addIndented("break "); |
664 writeContinueLabel(target); | 670 writeContinueLabel(target); |
665 buffer.add(";\n"); | 671 buffer.add(";\n"); |
666 } | 672 } |
667 | 673 |
(...skipping 2468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3136 if (leftType.canBeNull() && rightType.canBeNull()) { | 3142 if (leftType.canBeNull() && rightType.canBeNull()) { |
3137 if (left.isConstantNull() || right.isConstantNull() || | 3143 if (left.isConstantNull() || right.isConstantNull() || |
3138 (leftType.isPrimitive() && leftType == rightType)) { | 3144 (leftType.isPrimitive() && leftType == rightType)) { |
3139 return '=='; | 3145 return '=='; |
3140 } | 3146 } |
3141 return null; | 3147 return null; |
3142 } else { | 3148 } else { |
3143 return '==='; | 3149 return '==='; |
3144 } | 3150 } |
3145 } | 3151 } |
OLD | NEW |