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

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