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

Side by Side Diff: pkg/compiler/lib/src/js_backend/codegen/codegen.dart

Issue 1229673006: Generated source mapping through CPS. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 5 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library code_generator; 5 library code_generator;
6 6
7 import 'glue.dart'; 7 import 'glue.dart';
8 8
9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
10 import '../../tree_ir/tree_ir_nodes.dart' show BuiltinOperator; 10 import '../../tree_ir/tree_ir_nodes.dart' show BuiltinOperator;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 new Maplet<VariableElement, String>(); 44 new Maplet<VariableElement, String>();
45 45
46 /// Variable names that have already been used. Used to avoid name clashes. 46 /// Variable names that have already been used. Used to avoid name clashes.
47 Set<String> usedVariableNames = new Set<String>(); 47 Set<String> usedVariableNames = new Set<String>();
48 48
49 final tree_ir.FallthroughStack fallthrough = new tree_ir.FallthroughStack(); 49 final tree_ir.FallthroughStack fallthrough = new tree_ir.FallthroughStack();
50 50
51 /// Stacks whose top element is the current target of an unlabeled break 51 /// Stacks whose top element is the current target of an unlabeled break
52 /// or continue. For continues, this is the loop node itself. 52 /// or continue. For continues, this is the loop node itself.
53 final tree_ir.FallthroughStack shortBreak = new tree_ir.FallthroughStack(); 53 final tree_ir.FallthroughStack shortBreak = new tree_ir.FallthroughStack();
54 final tree_ir.FallthroughStack shortContinue = 54 final tree_ir.FallthroughStack shortContinue =
55 new tree_ir.FallthroughStack(); 55 new tree_ir.FallthroughStack();
56 56
57 Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>(); 57 Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>();
58 58
59 List<js.Statement> accumulator = new List<js.Statement>(); 59 List<js.Statement> accumulator = new List<js.Statement>();
60 60
61 CodeGenerator(this.glue, this.registry); 61 CodeGenerator(this.glue, this.registry);
62 62
63 /// Generates JavaScript code for the body of [function]. 63 /// Generates JavaScript code for the body of [function].
64 js.Fun buildFunction(tree_ir.FunctionDefinition function) { 64 js.Fun buildFunction(tree_ir.FunctionDefinition function) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 } 176 }
177 177
178 @override 178 @override
179 js.Expression visitConditional(tree_ir.Conditional node) { 179 js.Expression visitConditional(tree_ir.Conditional node) {
180 return new js.Conditional( 180 return new js.Conditional(
181 visitExpression(node.condition), 181 visitExpression(node.condition),
182 visitExpression(node.thenExpression), 182 visitExpression(node.thenExpression),
183 visitExpression(node.elseExpression)); 183 visitExpression(node.elseExpression));
184 } 184 }
185 185
186 js.Expression buildConstant(ConstantValue constant) { 186 js.Expression buildConstant(ConstantValue constant,
187 {SourceInformation sourceInformation}) {
187 registry.registerCompileTimeConstant(constant); 188 registry.registerCompileTimeConstant(constant);
188 return glue.constantReference(constant); 189 return glue.constantReference(constant)
190 .withSourceInformation(sourceInformation);
189 } 191 }
190 192
191 @override 193 @override
192 js.Expression visitConstant(tree_ir.Constant node) { 194 js.Expression visitConstant(tree_ir.Constant node) {
193 return buildConstant(node.value); 195 return buildConstant(
196 node.value,
197 sourceInformation: node.sourceInformation);
194 } 198 }
195 199
196 js.Expression compileConstant(ParameterElement parameter) { 200 js.Expression compileConstant(ParameterElement parameter) {
197 return buildConstant(glue.getConstantValueForVariable(parameter)); 201 return buildConstant(glue.getConstantValueForVariable(parameter));
198 } 202 }
199 203
200 js.Expression buildStaticInvoke(Element target, 204 js.Expression buildStaticInvoke(Element target,
201 List<js.Expression> arguments, 205 List<js.Expression> arguments,
202 {SourceInformation sourceInformation}) { 206 {SourceInformation sourceInformation}) {
203 registry.registerStaticInvocation(target.declaration); 207 registry.registerStaticInvocation(target.declaration);
204 js.Expression elementAccess = glue.staticFunctionAccess(target); 208 js.Expression elementAccess = glue.staticFunctionAccess(target);
205 return new js.Call(elementAccess, arguments, 209 return new js.Call(elementAccess, arguments,
206 sourceInformation: sourceInformation); 210 sourceInformation: sourceInformation);
207 } 211 }
208 212
209 @override 213 @override
210 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { 214 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) {
211 if (node.constant != null) return giveup(node); 215 if (node.constant != null) return giveup(node);
212 216
213 registry.registerInstantiatedType(node.type); 217 registry.registerInstantiatedType(node.type);
214 FunctionElement target = node.target; 218 FunctionElement target = node.target;
215 List<js.Expression> arguments = visitExpressionList(node.arguments); 219 List<js.Expression> arguments = visitExpressionList(node.arguments);
216 return buildStaticInvoke(target, arguments); 220 return buildStaticInvoke(
221 target, arguments, sourceInformation: node.sourceInformation);
217 } 222 }
218 223
219 void registerMethodInvoke(tree_ir.InvokeMethod node) { 224 void registerMethodInvoke(tree_ir.InvokeMethod node) {
220 Selector selector = node.selector; 225 Selector selector = node.selector;
221 TypeMask mask = node.mask; 226 TypeMask mask = node.mask;
222 if (selector.isGetter) { 227 if (selector.isGetter) {
223 registry.registerDynamicGetter(new UniverseSelector(selector, mask)); 228 registry.registerDynamicGetter(new UniverseSelector(selector, mask));
224 } else if (selector.isSetter) { 229 } else if (selector.isSetter) {
225 registry.registerDynamicSetter(new UniverseSelector(selector, mask)); 230 registry.registerDynamicSetter(new UniverseSelector(selector, mask));
226 } else { 231 } else {
227 assert(invariant(CURRENT_ELEMENT_SPANNABLE, 232 assert(invariant(CURRENT_ELEMENT_SPANNABLE,
228 selector.isCall || selector.isOperator || 233 selector.isCall || selector.isOperator ||
229 selector.isIndex || selector.isIndexSet, 234 selector.isIndex || selector.isIndexSet,
230 message: 'unexpected kind ${selector.kind}')); 235 message: 'unexpected kind ${selector.kind}'));
231 // TODO(sigurdm): We should find a better place to register the call. 236 // TODO(sigurdm): We should find a better place to register the call.
232 Selector call = new Selector.callClosureFrom(selector); 237 Selector call = new Selector.callClosureFrom(selector);
233 registry.registerDynamicInvocation(new UniverseSelector(call, null)); 238 registry.registerDynamicInvocation(new UniverseSelector(call, null));
234 registry.registerDynamicInvocation(new UniverseSelector(selector, mask)); 239 registry.registerDynamicInvocation(new UniverseSelector(selector, mask));
235 } 240 }
236 } 241 }
237 242
238 @override 243 @override
239 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) { 244 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) {
240 registerMethodInvoke(node); 245 registerMethodInvoke(node);
241 return js.propertyCall(visitExpression(node.receiver), 246 return js.propertyCall(visitExpression(node.receiver),
242 glue.invocationName(node.selector), 247 glue.invocationName(node.selector),
243 visitExpressionList(node.arguments)); 248 visitExpressionList(node.arguments))
249 .withSourceInformation(node.sourceInformation);
244 } 250 }
245 251
246 @override 252 @override
247 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { 253 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) {
248 FunctionElement target = node.target; 254 FunctionElement target = node.target;
249 List<js.Expression> arguments = visitExpressionList(node.arguments); 255 List<js.Expression> arguments = visitExpressionList(node.arguments);
250 return buildStaticInvoke(target, arguments, 256 return buildStaticInvoke(target, arguments,
251 sourceInformation: node.sourceInformation); 257 sourceInformation: node.sourceInformation);
252 } 258 }
253 259
254 @override 260 @override
255 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { 261 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) {
256 registry.registerDirectInvocation(node.target.declaration); 262 registry.registerDirectInvocation(node.target.declaration);
257 if (node.target is ConstructorBodyElement) { 263 if (node.target is ConstructorBodyElement) {
258 // A constructor body cannot be overriden or intercepted, so we can 264 // A constructor body cannot be overriden or intercepted, so we can
259 // use the short form for this invocation. 265 // use the short form for this invocation.
260 return js.js('#.#(#)', 266 return js.js('#.#(#)',
261 [visitExpression(node.receiver), 267 [visitExpression(node.receiver),
262 glue.instanceMethodName(node.target), 268 glue.instanceMethodName(node.target),
263 visitExpressionList(node.arguments)]); 269 visitExpressionList(node.arguments)])
270 .withSourceInformation(node.sourceInformation);
264 } 271 }
265 return js.js('#.#.call(#, #)', 272 return js.js('#.#.call(#, #)',
266 [glue.prototypeAccess(node.target.enclosingClass), 273 [glue.prototypeAccess(node.target.enclosingClass),
267 glue.invocationName(node.selector), 274 glue.invocationName(node.selector),
268 visitExpression(node.receiver), 275 visitExpression(node.receiver),
269 visitExpressionList(node.arguments)]); 276 visitExpressionList(node.arguments)])
277 .withSourceInformation(node.sourceInformation);
270 } 278 }
271 279
272 @override 280 @override
273 js.Expression visitLiteralList(tree_ir.LiteralList node) { 281 js.Expression visitLiteralList(tree_ir.LiteralList node) {
274 registry.registerInstantiatedClass(glue.listClass); 282 registry.registerInstantiatedClass(glue.listClass);
275 List<js.Expression> entries = visitExpressionList(node.values); 283 List<js.Expression> entries = visitExpressionList(node.values);
276 return new js.ArrayInitializer(entries); 284 return new js.ArrayInitializer(entries);
277 } 285 }
278 286
279 @override 287 @override
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } 426 }
419 427
420 @override 428 @override
421 void visitBreak(tree_ir.Break node) { 429 void visitBreak(tree_ir.Break node) {
422 if (isEffectiveBreakTarget(node, fallthrough.target)) { 430 if (isEffectiveBreakTarget(node, fallthrough.target)) {
423 // Fall through to break target or to equivalent break. 431 // Fall through to break target or to equivalent break.
424 fallthrough.use(); 432 fallthrough.use();
425 } else if (isEffectiveBreakTarget(node, shortBreak.target)) { 433 } else if (isEffectiveBreakTarget(node, shortBreak.target)) {
426 // Unlabeled break to the break target or to an equivalent break. 434 // Unlabeled break to the break target or to an equivalent break.
427 shortBreak.use(); 435 shortBreak.use();
428 accumulator.add(new js.Break(null)); 436 accumulator.add(new js.Break(null));
429 } else { 437 } else {
430 usedLabels.add(node.target); 438 usedLabels.add(node.target);
431 accumulator.add(new js.Break(node.target.name)); 439 accumulator.add(new js.Break(node.target.name));
432 } 440 }
433 } 441 }
434 442
435 @override 443 @override
436 void visitExpressionStatement(tree_ir.ExpressionStatement node) { 444 void visitExpressionStatement(tree_ir.ExpressionStatement node) {
437 accumulator.add(new js.ExpressionStatement( 445 accumulator.add(new js.ExpressionStatement(
438 visitExpression(node.expression))); 446 visitExpression(node.expression)));
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 return node is tree_ir.Constant && node.value.isNull; 548 return node is tree_ir.Constant && node.value.isNull;
541 } 549 }
542 550
543 @override 551 @override
544 void visitReturn(tree_ir.Return node) { 552 void visitReturn(tree_ir.Return node) {
545 if (isNull(node.value) && fallthrough.target == null) { 553 if (isNull(node.value) && fallthrough.target == null) {
546 // Do nothing. Implicitly return JS undefined by falling over the end. 554 // Do nothing. Implicitly return JS undefined by falling over the end.
547 registry.registerCompileTimeConstant(new NullConstantValue()); 555 registry.registerCompileTimeConstant(new NullConstantValue());
548 fallthrough.use(); 556 fallthrough.use();
549 } else { 557 } else {
550 accumulator.add(new js.Return(visitExpression(node.value))); 558 accumulator.add(new js.Return(visitExpression(node.value))
559 .withSourceInformation(node.sourceInformation));
551 } 560 }
552 } 561 }
553 562
554 @override 563 @override
555 void visitThrow(tree_ir.Throw node) { 564 void visitThrow(tree_ir.Throw node) {
556 accumulator.add(new js.Throw(visitExpression(node.value))); 565 accumulator.add(new js.Throw(visitExpression(node.value)));
557 } 566 }
558 567
559 @override 568 @override
560 void visitRethrow(tree_ir.Rethrow node) { 569 void visitRethrow(tree_ir.Rethrow node) {
(...skipping 28 matching lines...) Expand all
589 // TODO(asgerf): To allow inlining of InvokeConstructor, CreateInstance must 598 // TODO(asgerf): To allow inlining of InvokeConstructor, CreateInstance must
590 // carry a DartType so we can register the instantiated type 599 // carry a DartType so we can register the instantiated type
591 // with its type arguments. Otherwise dataflow analysis is 600 // with its type arguments. Otherwise dataflow analysis is
592 // needed to reconstruct the instantiated type. 601 // needed to reconstruct the instantiated type.
593 registry.registerInstantiatedClass(classElement); 602 registry.registerInstantiatedClass(classElement);
594 if (classElement is ClosureClassElement) { 603 if (classElement is ClosureClassElement) {
595 registry.registerInstantiatedClosure(classElement.methodElement); 604 registry.registerInstantiatedClosure(classElement.methodElement);
596 } 605 }
597 js.Expression instance = new js.New( 606 js.Expression instance = new js.New(
598 glue.constructorAccess(classElement), 607 glue.constructorAccess(classElement),
599 visitExpressionList(node.arguments)); 608 visitExpressionList(node.arguments))
609 .withSourceInformation(node.sourceInformation);
600 610
601 List<tree_ir.Expression> typeInformation = node.typeInformation; 611 List<tree_ir.Expression> typeInformation = node.typeInformation;
602 assert(typeInformation.isEmpty || 612 assert(typeInformation.isEmpty ||
603 typeInformation.length == classElement.typeVariables.length); 613 typeInformation.length == classElement.typeVariables.length);
604 if (typeInformation.isNotEmpty) { 614 if (typeInformation.isNotEmpty) {
605 FunctionElement helper = glue.getAddRuntimeTypeInformation(); 615 FunctionElement helper = glue.getAddRuntimeTypeInformation();
606 js.Expression typeArguments = new js.ArrayInitializer( 616 js.Expression typeArguments = new js.ArrayInitializer(
607 visitExpressionList(typeInformation)); 617 visitExpressionList(typeInformation));
608 return buildStaticHelperInvocation(helper, 618 return buildStaticHelperInvocation(helper,
609 <js.Expression>[instance, typeArguments]); 619 <js.Expression>[instance, typeArguments],
620 sourceInformation: node.sourceInformation);
610 } else { 621 } else {
611 return instance; 622 return instance;
612 } 623 }
613 } 624 }
614 625
615 @override 626 @override
616 js.Expression visitCreateInvocationMirror( 627 js.Expression visitCreateInvocationMirror(
617 tree_ir.CreateInvocationMirror node) { 628 tree_ir.CreateInvocationMirror node) {
618 js.Expression name = js.string(node.selector.name); 629 js.Expression name = js.string(node.selector.name);
619 js.Expression internalName = 630 js.Expression internalName =
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 } 708 }
698 709
699 @override 710 @override
700 js.Expression visitSetIndex(tree_ir.SetIndex node) { 711 js.Expression visitSetIndex(tree_ir.SetIndex node) {
701 return js.js('#[#] = #', 712 return js.js('#[#] = #',
702 [visitExpression(node.object), 713 [visitExpression(node.object),
703 visitExpression(node.index), 714 visitExpression(node.index),
704 visitExpression(node.value)]); 715 visitExpression(node.value)]);
705 } 716 }
706 717
707 js.Expression buildStaticHelperInvocation(FunctionElement helper, 718 js.Expression buildStaticHelperInvocation(
708 List<js.Expression> arguments) { 719 FunctionElement helper,
720 List<js.Expression> arguments,
721 {SourceInformation sourceInformation}) {
709 registry.registerStaticUse(helper); 722 registry.registerStaticUse(helper);
710 return buildStaticInvoke(helper, arguments); 723 return buildStaticInvoke(
724 helper, arguments, sourceInformation: sourceInformation);
711 } 725 }
712 726
713 @override 727 @override
714 js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) { 728 js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) {
715 FunctionElement createType = glue.getCreateRuntimeType(); 729 js.Expression typeToString = buildStaticHelperInvocation(
716 FunctionElement typeToString = glue.getRuntimeTypeToString(); 730 glue.getRuntimeTypeToString(),
717 return buildStaticHelperInvocation(createType, 731 [visitExpression(node.value)],
718 [buildStaticHelperInvocation(typeToString, 732 sourceInformation: node.sourceInformation);
719 [visitExpression(node.value)])]); 733 return buildStaticHelperInvocation(
734 glue.getCreateRuntimeType(),
735 [typeToString],
736 sourceInformation: node.sourceInformation);
720 } 737 }
721 738
722 @override 739 @override
723 js.Expression visitReadTypeVariable(tree_ir.ReadTypeVariable node) { 740 js.Expression visitReadTypeVariable(tree_ir.ReadTypeVariable node) {
724 ClassElement context = node.variable.element.enclosingClass; 741 ClassElement context = node.variable.element.enclosingClass;
725 js.Expression index = js.number(glue.getTypeVariableIndex(node.variable)); 742 js.Expression index = js.number(glue.getTypeVariableIndex(node.variable));
726 if (glue.needsSubstitutionForTypeVariableAccess(context)) { 743 if (glue.needsSubstitutionForTypeVariableAccess(context)) {
727 js.Expression typeName = glue.getRuntimeTypeName(context); 744 js.Expression typeName = glue.getRuntimeTypeName(context);
728 return buildStaticHelperInvocation( 745 return buildStaticHelperInvocation(
729 glue.getRuntimeTypeArgument(), 746 glue.getRuntimeTypeArgument(),
730 [visitExpression(node.target), typeName, index]); 747 [visitExpression(node.target), typeName, index],
748 sourceInformation: node.sourceInformation);
731 } else { 749 } else {
732 return buildStaticHelperInvocation( 750 return buildStaticHelperInvocation(
733 glue.getTypeArgumentByIndex(), 751 glue.getTypeArgumentByIndex(),
734 [visitExpression(node.target), index]); 752 [visitExpression(node.target), index],
753 sourceInformation: node.sourceInformation);
735 } 754 }
736 } 755 }
737 756
738 @override 757 @override
739 js.Expression visitTypeExpression(tree_ir.TypeExpression node) { 758 js.Expression visitTypeExpression(tree_ir.TypeExpression node) {
740 List<js.Expression> arguments = visitExpressionList(node.arguments); 759 List<js.Expression> arguments = visitExpressionList(node.arguments);
741 return glue.generateTypeRepresentation(node.dartType, arguments); 760 return glue.generateTypeRepresentation(node.dartType, arguments);
742 } 761 }
743 762
744 js.Node handleForeignCode(tree_ir.ForeignCode node) { 763 js.Node handleForeignCode(tree_ir.ForeignCode node) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 return js.js("typeof # === 'number' && Math.floor(#) === #", args); 825 return js.js("typeof # === 'number' && Math.floor(#) === #", args);
807 } 826 }
808 } 827 }
809 828
810 visitFunctionExpression(tree_ir.FunctionExpression node) { 829 visitFunctionExpression(tree_ir.FunctionExpression node) {
811 // FunctionExpressions are currently unused. 830 // FunctionExpressions are currently unused.
812 // We might need them if we want to emit raw JS nested functions. 831 // We might need them if we want to emit raw JS nested functions.
813 throw 'FunctionExpressions should not be used'; 832 throw 'FunctionExpressions should not be used';
814 } 833 }
815 } 834 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/io/start_end_information.dart ('k') | pkg/compiler/lib/src/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698