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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 701123002: Support local functions in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comment Created 6 years, 1 month 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import '../constants/expressions.dart'; 7 import '../constants/expressions.dart';
8 import '../constants/values.dart' show PrimitiveConstantValue; 8 import '../constants/values.dart' show PrimitiveConstantValue;
9 import '../dart_backend/dart_backend.dart' show DartBackend; 9 import '../dart_backend/dart_backend.dart' show DartBackend;
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 299
300 /// Add the constant [variableElement] to the environment with [value] as its 300 /// Add the constant [variableElement] to the environment with [value] as its
301 /// constant value. 301 /// constant value.
302 void declareLocalConstant(LocalVariableElement variableElement, 302 void declareLocalConstant(LocalVariableElement variableElement,
303 ConstantExpression value) { 303 ConstantExpression value) {
304 state.localConstants.add(new ConstDeclaration(variableElement, value)); 304 state.localConstants.add(new ConstDeclaration(variableElement, value));
305 } 305 }
306 306
307 /// Add [variableElement] to the environment with [initialValue] as its 307 /// Add [variableElement] to the environment with [initialValue] as its
308 /// initial value. 308 /// initial value.
309 ///
310 /// [isClosureVariable] marks whether [variableElement] is accessed from an
311 /// inner function.
312 void declareLocalVariable(LocalVariableElement variableElement, 309 void declareLocalVariable(LocalVariableElement variableElement,
313 {ir.Primitive initialValue}) { 310 {ir.Primitive initialValue}) {
314 assert(isOpen); 311 assert(isOpen);
315 if (initialValue == null) { 312 if (initialValue == null) {
316 // TODO(kmillikin): Consider pooling constants. 313 // TODO(kmillikin): Consider pooling constants.
317 // The initial value is null. 314 // The initial value is null.
318 initialValue = buildNullLiteral(); 315 initialValue = buildNullLiteral();
319 } 316 }
320 if (isClosureVariable(variableElement)) { 317 if (isClosureVariable(variableElement)) {
321 add(new ir.SetClosureVariable(variableElement, 318 add(new ir.SetClosureVariable(variableElement,
322 initialValue, 319 initialValue,
323 isDeclaration: true)); 320 isDeclaration: true));
324 } else { 321 } else {
325 // In case a primitive was introduced for the initializer expression, 322 // In case a primitive was introduced for the initializer expression,
326 // use this variable element to help derive a good name for it. 323 // use this variable element to help derive a good name for it.
327 initialValue.useElementAsHint(variableElement); 324 initialValue.useElementAsHint(variableElement);
328 environment.extend(variableElement, initialValue); 325 environment.extend(variableElement, initialValue);
329 } 326 }
330 } 327 }
331 328
329 /// Add [functionElement] to the environment with provided [definition].
330 void declareLocalFunction(LocalFunctionElement functionElement,
331 ir.FunctionDefinition definition) {
332 assert(isOpen);
333 if (isClosureVariable(functionElement)) {
334 add(new ir.DeclareFunction(functionElement, definition));
335 } else {
336 ir.CreateFunction prim = new ir.CreateFunction(definition);
337 add(new ir.LetPrim(prim));
338 environment.extend(functionElement, prim);
339 prim.useElementAsHint(functionElement);
340 }
341 }
342
332 // Plug an expression into the 'hole' in the context being accumulated. The 343 // Plug an expression into the 'hole' in the context being accumulated. The
333 // empty context (just a hole) is represented by root (and current) being 344 // empty context (just a hole) is represented by root (and current) being
334 // null. Since the hole in the current context is filled by this function, 345 // null. Since the hole in the current context is filled by this function,
335 // the new hole must be in the newly added expression---which becomes the 346 // the new hole must be in the newly added expression---which becomes the
336 // new value of current. 347 // new value of current.
337 void add(ir.Expression expr) { 348 void add(ir.Expression expr) {
338 assert(isOpen); 349 assert(isOpen);
339 if (_root == null) { 350 if (_root == null) {
340 _root = _current = expr; 351 _root = _current = expr;
341 } else { 352 } else {
(...skipping 25 matching lines...) Expand all
367 } 378 }
368 379
369 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, 380 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver,
370 Selector selector, 381 Selector selector,
371 List<ir.Definition> arguments) { 382 List<ir.Definition> arguments) {
372 assert(isOpen); 383 assert(isOpen);
373 return _continueWithExpression( 384 return _continueWithExpression(
374 (k) => new ir.InvokeMethod(receiver, selector, k, arguments)); 385 (k) => new ir.InvokeMethod(receiver, selector, k, arguments));
375 } 386 }
376 387
388 ir.Primitive _buildInvokeCall(ir.Primitive target,
389 Selector selector,
390 List<ir.Definition> arguments) {
391 Selector callSelector = new Selector.callClosure(
392 selector.argumentCount,
393 selector.namedArguments);
394 return _buildInvokeDynamic(target, callSelector, arguments);
395 }
396
377 397
378 /// Create a constant literal from [constant]. 398 /// Create a constant literal from [constant].
379 ir.Constant buildConstantLiteral(ConstantExpression constant) { 399 ir.Constant buildConstantLiteral(ConstantExpression constant) {
380 assert(isOpen); 400 assert(isOpen);
381 ir.Constant prim = new ir.Constant(constant); 401 ir.Constant prim = new ir.Constant(constant);
382 add(new ir.LetPrim(prim)); 402 add(new ir.LetPrim(prim));
383 return prim; 403 return prim;
384 } 404 }
385 405
386 // Helper for building primitive literals. 406 // Helper for building primitive literals.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 new ir.LetCont(elseContinuation, 507 new ir.LetCont(elseContinuation,
488 new ir.Branch(new ir.IsTrue(condition), 508 new ir.Branch(new ir.IsTrue(condition),
489 thenContinuation, 509 thenContinuation,
490 elseContinuation))))); 510 elseContinuation)))));
491 return (thenValue == elseValue) 511 return (thenValue == elseValue)
492 ? thenValue 512 ? thenValue
493 : joinContinuation.parameters.last; 513 : joinContinuation.parameters.last;
494 514
495 } 515 }
496 516
517 /// Create a function expression from [definition].
518 ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) {
519 ir.CreateFunction prim = new ir.CreateFunction(definition);
520 add(new ir.LetPrim(prim));
521 return prim;
522 }
523
497 /** 524 /**
498 * Add an explicit `return null` for functions that don't have a return 525 * Add an explicit `return null` for functions that don't have a return
499 * statement on each branch. This includes functions with an empty body, 526 * statement on each branch. This includes functions with an empty body,
500 * such as `foo(){ }`. 527 * such as `foo(){ }`.
501 */ 528 */
502 void _ensureReturn() { 529 void _ensureReturn() {
503 if (!isOpen) return; 530 if (!isOpen) return;
504 ir.Constant constant = buildNullLiteral(); 531 ir.Constant constant = buildNullLiteral();
505 add(new ir.InvokeContinuation(state.returnContinuation, [constant])); 532 add(new ir.InvokeContinuation(state.returnContinuation, [constant]));
506 _current = null; 533 _current = null;
(...skipping 15 matching lines...) Expand all
522 assert(invariant(element, _root == null, 549 assert(invariant(element, _root == null,
523 message: "Non-empty body for abstract method $element: $_root")); 550 message: "Non-empty body for abstract method $element: $_root"));
524 assert(invariant(element, state.localConstants.isEmpty, 551 assert(invariant(element, state.localConstants.isEmpty,
525 message: "Local constants for abstract method $element: " 552 message: "Local constants for abstract method $element: "
526 "${state.localConstants}")); 553 "${state.localConstants}"));
527 return new ir.FunctionDefinition.abstract( 554 return new ir.FunctionDefinition.abstract(
528 element, _parameters, defaults); 555 element, _parameters, defaults);
529 } 556 }
530 } 557 }
531 558
532
533 /// Create a super invocation where the method name and the argument structure 559 /// Create a super invocation where the method name and the argument structure
534 /// are defined by [selector] and the argument values are defined by 560 /// are defined by [selector] and the argument values are defined by
535 /// [arguments]. 561 /// [arguments].
536 ir.Primitive buildSuperInvocation(Selector selector, 562 ir.Primitive buildSuperInvocation(Selector selector,
537 List<ir.Definition> arguments) { 563 List<ir.Definition> arguments) {
538 return _buildInvokeSuper(selector, arguments); 564 return _buildInvokeSuper(selector, arguments);
539 } 565 }
540 566
541 /// Create a getter invocation on the super class where the getter name is 567 /// Create a getter invocation on the super class where the getter name is
542 /// defined by [selector]. 568 /// defined by [selector].
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 assert(isOpen); 684 assert(isOpen);
659 if (isClosureVariable(local)) { 685 if (isClosureVariable(local)) {
660 add(new ir.SetClosureVariable(local, value)); 686 add(new ir.SetClosureVariable(local, value));
661 } else { 687 } else {
662 value.useElementAsHint(local); 688 value.useElementAsHint(local);
663 environment.update(local, value); 689 environment.update(local, value);
664 } 690 }
665 return value; 691 return value;
666 } 692 }
667 693
694 /// Create an invocation of [local] where the argument structure is defined
695 /// by [selector] and the argument values are defined by [arguments].
696 ir.Primitive buildLocalInvocation(LocalElement local,
697 Selector selector,
698 List<ir.Definition> arguments) {
699 ir.Primitive receiver;
700 if (isClosureVariable(local)) {
701 receiver = new ir.GetClosureVariable(local);
702 add(new ir.LetPrim(receiver));
703 } else {
704 receiver = environment.lookup(local);
705 }
706 return _buildInvokeCall(receiver, selector, arguments);
707 }
708
709 /// Create an invocation of the [functionExpression] where the argument
710 /// structure are defined by [selector] and the argument values are defined by
711 /// [arguments].
712 ir.Primitive buildFunctionExpressionInvocation(
713 ir.Primitive functionExpression,
714 Selector selector,
715 List<ir.Definition> arguments) {
716 return _buildInvokeCall(functionExpression, selector, arguments);
717 }
718
668 /// Creates an if-then-else statement with the provided [condition] where the 719 /// Creates an if-then-else statement with the provided [condition] where the
669 /// then and else branches are created through the [buildThenPart] and 720 /// then and else branches are created through the [buildThenPart] and
670 /// [buildElsePart] functions, respectively. 721 /// [buildElsePart] functions, respectively.
671 /// 722 ///
672 /// An if-then statement is created if [buildElsePart] is a no-op. 723 /// An if-then statement is created if [buildElsePart] is a no-op.
673 // TODO(johnniwinther): Unify implementation with [buildConditional] and 724 // TODO(johnniwinther): Unify implementation with [buildConditional] and
674 // [_buildLogicalOperator]. 725 // [_buildLogicalOperator].
675 void buildIf(ir.Primitive condition, 726 void buildIf(ir.Primitive condition,
676 void buildThenPart(IrBuilder builder), 727 void buildThenPart(IrBuilder builder),
677 void buildElsePart(IrBuilder builder)) { 728 void buildElsePart(IrBuilder builder)) {
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 index = 0; 1454 index = 0;
1404 for (int i = 0; i < environment.length; ++i) { 1455 for (int i = 0; i < environment.length; ++i) {
1405 if (common[i] == null) { 1456 if (common[i] == null) {
1406 environment.index2value[i] = parameters[index++]; 1457 environment.index2value[i] = parameters[index++];
1407 } 1458 }
1408 } 1459 }
1409 1460
1410 return join; 1461 return join;
1411 } 1462 }
1412 } 1463 }
OLDNEW
« no previous file with comments | « pkg/analyzer2dart/test/sexpr_data.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698