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

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: Address comments. 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 // TODO(johnniwinther): remove the 'element.patch' hack.
22 result.endSourcePosition = expression.getEndToken(); 22 Element sourceElement = element.patch == null ? element : element.patch;
23 SourceFile sourceFile = sourceElement.getCompilationUnit().script.file;
24 result.sourcePosition = new SourceFileLocation(
25 sourceFile, expression.getBeginToken());
26 result.endSourcePosition = new SourceFileLocation(
27 sourceFile, expression.getEndToken());
23 return result; 28 return result;
24 } 29 }
25 30
26 CodeBuffer prettyPrint(js.Node node, Element positionElement) { 31 CodeBuffer prettyPrint(js.Node node) {
27 return js.prettyPrint(node, compiler, positionElement); 32 return js.prettyPrint(node, compiler);
28 } 33 }
29 34
30 CodeBuffer generateCode(WorkItem work, HGraph graph) { 35 CodeBuffer generateCode(WorkItem work, HGraph graph) {
31 if (work.element.isField()) { 36 if (work.element.isField()) {
32 return generateLazyInitializer(work, graph); 37 return generateLazyInitializer(work, graph);
33 } else { 38 } else {
34 return generateMethod(work, graph); 39 return generateMethod(work, graph);
35 } 40 }
36 } 41 }
37 42
38 CodeBuffer generateLazyInitializer(work, graph) { 43 CodeBuffer generateLazyInitializer(work, graph) {
39 return measure(() { 44 return measure(() {
40 compiler.tracer.traceGraph("codegen", graph); 45 compiler.tracer.traceGraph("codegen", graph);
41 List<js.Parameter> parameters = <js.Parameter>[]; 46 List<js.Parameter> parameters = <js.Parameter>[];
42 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( 47 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator(
43 backend, work, parameters, new Map<Element, String>()); 48 backend, work, parameters, new Map<Element, String>());
44 codegen.visitGraph(graph); 49 codegen.visitGraph(graph);
45 js.Block body = codegen.body; 50 js.Block body = codegen.body;
46 Element element = work.element;
47 js.Fun fun = new js.Fun(parameters, body); 51 js.Fun fun = new js.Fun(parameters, body);
48 return prettyPrint(fun, element); 52 return prettyPrint(fun);
49 }); 53 });
50 } 54 }
51 55
52 CodeBuffer generateMethod(WorkItem work, HGraph graph) { 56 CodeBuffer generateMethod(WorkItem work, HGraph graph) {
53 return measure(() { 57 return measure(() {
54 JavaScriptItemCompilationContext context = work.compilationContext; 58 JavaScriptItemCompilationContext context = work.compilationContext;
55 HTypeMap types = context.types; 59 HTypeMap types = context.types;
56 graph.exit.predecessors.forEach((block) { 60 graph.exit.predecessors.forEach((block) {
57 assert(block.last is HGoto || block.last is HReturn); 61 assert(block.last is HGoto || block.last is HReturn);
58 if (block.last is HReturn) { 62 if (block.last is HReturn) {
(...skipping 22 matching lines...) Expand all
81 ClassElement enclosingClass = element.getEnclosingClass(); 85 ClassElement enclosingClass = element.getEnclosingClass();
82 if (element.isInstanceMember() 86 if (element.isInstanceMember()
83 && enclosingClass.isNative() 87 && enclosingClass.isNative()
84 && native.isOverriddenMethod( 88 && native.isOverriddenMethod(
85 element, enclosingClass, nativeEmitter)) { 89 element, enclosingClass, nativeEmitter)) {
86 // Record that this method is overridden. In case of optional 90 // Record that this method is overridden. In case of optional
87 // arguments, the emitter will generate stubs to handle them, 91 // arguments, the emitter will generate stubs to handle them,
88 // and needs to know if the method is overridden. 92 // and needs to know if the method is overridden.
89 nativeEmitter.overriddenMethods.add(element); 93 nativeEmitter.overriddenMethods.add(element);
90 StringBuffer buffer = new StringBuffer(); 94 StringBuffer buffer = new StringBuffer();
91 String codeString = prettyPrint(codegen.body, work.element).toString(); 95 String codeString = prettyPrint(codegen.body).toString();
92 native.generateMethodWithPrototypeCheckForElement( 96 native.generateMethodWithPrototypeCheckForElement(
93 compiler, buffer, element, codeString, parametersString); 97 compiler, buffer, element, codeString, parametersString);
94 js.Node nativeCode = new js.LiteralStatement(buffer.toString()); 98 js.Node nativeCode = new js.LiteralStatement(buffer.toString());
95 body = new js.Block(<js.Statement>[nativeCode]); 99 body = new js.Block(<js.Statement>[nativeCode]);
96 } else { 100 } else {
97 body = codegen.body; 101 body = codegen.body;
98 } 102 }
99 js.Fun fun = buildJavaScriptFunction(element, parameters, body); 103 js.Fun fun = buildJavaScriptFunction(element, parameters, body);
100 return prettyPrint(fun, work.element); 104 return prettyPrint(fun);
101 }); 105 });
102 } 106 }
103 107
104 void addTypeParameters(Element element, 108 void addTypeParameters(Element element,
105 List<js.Parameter> parameters, 109 List<js.Parameter> parameters,
106 Map<Element, String> parameterNames) { 110 Map<Element, String> parameterNames) {
107 if (element.isFactoryConstructor() || element.isGenerativeConstructor()) { 111 if (element.isFactoryConstructor() || element.isGenerativeConstructor()) {
108 ClassElement cls = element.enclosingElement; 112 ClassElement cls = element.enclosingElement;
109 cls.typeVariables.forEach((TypeVariableType typeVariable) { 113 cls.typeVariables.forEach((TypeVariableType typeVariable) {
110 String name = typeVariable.element.name.slowToString(); 114 String name = typeVariable.element.name.slowToString();
(...skipping 22 matching lines...) Expand all
133 137
134 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( 138 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator(
135 backend, work, parameters, parameterNames); 139 backend, work, parameters, parameterNames);
136 codegen.visitGraph(graph); 140 codegen.visitGraph(graph);
137 141
138 js.Block body = new js.Block(<js.Statement>[]); 142 js.Block body = new js.Block(<js.Statement>[]);
139 if (codegen.setup != null) body.statements.add(codegen.setup); 143 if (codegen.setup != null) body.statements.add(codegen.setup);
140 body.statements.add(codegen.body); 144 body.statements.add(codegen.body);
141 js.Fun fun = 145 js.Fun fun =
142 buildJavaScriptFunction(work.element, codegen.newParameters, body); 146 buildJavaScriptFunction(work.element, codegen.newParameters, body);
143 return prettyPrint(fun, work.element); 147 return prettyPrint(fun);
144 }); 148 });
145 } 149 }
146 150
147 Map<Element, String> getParameterNames(WorkItem work) { 151 Map<Element, String> getParameterNames(WorkItem work) {
148 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>(); 152 Map<Element, String> parameterNames = new LinkedHashMap<Element, String>();
149 FunctionElement function = work.element; 153 FunctionElement function = work.element;
150 154
151 // The dom/html libraries have inline JS code that reference 155 // The dom/html libraries have inline JS code that reference
152 // parameter names directly. Long-term such code will be rejected. 156 // parameter names directly. Long-term such code will be rejected.
153 // Now, just don't mangle the parameter name. 157 // Now, just don't mangle the parameter name.
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 335
332 js.Expression pop() { 336 js.Expression pop() {
333 return expressionStack.removeLast(); 337 return expressionStack.removeLast();
334 } 338 }
335 339
336 attachLocationToLast(HInstruction instruction) { 340 attachLocationToLast(HInstruction instruction) {
337 attachLocation(expressionStack.last(), instruction); 341 attachLocation(expressionStack.last(), instruction);
338 } 342 }
339 343
340 js.Node attachLocation(js.Node jsNode, HInstruction instruction) { 344 js.Node attachLocation(js.Node jsNode, HInstruction instruction) {
341 if (instruction.sourcePosition !== null) { 345 jsNode.sourcePosition = instruction.sourcePosition;
342 jsNode.sourcePosition = instruction.sourcePosition;
343 }
344 return jsNode; 346 return jsNode;
345 } 347 }
346 348
347 js.Node attachLocationRange(js.Node jsNode, Node node) { 349 js.Node attachLocationRange(js.Node jsNode,
348 jsNode.sourcePosition = node.getBeginToken(); 350 SourceFileLocation sourcePosition,
349 jsNode.endSourcePosition = node.getEndToken(); 351 SourceFileLocation endSourcePosition) {
352 jsNode.sourcePosition = sourcePosition;
353 jsNode.endSourcePosition = endSourcePosition;
350 return jsNode; 354 return jsNode;
351 } 355 }
352 356
353 abstract visitTypeGuard(HTypeGuard node); 357 abstract visitTypeGuard(HTypeGuard node);
354 abstract visitBailoutTarget(HBailoutTarget node); 358 abstract visitBailoutTarget(HBailoutTarget node);
355 359
356 abstract beginGraph(HGraph graph); 360 abstract beginGraph(HGraph graph);
357 abstract endGraph(HGraph graph); 361 abstract endGraph(HGraph graph);
358 362
359 abstract beginLoop(HBasicBlock block); 363 abstract beginLoop(HBasicBlock block);
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 currentContainer = oldContainer; 927 currentContainer = oldContainer;
924 body = unwrapStatement(body); 928 body = unwrapStatement(body);
925 loop = new js.Do(body, jsCondition); 929 loop = new js.Do(body, jsCondition);
926 break; 930 break;
927 } 931 }
928 default: 932 default:
929 compiler.internalError( 933 compiler.internalError(
930 'Unexpected loop kind: ${info.kind}', 934 'Unexpected loop kind: ${info.kind}',
931 instruction: condition.conditionExpression); 935 instruction: condition.conditionExpression);
932 } 936 }
933 attachLocationRange(loop, info.sourcePosition); 937 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition);
934 pushStatement(wrapIntoLabels(loop, info.labels)); 938 pushStatement(wrapIntoLabels(loop, info.labels));
935 return true; 939 return true;
936 } 940 }
937 941
938 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { 942 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) {
939 preLabeledBlock(labeledBlockInfo); 943 preLabeledBlock(labeledBlockInfo);
940 Link<Element> continueOverrides = const EmptyLink<Element>(); 944 Link<Element> continueOverrides = const EmptyLink<Element>();
941 945
942 js.Block oldContainer = currentContainer; 946 js.Block oldContainer = currentContainer;
943 js.Block body = new js.Block.empty(); 947 js.Block body = new js.Block.empty();
(...skipping 1668 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 currentContainer = new js.Block.empty(); 2616 currentContainer = new js.Block.empty();
2613 } 2617 }
2614 2618
2615 void endLoop(HBasicBlock block) { 2619 void endLoop(HBasicBlock block) {
2616 js.Statement body = currentContainer; 2620 js.Statement body = currentContainer;
2617 currentContainer = oldContainerStack.removeLast(); 2621 currentContainer = oldContainerStack.removeLast();
2618 body = unwrapStatement(body); 2622 body = unwrapStatement(body);
2619 js.While loop = new js.While(new js.LiteralBool(true), body); 2623 js.While loop = new js.While(new js.LiteralBool(true), body);
2620 2624
2621 HLoopInformation info = block.loopInformation; 2625 HLoopInformation info = block.loopInformation;
2622 attachLocationRange(loop, info.loopBlockInformation.sourcePosition); 2626 attachLocationRange(loop,
2627 info.loopBlockInformation.sourcePosition,
2628 info.loopBlockInformation.endSourcePosition);
2623 pushStatement(wrapIntoLabels(loop, info.labels)); 2629 pushStatement(wrapIntoLabels(loop, info.labels));
2624 } 2630 }
2625 2631
2626 void handleLoopCondition(HLoopBranch node) { 2632 void handleLoopCondition(HLoopBranch node) {
2627 use(node.inputs[0]); 2633 use(node.inputs[0]);
2628 pushStatement(new js.If.noElse(pop(), new js.Break(null)), node); 2634 pushStatement(new js.If.noElse(pop(), new js.Break(null)), node);
2629 } 2635 }
2630 2636
2631 2637
2632 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2638 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
2866 HLoopInformation info = header.loopInformation; 2872 HLoopInformation info = header.loopInformation;
2867 if (header.hasBailoutTargets()) { 2873 if (header.hasBailoutTargets()) {
2868 endBailoutSwitch(); 2874 endBailoutSwitch();
2869 if (info.target != null) breakAction.remove(info.target); 2875 if (info.target != null) breakAction.remove(info.target);
2870 } 2876 }
2871 2877
2872 js.Statement body = unwrapStatement(currentContainer); 2878 js.Statement body = unwrapStatement(currentContainer);
2873 currentContainer = oldContainerStack.removeLast(); 2879 currentContainer = oldContainerStack.removeLast();
2874 2880
2875 js.Statement result = new js.While(new js.LiteralBool(true), body); 2881 js.Statement result = new js.While(new js.LiteralBool(true), body);
2876 attachLocationRange(result, info.loopBlockInformation.sourcePosition); 2882 attachLocationRange(result,
2883 info.loopBlockInformation.sourcePosition,
2884 info.loopBlockInformation.endSourcePosition);
2877 result = new js.LabeledStatement(loopLabel, result); 2885 result = new js.LabeledStatement(loopLabel, result);
2878 result = wrapIntoLabels(result, info.labels); 2886 result = wrapIntoLabels(result, info.labels);
2879 pushStatement(result); 2887 pushStatement(result);
2880 } 2888 }
2881 2889
2882 void handleLoopCondition(HLoopBranch node) { 2890 void handleLoopCondition(HLoopBranch node) {
2883 use(node.inputs[0]); 2891 use(node.inputs[0]);
2884 js.Expression test = new js.Prefix('!', pop()); 2892 js.Expression test = new js.Prefix('!', pop());
2885 js.Statement then = new js.Break(currentLabel()); 2893 js.Statement then = new js.Break(currentLabel());
2886 pushStatement(new js.If.noElse(test, then), node); 2894 pushStatement(new js.If.noElse(test, then), node);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2968 if (leftType.canBeNull() && rightType.canBeNull()) { 2976 if (leftType.canBeNull() && rightType.canBeNull()) {
2969 if (left.isConstantNull() || right.isConstantNull() || 2977 if (left.isConstantNull() || right.isConstantNull() ||
2970 (leftType.isPrimitive() && leftType == rightType)) { 2978 (leftType.isPrimitive() && leftType == rightType)) {
2971 return '=='; 2979 return '==';
2972 } 2980 }
2973 return null; 2981 return null;
2974 } else { 2982 } else {
2975 return '==='; 2983 return '===';
2976 } 2984 }
2977 } 2985 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/builder.dart ('k') | lib/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698