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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart

Issue 693803003: Move continueWithExpression to IrBuilder. (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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 // new value of current. 336 // new value of current.
337 void add(ir.Expression expr) { 337 void add(ir.Expression expr) {
338 assert(isOpen); 338 assert(isOpen);
339 if (_root == null) { 339 if (_root == null) {
340 _root = _current = expr; 340 _root = _current = expr;
341 } else { 341 } else {
342 _current = _current.plug(expr); 342 _current = _current.plug(expr);
343 } 343 }
344 } 344 }
345 345
346 ir.Primitive continueWithExpression(ir.Expression build(ir.Continuation k)) { 346 ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) {
347 ir.Parameter v = new ir.Parameter(null); 347 ir.Parameter v = new ir.Parameter(null);
348 ir.Continuation k = new ir.Continuation([v]); 348 ir.Continuation k = new ir.Continuation([v]);
349 ir.Expression expression = build(k); 349 ir.Expression expression = build(k);
350 add(new ir.LetCont(k, expression)); 350 add(new ir.LetCont(k, expression));
351 return v; 351 return v;
352 } 352 }
353 353
354 ir.Primitive _buildInvokeStatic(Element element,
355 Selector selector,
356 List<ir.Definition> arguments) {
357 assert(isOpen);
358 return _continueWithExpression(
359 (k) => new ir.InvokeStatic(element, selector, k, arguments));
360 }
361
362 ir.Primitive _buildInvokeSuper(Selector selector,
363 List<ir.Definition> arguments) {
364 assert(isOpen);
365 return _continueWithExpression(
366 (k) => new ir.InvokeSuperMethod(selector, k, arguments));
367 }
368
369 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver,
370 Selector selector,
371 List<ir.Definition> arguments) {
372 assert(isOpen);
373 return _continueWithExpression(
374 (k) => new ir.InvokeMethod(receiver, selector, k, arguments));
375 }
376
377
354 /// Create a constant literal from [constant]. 378 /// Create a constant literal from [constant].
355 ir.Constant buildConstantLiteral(ConstantExpression constant) { 379 ir.Constant buildConstantLiteral(ConstantExpression constant) {
356 assert(isOpen); 380 assert(isOpen);
357 ir.Constant prim = new ir.Constant(constant); 381 ir.Constant prim = new ir.Constant(constant);
358 add(new ir.LetPrim(prim)); 382 add(new ir.LetPrim(prim));
359 return prim; 383 return prim;
360 } 384 }
361 385
362 // Helper for building primitive literals. 386 // Helper for building primitive literals.
363 ir.Constant _buildPrimitiveConstant(PrimitiveConstantValue constant) { 387 ir.Constant _buildPrimitiveConstant(PrimitiveConstantValue constant) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 new ir.LetCont(elseContinuation, 487 new ir.LetCont(elseContinuation,
464 new ir.Branch(new ir.IsTrue(condition), 488 new ir.Branch(new ir.IsTrue(condition),
465 thenContinuation, 489 thenContinuation,
466 elseContinuation))))); 490 elseContinuation)))));
467 return (thenValue == elseValue) 491 return (thenValue == elseValue)
468 ? thenValue 492 ? thenValue
469 : joinContinuation.parameters.last; 493 : joinContinuation.parameters.last;
470 494
471 } 495 }
472 496
473 /// Create a read access of [local].
474 ir.Primitive buildLocalGet(LocalElement local) {
475 assert(isOpen);
476 if (isClosureVariable(local)) {
477 ir.Primitive result = new ir.GetClosureVariable(local);
478 add(new ir.LetPrim(result));
479 return result;
480 } else {
481 return environment.lookup(local);
482 }
483 }
484
485 /// Create a write access to [local].
486 ir.Primitive buildLocalSet(LocalElement local, ir.Primitive valueToStore) {
487 assert(isOpen);
488 if (isClosureVariable(local)) {
489 add(new ir.SetClosureVariable(local, valueToStore));
490 } else {
491 valueToStore.useElementAsHint(local);
492 environment.update(local, valueToStore);
493 }
494 return valueToStore;
495 }
496
497 /// Create a get access of the static [element].
498 ir.Primitive buildStaticGet(Element element, Selector selector) {
499 assert(isOpen);
500 assert(selector.isGetter);
501 return continueWithExpression(
502 (k) => new ir.InvokeStatic(
503 element, selector, k, const <ir.Definition>[]));
504 }
505
506 /// Create a dynamic get access on [receiver] where the property is defined
507 /// by the getter [selector].
508 ir.Primitive buildDynamicGet(ir.Primitive receiver, Selector selector) {
509 assert(isOpen);
510 assert(selector.isGetter);
511 return continueWithExpression(
512 (k) => new ir.InvokeMethod(
513 receiver, selector, k, const <ir.Definition>[]));
514 }
515
516 /** 497 /**
517 * Add an explicit `return null` for functions that don't have a return 498 * Add an explicit `return null` for functions that don't have a return
518 * statement on each branch. This includes functions with an empty body, 499 * statement on each branch. This includes functions with an empty body,
519 * such as `foo(){ }`. 500 * such as `foo(){ }`.
520 */ 501 */
521 void ensureReturn() { 502 void _ensureReturn() {
522 if (!isOpen) return; 503 if (!isOpen) return;
523 ir.Constant constant = buildNullLiteral(); 504 ir.Constant constant = buildNullLiteral();
524 add(new ir.InvokeContinuation(state.returnContinuation, [constant])); 505 add(new ir.InvokeContinuation(state.returnContinuation, [constant]));
525 _current = null; 506 _current = null;
526 } 507 }
527 508
528 /// Create a [ir.FunctionDefinition] for [element] using [_root] as the body. 509 /// Create a [ir.FunctionDefinition] for [element] using [_root] as the body.
529 /// 510 ///
530 /// Parameters must be created before the construction of the body using 511 /// Parameters must be created before the construction of the body using
531 /// [createParameter]. 512 /// [createParameter].
532 ir.FunctionDefinition buildFunctionDefinition( 513 ir.FunctionDefinition buildFunctionDefinition(
533 FunctionElement element, 514 FunctionElement element,
534 List<ConstantExpression> defaults) { 515 List<ConstantExpression> defaults) {
535 if (!element.isAbstract) { 516 if (!element.isAbstract) {
536 ensureReturn(); 517 _ensureReturn();
537 return new ir.FunctionDefinition( 518 return new ir.FunctionDefinition(
538 element, state.returnContinuation, _parameters, _root, 519 element, state.returnContinuation, _parameters, _root,
539 state.localConstants, defaults); 520 state.localConstants, defaults);
540 } else { 521 } else {
541 assert(invariant(element, _root == null, 522 assert(invariant(element, _root == null,
542 message: "Non-empty body for abstract method $element: $_root")); 523 message: "Non-empty body for abstract method $element: $_root"));
543 assert(invariant(element, state.localConstants.isEmpty, 524 assert(invariant(element, state.localConstants.isEmpty,
544 message: "Local constants for abstract method $element: " 525 message: "Local constants for abstract method $element: "
545 "${state.localConstants}")); 526 "${state.localConstants}"));
546 return new ir.FunctionDefinition.abstract( 527 return new ir.FunctionDefinition.abstract(
547 element, _parameters, defaults); 528 element, _parameters, defaults);
548 } 529 }
549 } 530 }
550 531
551 532
552 /// Create a super invocation with method name and arguments structure defined 533 /// Create a super invocation where the method name and the argument structure
553 /// by [selector] and argument values defined by [arguments]. 534 /// are defined by [selector] and the argument values are defined by
535 /// [arguments].
554 ir.Primitive buildSuperInvocation(Selector selector, 536 ir.Primitive buildSuperInvocation(Selector selector,
555 List<ir.Definition> arguments) { 537 List<ir.Definition> arguments) {
556 assert(isOpen); 538 return _buildInvokeSuper(selector, arguments);
557 return continueWithExpression(
558 (k) => new ir.InvokeSuperMethod(selector, k, arguments));
559
560 } 539 }
561 540
562 /// Create a dynamic invocation on [receiver] with method name and argument 541 /// Create a getter invocation on the super class where the getter name is
563 /// structure defined by [selector] and argument values defined by 542 /// defined by [selector].
564 /// [arguments]. 543 ir.Primitive buildSuperGet(Selector selector) {
544 assert(selector.isGetter);
545 return _buildInvokeSuper(selector, const <ir.Definition>[]);
546 }
547
548 /// Create a setter invocation on the super class where the setter name and
549 /// argument are defined by [selector] and [value], respectively.
550 ir.Primitive buildSuperSet(Selector selector, ir.Primitive value) {
551 assert(selector.isSetter);
552 _buildInvokeSuper(selector, <ir.Definition>[value]);
553 return value;
554 }
555
556 /// Create an index set invocation on the super class with the provided
557 /// [index] and [value].
558 ir.Primitive buildSuperIndexSet(ir.Primitive index,
559 ir.Primitive value) {
560 _buildInvokeSuper(new Selector.indexSet(), <ir.Definition>[index, value]);
561 return value;
562 }
563
564 /// Create a dynamic invocation on [receiver] where the method name and
565 /// argument structure are defined by [selector] and the argument values are
566 /// defined by [arguments].
565 ir.Primitive buildDynamicInvocation(ir.Definition receiver, 567 ir.Primitive buildDynamicInvocation(ir.Definition receiver,
566 Selector selector, 568 Selector selector,
567 List<ir.Definition> arguments) { 569 List<ir.Definition> arguments) {
568 assert(isOpen); 570 return _buildInvokeDynamic(receiver, selector, arguments);
569 return continueWithExpression(
570 (k) => new ir.InvokeMethod(receiver, selector, k, arguments));
571 } 571 }
572 572
573 /// Create a static invocation of [element] with argument structure defined 573 /// Create a dynamic getter invocation on [receiver] where the getter name is
574 /// by [selector] and argument values defined by [arguments]. 574 /// defined by [selector].
575 ir.Primitive buildDynamicGet(ir.Primitive receiver, Selector selector) {
576 assert(selector.isGetter);
577 return _buildInvokeDynamic(receiver, selector, const <ir.Definition>[]);
578 }
579
580 /// Create a dynamic setter invocation on [receiver] where the setter name and
581 /// argument are defined by [selector] and [value], respectively.
582 ir.Primitive buildDynamicSet(ir.Primitive receiver,
583 Selector selector,
584 ir.Primitive value) {
585 assert(selector.isSetter);
586 _buildInvokeDynamic(receiver, selector, <ir.Definition>[value]);
587 return value;
588 }
589
590 /// Create a dynamic index set invocation on [receiver] with the provided
591 /// [index] and [value].
592 ir.Primitive buildDynamicIndexSet(ir.Primitive receiver,
593 ir.Primitive index,
594 ir.Primitive value) {
595 _buildInvokeDynamic(
596 receiver, new Selector.indexSet(), <ir.Definition>[index, value]);
597 return value;
598 }
599
600 /// Create a static invocation of [element] where argument structure is
601 /// defined by [selector] and the argument values are defined by [arguments].
575 ir.Primitive buildStaticInvocation(Element element, 602 ir.Primitive buildStaticInvocation(Element element,
576 Selector selector, 603 Selector selector,
577 List<ir.Definition> arguments) { 604 List<ir.Definition> arguments) {
578 return continueWithExpression( 605 return _buildInvokeStatic(element, selector, arguments);
579 (k) => new ir.InvokeStatic(element, selector, k, arguments));
580 } 606 }
581 607
582 /// Create a constructor invocation of [element] on [type] with argument 608 /// Create a static getter invocation of [element] where the getter name is
583 /// structure defined by [selector] and argument values defined by 609 /// defined by [selector].
584 /// [arguments]. 610 ir.Primitive buildStaticGet(Element element, Selector selector) {
611 assert(selector.isGetter);
612 return _buildInvokeStatic(element, selector, const <ir.Definition>[]);
613 }
614
615 /// Create a static setter invocation of [element] where the setter name and
616 /// argument are defined by [selector] and [value], respectively.
617 ir.Primitive buildStaticSet(Element element,
618 Selector selector,
619 ir.Primitive value) {
620 assert(selector.isSetter);
621 _buildInvokeStatic(element, selector, <ir.Definition>[value]);
622 return value;
623 }
624
625 /// Create a constructor invocation of [element] on [type] where the
626 /// constructor name and argument structure are defined by [selector] and the
627 /// argument values are defined by [arguments].
585 ir.Primitive buildConstructorInvocation(FunctionElement element, 628 ir.Primitive buildConstructorInvocation(FunctionElement element,
586 Selector selector, 629 Selector selector,
587 DartType type, 630 DartType type,
588 List<ir.Definition> arguments) { 631 List<ir.Definition> arguments) {
589 assert(isOpen); 632 assert(isOpen);
590 return continueWithExpression( 633 return _continueWithExpression(
591 (k) => new ir.InvokeConstructor(type, element, selector, k, arguments)); 634 (k) => new ir.InvokeConstructor(type, element, selector, k, arguments));
592 } 635 }
593 636
637 /// Create a string concatenation of the [arguments].
638 ir.Primitive buildStringConcatenation(List<ir.Definition> arguments) {
639 assert(isOpen);
640 return _continueWithExpression(
641 (k) => new ir.ConcatenateStrings(k, arguments));
642 }
643
644 /// Create a read access of [local].
645 ir.Primitive buildLocalGet(LocalElement local) {
646 assert(isOpen);
647 if (isClosureVariable(local)) {
648 ir.Primitive result = new ir.GetClosureVariable(local);
649 add(new ir.LetPrim(result));
650 return result;
651 } else {
652 return environment.lookup(local);
653 }
654 }
655
656 /// Create a write access to [local] with the provided [value].
657 ir.Primitive buildLocalSet(LocalElement local, ir.Primitive value) {
658 assert(isOpen);
659 if (isClosureVariable(local)) {
660 add(new ir.SetClosureVariable(local, value));
661 } else {
662 value.useElementAsHint(local);
663 environment.update(local, value);
664 }
665 return value;
666 }
667
594 /// Creates an if-then-else statement with the provided [condition] where the 668 /// Creates an if-then-else statement with the provided [condition] where the
595 /// then and else branches are created through the [buildThenPart] and 669 /// then and else branches are created through the [buildThenPart] and
596 /// [buildElsePart] functions, respectively. 670 /// [buildElsePart] functions, respectively.
597 /// 671 ///
598 /// An if-then statement is created if [buildElsePart] is a no-op. 672 /// An if-then statement is created if [buildElsePart] is a no-op.
599 // TODO(johnniwinther): Unify implementation with [buildConditional] and 673 // TODO(johnniwinther): Unify implementation with [buildConditional] and
600 // [_buildLogicalOperator]. 674 // [_buildLogicalOperator].
601 void buildIf(ir.Primitive condition, 675 void buildIf(ir.Primitive condition,
602 void buildThenPart(IrBuilder builder), 676 void buildThenPart(IrBuilder builder),
603 void buildElsePart(IrBuilder builder)) { 677 void buildElsePart(IrBuilder builder)) {
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 1061
988 add(new ir.LetCont(joinContinuation, 1062 add(new ir.LetCont(joinContinuation,
989 new ir.LetCont(thenContinuation, 1063 new ir.LetCont(thenContinuation,
990 new ir.LetCont(elseContinuation, 1064 new ir.LetCont(elseContinuation,
991 new ir.Branch(new ir.IsTrue(condition), 1065 new ir.Branch(new ir.IsTrue(condition),
992 thenContinuation, 1066 thenContinuation,
993 elseContinuation))))); 1067 elseContinuation)))));
994 return resultParameter; 1068 return resultParameter;
995 } 1069 }
996 1070
1071 /// Creates a type test or type cast of [receiver] against [type].
1072 ///
1073 /// Set [isTypeTest] to `true` to create a type test and furthermore set
1074 /// [isNotCheck] to `true` to create a negated type test.
1075 ir.Primitive buildTypeOperator(ir.Primitive receiver,
1076 DartType type,
1077 {bool isTypeTest: false,
1078 bool isNotCheck: false}) {
1079 assert(isOpen);
1080 assert(isTypeTest != null);
1081 assert(!isNotCheck || isTypeTest);
1082 ir.Primitive check = _continueWithExpression(
1083 (k) => new ir.TypeOperator(receiver, type, k, isTypeTest: isTypeTest));
1084 return isNotCheck ? buildNegation(check) : check;
1085
1086 }
1087
997 /// Create a lazy and/or expression. [leftValue] is the value of the left 1088 /// Create a lazy and/or expression. [leftValue] is the value of the left
998 /// operand and [buildRightValue] is called to process the value of the right 1089 /// operand and [buildRightValue] is called to process the value of the right
999 /// operand in the context of its own [IrBuilder]. 1090 /// operand in the context of its own [IrBuilder].
1000 ir.Primitive buildLogicalOperator( 1091 ir.Primitive buildLogicalOperator(
1001 ir.Primitive leftValue, 1092 ir.Primitive leftValue,
1002 ir.Primitive buildRightValue(IrBuilder builder), 1093 ir.Primitive buildRightValue(IrBuilder builder),
1003 {bool isLazyOr: false}) { 1094 {bool isLazyOr: false}) {
1004 // e0 && e1 is translated as if e0 ? (e1 == true) : false. 1095 // e0 && e1 is translated as if e0 ? (e1 == true) : false.
1005 // e0 || e1 is translated as if e0 ? true : (e1 == true). 1096 // e0 || e1 is translated as if e0 ? true : (e1 == true).
1006 // The translation must convert both e0 and e1 to booleans and handle 1097 // The translation must convert both e0 and e1 to booleans and handle
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 index = 0; 1268 index = 0;
1178 for (int i = 0; i < environment.length; ++i) { 1269 for (int i = 0; i < environment.length; ++i) {
1179 if (common[i] == null) { 1270 if (common[i] == null) {
1180 environment.index2value[i] = parameters[index++]; 1271 environment.index2value[i] = parameters[index++];
1181 } 1272 }
1182 } 1273 }
1183 1274
1184 return join; 1275 return join;
1185 } 1276 }
1186 } 1277 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698