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

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

Issue 1164563005: Add type arguments to lists in the code generator and make them fixed length. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fix long line. Created 5 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 '../../js/js.dart' as js; 10 import '../../js/js.dart' as js;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 : variable.element.name); 149 : variable.element.name);
150 while (!usedVariableNames.add(name)) { 150 while (!usedVariableNames.add(name)) {
151 ++counter; 151 ++counter;
152 name = '$prefix$counter'; 152 name = '$prefix$counter';
153 } 153 }
154 variableNames[variable] = name; 154 variableNames[variable] = name;
155 155
156 return name; 156 return name;
157 } 157 }
158 158
159 List<js.Expression> visitArguments(List<tree_ir.Expression> arguments) { 159 List<js.Expression> visitExpressionList(
160 return arguments.map(visitExpression).toList(); 160 List<tree_ir.Expression> expressions) {
161 return new List<js.Expression>.generate(expressions.length,
162 (int index) => visitExpression(expressions[index]),
163 growable: false);
161 } 164 }
162 165
163 giveup(tree_ir.Node node, 166 giveup(tree_ir.Node node,
164 [String reason = 'unimplemented in CodeGenerator']) { 167 [String reason = 'unimplemented in CodeGenerator']) {
165 throw new CodegenBailout(node, reason); 168 throw new CodegenBailout(node, reason);
166 } 169 }
167 170
168 @override 171 @override
169 js.Expression visitConcatenateStrings(tree_ir.ConcatenateStrings node) { 172 js.Expression visitConcatenateStrings(tree_ir.ConcatenateStrings node) {
170 js.Expression addStrings(js.Expression left, js.Expression right) { 173 js.Expression addStrings(js.Expression left, js.Expression right) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 } 238 }
236 } 239 }
237 240
238 @override 241 @override
239 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { 242 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) {
240 if (node.constant != null) return giveup(node); 243 if (node.constant != null) return giveup(node);
241 244
242 registry.registerInstantiatedType(node.type); 245 registry.registerInstantiatedType(node.type);
243 Selector selector = node.selector; 246 Selector selector = node.selector;
244 FunctionElement target = node.target; 247 FunctionElement target = node.target;
245 List<js.Expression> arguments = visitArguments(node.arguments); 248 List<js.Expression> arguments = visitExpressionList(node.arguments);
246 return buildStaticInvoke(selector, target, arguments); 249 return buildStaticInvoke(selector, target, arguments);
247 } 250 }
248 251
249 void registerMethodInvoke(tree_ir.InvokeMethod node) { 252 void registerMethodInvoke(tree_ir.InvokeMethod node) {
250 Selector selector = node.selector; 253 Selector selector = node.selector;
251 if (selector.isGetter) { 254 if (selector.isGetter) {
252 registry.registerDynamicGetter(selector); 255 registry.registerDynamicGetter(selector);
253 } else if (selector.isSetter) { 256 } else if (selector.isSetter) {
254 registry.registerDynamicSetter(selector); 257 registry.registerDynamicSetter(selector);
255 } else { 258 } else {
256 assert(invariant(CURRENT_ELEMENT_SPANNABLE, 259 assert(invariant(CURRENT_ELEMENT_SPANNABLE,
257 selector.isCall || selector.isOperator || 260 selector.isCall || selector.isOperator ||
258 selector.isIndex || selector.isIndexSet, 261 selector.isIndex || selector.isIndexSet,
259 message: 'unexpected kind ${selector.kind}')); 262 message: 'unexpected kind ${selector.kind}'));
260 // TODO(sigurdm): We should find a better place to register the call. 263 // TODO(sigurdm): We should find a better place to register the call.
261 Selector call = new Selector.callClosureFrom(selector); 264 Selector call = new Selector.callClosureFrom(selector);
262 registry.registerDynamicInvocation(call); 265 registry.registerDynamicInvocation(call);
263 registry.registerDynamicInvocation(selector); 266 registry.registerDynamicInvocation(selector);
264 } 267 }
265 } 268 }
266 269
267 @override 270 @override
268 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) { 271 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) {
269 registerMethodInvoke(node); 272 registerMethodInvoke(node);
270 return js.propertyCall(visitExpression(node.receiver), 273 return js.propertyCall(visitExpression(node.receiver),
271 glue.invocationName(node.selector), 274 glue.invocationName(node.selector),
272 visitArguments(node.arguments)); 275 visitExpressionList(node.arguments));
273 } 276 }
274 277
275 @override 278 @override
276 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { 279 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) {
277 Selector selector = node.selector; 280 Selector selector = node.selector;
278 assert(selector.isGetter || selector.isSetter || selector.isCall); 281 assert(selector.isGetter || selector.isSetter || selector.isCall);
279 FunctionElement target = node.target; 282 FunctionElement target = node.target;
280 List<js.Expression> arguments = visitArguments(node.arguments); 283 List<js.Expression> arguments = visitExpressionList(node.arguments);
281 return buildStaticInvoke(selector, target, arguments, 284 return buildStaticInvoke(selector, target, arguments,
282 sourceInformation: node.sourceInformation); 285 sourceInformation: node.sourceInformation);
283 } 286 }
284 287
285 @override 288 @override
286 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { 289 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) {
287 registry.registerDirectInvocation(node.target.declaration); 290 registry.registerDirectInvocation(node.target.declaration);
288 if (node.target is ConstructorBodyElement) { 291 if (node.target is ConstructorBodyElement) {
289 // A constructor body cannot be overriden or intercepted, so we can 292 // A constructor body cannot be overriden or intercepted, so we can
290 // use the short form for this invocation. 293 // use the short form for this invocation.
291 return js.js('#.#(#)', 294 return js.js('#.#(#)',
292 [visitExpression(node.receiver), 295 [visitExpression(node.receiver),
293 glue.instanceMethodName(node.target), 296 glue.instanceMethodName(node.target),
294 visitArguments(node.arguments)]); 297 visitExpressionList(node.arguments)]);
295 } 298 }
296 return js.js('#.#.call(#, #)', 299 return js.js('#.#.call(#, #)',
297 [glue.prototypeAccess(node.target.enclosingClass), 300 [glue.prototypeAccess(node.target.enclosingClass),
298 glue.invocationName(node.selector), 301 glue.invocationName(node.selector),
299 visitExpression(node.receiver), 302 visitExpression(node.receiver),
300 visitArguments(node.arguments)]); 303 visitExpressionList(node.arguments)]);
301 } 304 }
302 305
303 @override 306 @override
304 js.Expression visitLiteralList(tree_ir.LiteralList node) { 307 js.Expression visitLiteralList(tree_ir.LiteralList node) {
305 registry.registerInstantiatedClass(glue.listClass); 308 registry.registerInstantiatedClass(glue.listClass);
306 List<js.Expression> entries = node.values.map(visitExpression).toList(); 309 List<js.Expression> entries = visitExpressionList(node.values);
307 return new js.ArrayInitializer(entries); 310 return new js.ArrayInitializer(entries);
308 } 311 }
309 312
310 @override 313 @override
311 js.Expression visitLiteralMap(tree_ir.LiteralMap node) { 314 js.Expression visitLiteralMap(tree_ir.LiteralMap node) {
312 ConstructorElement constructor; 315 ConstructorElement constructor;
313 if (node.entries.isEmpty) { 316 if (node.entries.isEmpty) {
314 constructor = glue.mapLiteralConstructorEmpty; 317 constructor = glue.mapLiteralConstructorEmpty;
315 } else { 318 } else {
316 constructor = glue.mapLiteralConstructor; 319 constructor = glue.mapLiteralConstructor;
(...skipping 27 matching lines...) Expand all
344 } 347 }
345 348
346 @override 349 @override
347 js.Expression visitThis(tree_ir.This node) { 350 js.Expression visitThis(tree_ir.This node) {
348 return new js.This(); 351 return new js.This();
349 } 352 }
350 353
351 @override 354 @override
352 js.Expression visitTypeOperator(tree_ir.TypeOperator node) { 355 js.Expression visitTypeOperator(tree_ir.TypeOperator node) {
353 js.Expression value = visitExpression(node.value); 356 js.Expression value = visitExpression(node.value);
354 List<js.Expression> typeArguments = 357 List<js.Expression> typeArguments = visitExpressionList(node.typeArguments);
355 node.typeArguments.map(visitExpression).toList();
356 if (!node.isTypeTest) { 358 if (!node.isTypeTest) {
357 giveup(node, 'type casts not implemented.'); 359 giveup(node, 'type casts not implemented.');
358 } 360 }
359 DartType type = node.type; 361 DartType type = node.type;
360 // Note that the trivial (but special) cases of Object, dynamic, and Null 362 // Note that the trivial (but special) cases of Object, dynamic, and Null
361 // are handled at build-time and must not occur in a TypeOperator. 363 // are handled at build-time and must not occur in a TypeOperator.
362 assert(!type.isObject && !type.isDynamic); 364 assert(!type.isObject && !type.isDynamic);
363 if (type is InterfaceType) { 365 if (type is InterfaceType) {
364 glue.registerIsCheck(type, registry); 366 glue.registerIsCheck(type, registry);
365 ClassElement clazz = type.element; 367 ClassElement clazz = type.element;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 tree_ir.Variable exceptionVariable = node.catchParameters.first; 552 tree_ir.Variable exceptionVariable = node.catchParameters.first;
551 js.VariableDeclaration exceptionParameter = 553 js.VariableDeclaration exceptionParameter =
552 new js.VariableDeclaration(getVariableName(exceptionVariable)); 554 new js.VariableDeclaration(getVariableName(exceptionVariable));
553 js.Block catchBlock = buildBodyBlock(node.catchBody); 555 js.Block catchBlock = buildBodyBlock(node.catchBody);
554 js.Catch catchPart = new js.Catch(exceptionParameter, catchBlock); 556 js.Catch catchPart = new js.Catch(exceptionParameter, catchBlock);
555 accumulator.add(new js.Try(tryBlock, catchPart, null)); 557 accumulator.add(new js.Try(tryBlock, catchPart, null));
556 } 558 }
557 559
558 @override 560 @override
559 js.Expression visitCreateBox(tree_ir.CreateBox node) { 561 js.Expression visitCreateBox(tree_ir.CreateBox node) {
560 return new js.ObjectInitializer([]); 562 return new js.ObjectInitializer(const <js.Property>[]);
561 } 563 }
562 564
563 @override 565 @override
564 js.Expression visitCreateInstance(tree_ir.CreateInstance node) { 566 js.Expression visitCreateInstance(tree_ir.CreateInstance node) {
565 ClassElement cls = node.classElement; 567 ClassElement cls = node.classElement;
566 // TODO(asgerf): To allow inlining of InvokeConstructor, CreateInstance must 568 // TODO(asgerf): To allow inlining of InvokeConstructor, CreateInstance must
567 // carry a DartType so we can register the instantiated type 569 // carry a DartType so we can register the instantiated type
568 // with its type arguments. Otherwise dataflow analysis is 570 // with its type arguments. Otherwise dataflow analysis is
569 // needed to reconstruct the instantiated type. 571 // needed to reconstruct the instantiated type.
570 registry.registerInstantiatedClass(cls); 572 registry.registerInstantiatedClass(cls);
571 js.Expression instance = new js.New( 573 js.Expression instance = new js.New(
572 glue.constructorAccess(cls), 574 glue.constructorAccess(cls),
573 node.arguments.map(visitExpression).toList()); 575 visitExpressionList(node.arguments));
574 576
575 List<tree_ir.Expression> typeInformation = node.typeInformation; 577 List<tree_ir.Expression> typeInformation = node.typeInformation;
576 assert(typeInformation.isEmpty || 578 assert(typeInformation.isEmpty ||
577 typeInformation.length == cls.typeVariables.length); 579 typeInformation.length == cls.typeVariables.length);
578 if (typeInformation.isNotEmpty) { 580 if (typeInformation.isNotEmpty) {
579 FunctionElement helper = glue.getAddRuntimeTypeInformation(); 581 FunctionElement helper = glue.getAddRuntimeTypeInformation();
580 js.Expression typeArguments = new js.ArrayInitializer( 582 js.Expression typeArguments = new js.ArrayInitializer(
581 typeInformation.map(visitExpression).toList()); 583 visitExpressionList(typeInformation));
582 return buildStaticHelperInvocation(helper, 584 return buildStaticHelperInvocation(helper,
583 <js.Expression>[instance, typeArguments]); 585 <js.Expression>[instance, typeArguments]);
584 } else { 586 } else {
585 return instance; 587 return instance;
586 } 588 }
587 } 589 }
588 590
589 @override 591 @override
590 js.Expression visitCreateInvocationMirror( 592 js.Expression visitCreateInvocationMirror(
591 tree_ir.CreateInvocationMirror node) { 593 tree_ir.CreateInvocationMirror node) {
592 js.Expression name = js.string(node.selector.name); 594 js.Expression name = js.string(node.selector.name);
593 js.Expression internalName = js.string(glue.invocationName(node.selector)); 595 js.Expression internalName = js.string(glue.invocationName(node.selector));
594 js.Expression kind = js.number(node.selector.invocationMirrorKind); 596 js.Expression kind = js.number(node.selector.invocationMirrorKind);
595 js.Expression arguments = new js.ArrayInitializer( 597 js.Expression arguments = new js.ArrayInitializer(
596 node.arguments.map(visitExpression).toList()); 598 visitExpressionList(node.arguments));
597 js.Expression argumentNames = new js.ArrayInitializer( 599 js.Expression argumentNames = new js.ArrayInitializer(
598 node.selector.namedArguments.map(js.string).toList()); 600 node.selector.namedArguments.map(js.string).toList(growable: false));
599 return buildStaticHelperInvocation(glue.createInvocationMirrorMethod, 601 return buildStaticHelperInvocation(glue.createInvocationMirrorMethod,
600 [name, internalName, kind, arguments, argumentNames]); 602 [name, internalName, kind, arguments, argumentNames]);
601 } 603 }
602 604
603 @override 605 @override
604 js.Expression visitGetField(tree_ir.GetField node) { 606 js.Expression visitGetField(tree_ir.GetField node) {
605 return new js.PropertyAccess.field( 607 return new js.PropertyAccess.field(
606 visitExpression(node.object), 608 visitExpression(node.object),
607 glue.instanceFieldPropertyName(node.field)); 609 glue.instanceFieldPropertyName(node.field));
608 } 610 }
(...skipping 12 matching lines...) Expand all
621 assert(node.element is FieldElement || node.element is FunctionElement); 623 assert(node.element is FieldElement || node.element is FunctionElement);
622 if (node.element is FunctionElement) { 624 if (node.element is FunctionElement) {
623 // Tear off a method. 625 // Tear off a method.
624 registry.registerGetOfStaticFunction(node.element.declaration); 626 registry.registerGetOfStaticFunction(node.element.declaration);
625 return glue.isolateStaticClosureAccess(node.element); 627 return glue.isolateStaticClosureAccess(node.element);
626 } 628 }
627 if (glue.isLazilyInitialized(node.element)) { 629 if (glue.isLazilyInitialized(node.element)) {
628 // Read a lazily initialized field. 630 // Read a lazily initialized field.
629 registry.registerStaticUse(node.element.declaration); 631 registry.registerStaticUse(node.element.declaration);
630 js.Expression getter = glue.isolateLazyInitializerAccess(node.element); 632 js.Expression getter = glue.isolateLazyInitializerAccess(node.element);
631 return new js.Call(getter, [], sourceInformation: node.sourceInformation); 633 return new js.Call(getter, <js.Expression>[],
634 sourceInformation: node.sourceInformation);
632 } 635 }
633 // Read an eagerly initialized field. 636 // Read an eagerly initialized field.
634 registry.registerStaticUse(node.element.declaration); 637 registry.registerStaticUse(node.element.declaration);
635 return glue.staticFieldAccess(node.element); 638 return glue.staticFieldAccess(node.element);
636 } 639 }
637 640
638 @override 641 @override
639 js.Expression visitSetStatic(tree_ir.SetStatic node) { 642 js.Expression visitSetStatic(tree_ir.SetStatic node) {
640 assert(node.element is FieldElement); 643 assert(node.element is FieldElement);
641 registry.registerStaticUse(node.element.declaration); 644 registry.registerStaticUse(node.element.declaration);
(...skipping 29 matching lines...) Expand all
671 [visitExpression(node.target), typeName, index]); 674 [visitExpression(node.target), typeName, index]);
672 } else { 675 } else {
673 return buildStaticHelperInvocation( 676 return buildStaticHelperInvocation(
674 glue.getTypeArgumentByIndex(), 677 glue.getTypeArgumentByIndex(),
675 [visitExpression(node.target), index]); 678 [visitExpression(node.target), index]);
676 } 679 }
677 } 680 }
678 681
679 @override 682 @override
680 js.Expression visitTypeExpression(tree_ir.TypeExpression node) { 683 js.Expression visitTypeExpression(tree_ir.TypeExpression node) {
681 List<js.Expression> arguments = 684 List<js.Expression> arguments = visitExpressionList(node.arguments);
682 node.arguments.map(visitExpression).toList(growable: false);
683 return glue.generateTypeRepresentation(node.dartType, arguments); 685 return glue.generateTypeRepresentation(node.dartType, arguments);
684 } 686 }
685 687
686 visitFunctionExpression(tree_ir.FunctionExpression node) { 688 visitFunctionExpression(tree_ir.FunctionExpression node) {
687 // FunctionExpressions are currently unused. 689 // FunctionExpressions are currently unused.
688 // We might need them if we want to emit raw JS nested functions. 690 // We might need them if we want to emit raw JS nested functions.
689 throw 'FunctionExpressions should not be used'; 691 throw 'FunctionExpressions should not be used';
690 } 692 }
691 } 693 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698