Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: lib/compiler/implementation/ssa/codegen.dart

Issue 10915122: Fix source locations for inlined and patched functions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 6
7 final JavaScriptBackend backend; 7 final JavaScriptBackend backend;
8 8
9 SsaCodeGeneratorTask(JavaScriptBackend backend) 9 SsaCodeGeneratorTask(JavaScriptBackend backend)
10 : this.backend = backend, 10 : this.backend = backend,
11 super(backend.compiler); 11 super(backend.compiler);
12 String get name => 'SSA code generator'; 12 String get name => 'SSA code generator';
13 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter; 13 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter;
14 14
15 15
16 js.Fun buildJavaScriptFunction(FunctionElement element, 16 js.Fun buildJavaScriptFunction(FunctionElement element,
17 List<js.Parameter> parameters, 17 List<js.Parameter> parameters,
18 js.Block body) { 18 js.Block body) {
19 FunctionExpression expression = element.cachedNode; 19 FunctionExpression expression = element.cachedNode;
20 js.Fun result = new js.Fun(parameters, body); 20 js.Fun result = new js.Fun(parameters, body);
21 result.sourcePosition = expression.getBeginToken(); 21 Element sourceElement = element.patch == null ? element : element.patch;
ahe 2012/09/08 08:55:50 Another TODO for Johnni.
podivilov 2012/09/10 11:13:23 Done.
22 result.endSourcePosition = expression.getEndToken(); 22 SourceFile sourceFile = sourceElement.getCompilationUnit().script.file;
23 result.sourcePosition = new SourceFileLocation(
24 sourceFile, expression.getBeginToken());
25 result.endSourcePosition = new SourceFileLocation(
26 sourceFile, expression.getEndToken());
23 return result; 27 return result;
24 } 28 }
25 29
26 CodeBuffer prettyPrint(js.Node node, Element positionElement) { 30 CodeBuffer prettyPrint(js.Node node) {
27 return js.prettyPrint(node, compiler, positionElement); 31 return js.prettyPrint(node, compiler);
28 } 32 }
29 33
30 CodeBuffer generateCode(WorkItem work, HGraph graph) { 34 CodeBuffer generateCode(WorkItem work, HGraph graph) {
31 if (work.element.isField()) { 35 if (work.element.isField()) {
32 return generateLazyInitializer(work, graph); 36 return generateLazyInitializer(work, graph);
33 } else { 37 } else {
34 return generateMethod(work, graph); 38 return generateMethod(work, graph);
35 } 39 }
36 } 40 }
37 41
38 CodeBuffer generateLazyInitializer(work, graph) { 42 CodeBuffer generateLazyInitializer(work, graph) {
39 return measure(() { 43 return measure(() {
40 compiler.tracer.traceGraph("codegen", graph); 44 compiler.tracer.traceGraph("codegen", graph);
41 List<js.Parameter> parameters = <js.Parameter>[]; 45 List<js.Parameter> parameters = <js.Parameter>[];
42 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( 46 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator(
43 backend, work, parameters, new Map<Element, String>()); 47 backend, work, parameters, new Map<Element, String>());
44 codegen.visitGraph(graph); 48 codegen.visitGraph(graph);
45 js.Block body = codegen.body; 49 js.Block body = codegen.body;
46 Element element = work.element;
47 js.Fun fun = new js.Fun(parameters, body); 50 js.Fun fun = new js.Fun(parameters, body);
48 return prettyPrint(fun, element); 51 return prettyPrint(fun);
49 }); 52 });
50 } 53 }
51 54
52 CodeBuffer generateMethod(WorkItem work, HGraph graph) { 55 CodeBuffer generateMethod(WorkItem work, HGraph graph) {
53 return measure(() { 56 return measure(() {
54 JavaScriptItemCompilationContext context = work.compilationContext; 57 JavaScriptItemCompilationContext context = work.compilationContext;
55 HTypeMap types = context.types; 58 HTypeMap types = context.types;
56 graph.exit.predecessors.forEach((block) { 59 graph.exit.predecessors.forEach((block) {
57 assert(block.last is HGoto || block.last is HReturn); 60 assert(block.last is HGoto || block.last is HReturn);
58 if (block.last is HReturn) { 61 if (block.last is HReturn) {
(...skipping 22 matching lines...) Expand all
81 ClassElement enclosingClass = element.getEnclosingClass(); 84 ClassElement enclosingClass = element.getEnclosingClass();
82 if (element.isInstanceMember() 85 if (element.isInstanceMember()
83 && enclosingClass.isNative() 86 && enclosingClass.isNative()
84 && native.isOverriddenMethod( 87 && native.isOverriddenMethod(
85 element, enclosingClass, nativeEmitter)) { 88 element, enclosingClass, nativeEmitter)) {
86 // Record that this method is overridden. In case of optional 89 // Record that this method is overridden. In case of optional
87 // arguments, the emitter will generate stubs to handle them, 90 // arguments, the emitter will generate stubs to handle them,
88 // and needs to know if the method is overridden. 91 // and needs to know if the method is overridden.
89 nativeEmitter.overriddenMethods.add(element); 92 nativeEmitter.overriddenMethods.add(element);
90 StringBuffer buffer = new StringBuffer(); 93 StringBuffer buffer = new StringBuffer();
91 String codeString = prettyPrint(codegen.body, work.element).toString(); 94 String codeString = prettyPrint(codegen.body).toString();
92 native.generateMethodWithPrototypeCheckForElement( 95 native.generateMethodWithPrototypeCheckForElement(
93 compiler, buffer, element, codeString, parametersString); 96 compiler, buffer, element, codeString, parametersString);
94 js.Node nativeCode = new js.LiteralStatement(buffer.toString()); 97 js.Node nativeCode = new js.LiteralStatement(buffer.toString());
95 body = new js.Block(<js.Statement>[nativeCode]); 98 body = new js.Block(<js.Statement>[nativeCode]);
96 } else { 99 } else {
97 body = codegen.body; 100 body = codegen.body;
98 } 101 }
99 js.Fun fun = buildJavaScriptFunction(element, parameters, body); 102 js.Fun fun = buildJavaScriptFunction(element, parameters, body);
100 return prettyPrint(fun, work.element); 103 return prettyPrint(fun);
101 }); 104 });
102 } 105 }
103 106
104 void addTypeParameters(Element element, 107 void addTypeParameters(Element element,
105 List<js.Parameter> parameters, 108 List<js.Parameter> parameters,
106 Map<Element, String> parameterNames) { 109 Map<Element, String> parameterNames) {
107 if (element.isFactoryConstructor() || element.isGenerativeConstructor()) { 110 if (element.isFactoryConstructor() || element.isGenerativeConstructor()) {
108 ClassElement cls = element.enclosingElement; 111 ClassElement cls = element.enclosingElement;
109 cls.typeVariables.forEach((TypeVariableType typeVariable) { 112 cls.typeVariables.forEach((TypeVariableType typeVariable) {
110 String name = typeVariable.element.name.slowToString(); 113 String name = typeVariable.element.name.slowToString();
(...skipping 22 matching lines...) Expand all
133 136
134 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( 137 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator(
135 backend, work, parameters, parameterNames); 138 backend, work, parameters, parameterNames);
136 codegen.visitGraph(graph); 139 codegen.visitGraph(graph);
137 140
138 js.Block body = new js.Block(<js.Statement>[]); 141 js.Block body = new js.Block(<js.Statement>[]);
139 if (codegen.setup != null) body.statements.add(codegen.setup); 142 if (codegen.setup != null) body.statements.add(codegen.setup);
140 body.statements.add(codegen.body); 143 body.statements.add(codegen.body);
141 js.Fun fun = 144 js.Fun fun =
142 buildJavaScriptFunction(work.element, codegen.newParameters, body); 145 buildJavaScriptFunction(work.element, codegen.newParameters, body);
143 return prettyPrint(fun, work.element); 146 return prettyPrint(fun);
144 }); 147 });
145 } 148 }
146 149
147 Map<Element, String> getParameterNames(WorkItem work) { 150 Map<Element, String> getParameterNames(WorkItem work) {
148 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>(); 151 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>();
149 FunctionElement function = work.element; 152 FunctionElement function = work.element;
150 153
151 // The dom/html libraries have inline JS code that reference 154 // The dom/html libraries have inline JS code that reference
152 // parameter names directly. Long-term such code will be rejected. 155 // parameter names directly. Long-term such code will be rejected.
153 // Now, just don't mangle the parameter name. 156 // Now, just don't mangle the parameter name.
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 334
332 js.Expression pop() { 335 js.Expression pop() {
333 return expressionStack.removeLast(); 336 return expressionStack.removeLast();
334 } 337 }
335 338
336 attachLocationToLast(HInstruction instruction) { 339 attachLocationToLast(HInstruction instruction) {
337 attachLocation(expressionStack.last(), instruction); 340 attachLocation(expressionStack.last(), instruction);
338 } 341 }
339 342
340 js.Node attachLocation(js.Node jsNode, HInstruction instruction) { 343 js.Node attachLocation(js.Node jsNode, HInstruction instruction) {
341 if (instruction.sourcePosition !== null) { 344 jsNode.sourcePosition = instruction.sourcePosition;
342 jsNode.sourcePosition = instruction.sourcePosition;
343 }
344 return jsNode; 345 return jsNode;
345 } 346 }
346 347
347 js.Node attachLocationRange(js.Node jsNode, Node node) { 348 js.Node attachLocationRange(js.Node jsNode,
348 jsNode.sourcePosition = node.getBeginToken(); 349 SourceFileLocation sourcePosition,
349 jsNode.endSourcePosition = node.getEndToken(); 350 SourceFileLocation endSourcePosition) {
351 jsNode.sourcePosition = sourcePosition;
352 jsNode.endSourcePosition = endSourcePosition;
350 return jsNode; 353 return jsNode;
351 } 354 }
352 355
353 abstract visitTypeGuard(HTypeGuard node); 356 abstract visitTypeGuard(HTypeGuard node);
354 abstract visitBailoutTarget(HBailoutTarget node); 357 abstract visitBailoutTarget(HBailoutTarget node);
355 358
356 abstract beginGraph(HGraph graph); 359 abstract beginGraph(HGraph graph);
357 abstract endGraph(HGraph graph); 360 abstract endGraph(HGraph graph);
358 361
359 abstract beginLoop(HBasicBlock block); 362 abstract beginLoop(HBasicBlock block);
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 currentContainer = oldContainer; 926 currentContainer = oldContainer;
924 body = unwrapStatement(body); 927 body = unwrapStatement(body);
925 loop = new js.Do(body, jsCondition); 928 loop = new js.Do(body, jsCondition);
926 break; 929 break;
927 } 930 }
928 default: 931 default:
929 compiler.internalError( 932 compiler.internalError(
930 'Unexpected loop kind: ${info.kind}', 933 'Unexpected loop kind: ${info.kind}',
931 instruction: condition.conditionExpression); 934 instruction: condition.conditionExpression);
932 } 935 }
933 attachLocationRange(loop, info.sourcePosition); 936 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition);
934 pushStatement(wrapIntoLabels(loop, info.labels)); 937 pushStatement(wrapIntoLabels(loop, info.labels));
935 return true; 938 return true;
936 } 939 }
937 940
938 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { 941 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) {
939 preLabeledBlock(labeledBlockInfo); 942 preLabeledBlock(labeledBlockInfo);
940 Link<Element> continueOverrides = const EmptyLink<Element>(); 943 Link<Element> continueOverrides = const EmptyLink<Element>();
941 944
942 js.Block oldContainer = currentContainer; 945 js.Block oldContainer = currentContainer;
943 js.Block body = new js.Block.empty(); 946 js.Block body = new js.Block.empty();
(...skipping 1634 matching lines...) Expand 10 before | Expand all | Expand 10 after
2578 currentContainer = new js.Block.empty(); 2581 currentContainer = new js.Block.empty();
2579 } 2582 }
2580 2583
2581 void endLoop(HBasicBlock block) { 2584 void endLoop(HBasicBlock block) {
2582 js.Statement body = currentContainer; 2585 js.Statement body = currentContainer;
2583 currentContainer = oldContainerStack.removeLast(); 2586 currentContainer = oldContainerStack.removeLast();
2584 body = unwrapStatement(body); 2587 body = unwrapStatement(body);
2585 js.While loop = new js.While(new js.LiteralBool(true), body); 2588 js.While loop = new js.While(new js.LiteralBool(true), body);
2586 2589
2587 HLoopInformation info = block.loopInformation; 2590 HLoopInformation info = block.loopInformation;
2588 attachLocationRange(loop, info.loopBlockInformation.sourcePosition); 2591 attachLocationRange(loop,
2592 info.loopBlockInformation.sourcePosition,
2593 info.loopBlockInformation.endSourcePosition);
2589 pushStatement(wrapIntoLabels(loop, info.labels)); 2594 pushStatement(wrapIntoLabels(loop, info.labels));
2590 } 2595 }
2591 2596
2592 void handleLoopCondition(HLoopBranch node) { 2597 void handleLoopCondition(HLoopBranch node) {
2593 use(node.inputs[0]); 2598 use(node.inputs[0]);
2594 pushStatement(new js.If.noElse(pop(), new js.Break(null)), node); 2599 pushStatement(new js.If.noElse(pop(), new js.Break(null)), node);
2595 } 2600 }
2596 2601
2597 2602
2598 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2603 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
2832 HLoopInformation info = header.loopInformation; 2837 HLoopInformation info = header.loopInformation;
2833 if (header.hasBailoutTargets()) { 2838 if (header.hasBailoutTargets()) {
2834 endBailoutSwitch(); 2839 endBailoutSwitch();
2835 if (info.target != null) breakAction.remove(info.target); 2840 if (info.target != null) breakAction.remove(info.target);
2836 } 2841 }
2837 2842
2838 js.Statement body = unwrapStatement(currentContainer); 2843 js.Statement body = unwrapStatement(currentContainer);
2839 currentContainer = oldContainerStack.removeLast(); 2844 currentContainer = oldContainerStack.removeLast();
2840 2845
2841 js.Statement result = new js.While(new js.LiteralBool(true), body); 2846 js.Statement result = new js.While(new js.LiteralBool(true), body);
2842 attachLocationRange(result, info.loopBlockInformation.sourcePosition); 2847 attachLocationRange(result,
2848 info.loopBlockInformation.sourcePosition,
2849 info.loopBlockInformation.endSourcePosition);
2843 result = new js.LabeledStatement(loopLabel, result); 2850 result = new js.LabeledStatement(loopLabel, result);
2844 result = wrapIntoLabels(result, info.labels); 2851 result = wrapIntoLabels(result, info.labels);
2845 pushStatement(result); 2852 pushStatement(result);
2846 } 2853 }
2847 2854
2848 void handleLoopCondition(HLoopBranch node) { 2855 void handleLoopCondition(HLoopBranch node) {
2849 use(node.inputs[0]); 2856 use(node.inputs[0]);
2850 js.Expression test = new js.Prefix('!', pop()); 2857 js.Expression test = new js.Prefix('!', pop());
2851 js.Statement then = new js.Break(currentLabel()); 2858 js.Statement then = new js.Break(currentLabel());
2852 pushStatement(new js.If.noElse(test, then), node); 2859 pushStatement(new js.If.noElse(test, then), node);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2934 if (leftType.canBeNull() && rightType.canBeNull()) { 2941 if (leftType.canBeNull() && rightType.canBeNull()) {
2935 if (left.isConstantNull() || right.isConstantNull() || 2942 if (left.isConstantNull() || right.isConstantNull() ||
2936 (leftType.isPrimitive() && leftType == rightType)) { 2943 (leftType.isPrimitive() && leftType == rightType)) {
2937 return '=='; 2944 return '==';
2938 } 2945 }
2939 return null; 2946 return null;
2940 } else { 2947 } else {
2941 return '==='; 2948 return '===';
2942 } 2949 }
2943 } 2950 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698