OLD | NEW |
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 '../compile_time_constants.dart' show BackendConstantEnvironment; | 7 import '../compile_time_constants.dart' show BackendConstantEnvironment; |
8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; | 10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 final BackendConstantEnvironment constants; | 392 final BackendConstantEnvironment constants; |
393 | 393 |
394 ConstantSystem get constantSystem => constants.constantSystem; | 394 ConstantSystem get constantSystem => constants.constantSystem; |
395 | 395 |
396 /// A stack of collectors for breaks. | 396 /// A stack of collectors for breaks. |
397 final List<JumpCollector> breakCollectors = <JumpCollector>[]; | 397 final List<JumpCollector> breakCollectors = <JumpCollector>[]; |
398 | 398 |
399 /// A stack of collectors for continues. | 399 /// A stack of collectors for continues. |
400 final List<JumpCollector> continueCollectors = <JumpCollector>[]; | 400 final List<JumpCollector> continueCollectors = <JumpCollector>[]; |
401 | 401 |
| 402 final List<ConstDeclaration> localConstants = <ConstDeclaration>[]; |
| 403 |
402 final ExecutableElement currentElement; | 404 final ExecutableElement currentElement; |
403 | 405 |
404 final ir.Continuation returnContinuation = new ir.Continuation.retrn(); | 406 final ir.Continuation returnContinuation = new ir.Continuation.retrn(); |
405 ir.Parameter _thisParameter; | 407 ir.Parameter _thisParameter; |
406 ir.Parameter enclosingMethodThisParameter; | 408 ir.Parameter enclosingMethodThisParameter; |
407 | 409 |
408 final List<ir.Parameter> functionParameters = <ir.Parameter>[]; | 410 final List<ir.Parameter> functionParameters = <ir.Parameter>[]; |
409 | 411 |
410 IrBuilderSharedState(this.constants, this.currentElement); | 412 IrBuilderSharedState(this.constants, this.currentElement); |
411 | 413 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 } | 591 } |
590 | 592 |
591 /// Creates a parameter for [local] and adds it to the current environment. | 593 /// Creates a parameter for [local] and adds it to the current environment. |
592 ir.Parameter createLocalParameter(Local local) { | 594 ir.Parameter createLocalParameter(Local local) { |
593 ir.Parameter parameter = new ir.Parameter(local); | 595 ir.Parameter parameter = new ir.Parameter(local); |
594 _parameters.add(parameter); | 596 _parameters.add(parameter); |
595 environment.extend(local, parameter); | 597 environment.extend(local, parameter); |
596 return parameter; | 598 return parameter; |
597 } | 599 } |
598 | 600 |
| 601 /// Adds the constant [variableElement] to the environment with [value] as its |
| 602 /// constant value. |
| 603 void declareLocalConstant(LocalVariableElement variableElement, |
| 604 ConstantExpression value) { |
| 605 state.localConstants.add(new ConstDeclaration(variableElement, value)); |
| 606 } |
| 607 |
599 /// Plug an expression into the 'hole' in the context being accumulated. The | 608 /// Plug an expression into the 'hole' in the context being accumulated. The |
600 /// empty context (just a hole) is represented by root (and current) being | 609 /// empty context (just a hole) is represented by root (and current) being |
601 /// null. Since the hole in the current context is filled by this function, | 610 /// null. Since the hole in the current context is filled by this function, |
602 /// the new hole must be in the newly added expression---which becomes the | 611 /// the new hole must be in the newly added expression---which becomes the |
603 /// new value of current. | 612 /// new value of current. |
604 void add(ir.Expression expr) { | 613 void add(ir.Expression expr) { |
605 assert(isOpen); | 614 assert(isOpen); |
606 if (_root == null) { | 615 if (_root == null) { |
607 _root = _current = expr; | 616 _root = _current = expr; |
608 } else { | 617 } else { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 ir.Primitive _buildInvokeCall(ir.Primitive target, | 668 ir.Primitive _buildInvokeCall(ir.Primitive target, |
660 CallStructure callStructure, | 669 CallStructure callStructure, |
661 List<ir.Definition> arguments, | 670 List<ir.Definition> arguments, |
662 {SourceInformation sourceInformation}) { | 671 {SourceInformation sourceInformation}) { |
663 Selector selector = callStructure.callSelector; | 672 Selector selector = callStructure.callSelector; |
664 return _buildInvokeDynamic(target, selector, arguments, | 673 return _buildInvokeDynamic(target, selector, arguments, |
665 sourceInformation: sourceInformation); | 674 sourceInformation: sourceInformation); |
666 } | 675 } |
667 | 676 |
668 | 677 |
669 /// Create a [ir.Constant] from [value] and add it to the CPS term. | 678 /// Create a [ir.Constant] from [constant] and add it to the CPS term. |
670 ir.Constant buildConstant(ConstantValue value) { | 679 // TODO(johnniwinther): Remove [value] when [ConstantValue] can be computed |
| 680 // directly from [constant]. |
| 681 ir.Constant buildConstant(ConstantExpression constant, ConstantValue value) { |
671 assert(isOpen); | 682 assert(isOpen); |
672 return addPrimitive(new ir.Constant(value)); | 683 return addPrimitive(new ir.Constant(constant, value)); |
673 } | 684 } |
674 | 685 |
675 /// Create an integer constant and add it to the CPS term. | 686 /// Create an integer constant and add it to the CPS term. |
676 ir.Constant buildIntegerConstant(int value) { | 687 ir.Constant buildIntegerConstant(int value) { |
677 return buildConstant(state.constantSystem.createInt(value)); | 688 return buildConstant( |
| 689 new IntConstantExpression(value), |
| 690 state.constantSystem.createInt(value)); |
678 } | 691 } |
679 | 692 |
680 /// Create a double constant and add it to the CPS term. | 693 /// Create a double constant and add it to the CPS term. |
681 ir.Constant buildDoubleConstant(double value) { | 694 ir.Constant buildDoubleConstant(double value) { |
682 return buildConstant(state.constantSystem.createDouble(value)); | 695 return buildConstant( |
| 696 new DoubleConstantExpression(value), |
| 697 state.constantSystem.createDouble(value)); |
683 } | 698 } |
684 | 699 |
685 /// Create a Boolean constant and add it to the CPS term. | 700 /// Create a Boolean constant and add it to the CPS term. |
686 ir.Constant buildBooleanConstant(bool value) { | 701 ir.Constant buildBooleanConstant(bool value) { |
687 return buildConstant(state.constantSystem.createBool(value)); | 702 return buildConstant( |
| 703 new BoolConstantExpression(value), |
| 704 state.constantSystem.createBool(value)); |
688 } | 705 } |
689 | 706 |
690 /// Create a null constant and add it to the CPS term. | 707 /// Create a null constant and add it to the CPS term. |
691 ir.Constant buildNullConstant() { | 708 ir.Constant buildNullConstant() { |
692 return buildConstant(state.constantSystem.createNull()); | 709 return buildConstant( |
| 710 new NullConstantExpression(), |
| 711 state.constantSystem.createNull()); |
693 } | 712 } |
694 | 713 |
695 /// Create a string constant and add it to the CPS term. | 714 /// Create a string constant and add it to the CPS term. |
696 ir.Constant buildStringConstant(String value) { | 715 ir.Constant buildStringConstant(String value) { |
697 return buildConstant( | 716 return buildConstant( |
| 717 new StringConstantExpression(value), |
698 state.constantSystem.createString(new ast.DartString.literal(value))); | 718 state.constantSystem.createString(new ast.DartString.literal(value))); |
699 } | 719 } |
700 | 720 |
701 /// Create a string constant and add it to the CPS term. | 721 /// Create a string constant and add it to the CPS term. |
702 ir.Constant buildDartStringConstant(ast.DartString value) { | 722 ir.Constant buildDartStringConstant(ast.DartString value) { |
703 return buildConstant(state.constantSystem.createString(value)); | 723 return buildConstant( |
| 724 new StringConstantExpression(value.slowToString()), |
| 725 state.constantSystem.createString(value)); |
704 } | 726 } |
705 | 727 |
706 /// Creates a non-constant list literal of the provided [type] and with the | 728 /// Creates a non-constant list literal of the provided [type] and with the |
707 /// provided [values]. | 729 /// provided [values]. |
708 ir.Primitive buildListLiteral(InterfaceType type, | 730 ir.Primitive buildListLiteral(InterfaceType type, |
709 Iterable<ir.Primitive> values) { | 731 Iterable<ir.Primitive> values) { |
710 assert(isOpen); | 732 assert(isOpen); |
711 return addPrimitive(new ir.LiteralList(type, values.toList())); | 733 return addPrimitive(new ir.LiteralList(type, values.toList())); |
712 } | 734 } |
713 | 735 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 } | 1083 } |
1062 | 1084 |
1063 /// Create a constructor invocation of [element] on [type] where the | 1085 /// Create a constructor invocation of [element] on [type] where the |
1064 /// constructor name and argument structure are defined by [callStructure] and | 1086 /// constructor name and argument structure are defined by [callStructure] and |
1065 /// the argument values are defined by [arguments]. | 1087 /// the argument values are defined by [arguments]. |
1066 ir.Primitive buildConstructorInvocation(FunctionElement element, | 1088 ir.Primitive buildConstructorInvocation(FunctionElement element, |
1067 CallStructure callStructure, | 1089 CallStructure callStructure, |
1068 DartType type, | 1090 DartType type, |
1069 List<ir.Primitive> arguments); | 1091 List<ir.Primitive> arguments); |
1070 | 1092 |
1071 ir.Primitive buildStringify(ir.Primitive argument); | 1093 /// Create a string concatenation of the [arguments]. |
1072 | |
1073 /// Concatenate string values. | |
1074 /// | |
1075 /// The arguments must be strings; usually a call to [buildStringify] is | |
1076 /// needed to ensure the proper conversion takes places. | |
1077 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) { | 1094 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) { |
1078 assert(isOpen); | 1095 assert(isOpen); |
1079 return addPrimitive(new ir.ApplyBuiltinOperator( | 1096 return _continueWithExpression( |
1080 ir.BuiltinOperator.StringConcatenate, | 1097 (k) => new ir.ConcatenateStrings(arguments, k)); |
1081 arguments)); | |
1082 } | 1098 } |
1083 | 1099 |
1084 /// Create an invocation of the `call` method of [functionExpression], where | 1100 /// Create an invocation of the `call` method of [functionExpression], where |
1085 /// the structure of arguments are given by [callStructure]. | 1101 /// the structure of arguments are given by [callStructure]. |
1086 ir.Primitive buildCallInvocation( | 1102 ir.Primitive buildCallInvocation( |
1087 ir.Primitive functionExpression, | 1103 ir.Primitive functionExpression, |
1088 CallStructure callStructure, | 1104 CallStructure callStructure, |
1089 List<ir.Definition> arguments, | 1105 List<ir.Definition> arguments, |
1090 {SourceInformation sourceInformation}) { | 1106 {SourceInformation sourceInformation}) { |
1091 return _buildInvokeCall(functionExpression, callStructure, arguments, | 1107 return _buildInvokeCall(functionExpression, callStructure, arguments, |
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1978 // ! e is translated as e ? false : true | 1994 // ! e is translated as e ? false : true |
1979 | 1995 |
1980 // Add a continuation parameter for the result of the expression. | 1996 // Add a continuation parameter for the result of the expression. |
1981 ir.Parameter resultParameter = new ir.Parameter(null); | 1997 ir.Parameter resultParameter = new ir.Parameter(null); |
1982 | 1998 |
1983 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]); | 1999 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]); |
1984 ir.Continuation thenContinuation = new ir.Continuation([]); | 2000 ir.Continuation thenContinuation = new ir.Continuation([]); |
1985 ir.Continuation elseContinuation = new ir.Continuation([]); | 2001 ir.Continuation elseContinuation = new ir.Continuation([]); |
1986 | 2002 |
1987 ir.Constant makeBoolConstant(bool value) { | 2003 ir.Constant makeBoolConstant(bool value) { |
1988 return new ir.Constant(state.constantSystem.createBool(value)); | 2004 return new ir.Constant( |
| 2005 new BoolConstantExpression(value), |
| 2006 state.constantSystem.createBool(value)); |
1989 } | 2007 } |
1990 | 2008 |
1991 ir.Constant trueConstant = makeBoolConstant(true); | 2009 ir.Constant trueConstant = makeBoolConstant(true); |
1992 ir.Constant falseConstant = makeBoolConstant(false); | 2010 ir.Constant falseConstant = makeBoolConstant(false); |
1993 | 2011 |
1994 thenContinuation.body = new ir.LetPrim(falseConstant) | 2012 thenContinuation.body = new ir.LetPrim(falseConstant) |
1995 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); | 2013 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); |
1996 elseContinuation.body = new ir.LetPrim(trueConstant) | 2014 elseContinuation.body = new ir.LetPrim(trueConstant) |
1997 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); | 2015 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); |
1998 | 2016 |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2531 ir.Primitive condition = _buildCheckNull(receiver); | 2549 ir.Primitive condition = _buildCheckNull(receiver); |
2532 return buildConditional(condition, (_) => receiver, buildSend); | 2550 return buildConditional(condition, (_) => receiver, buildSend); |
2533 } | 2551 } |
2534 | 2552 |
2535 /// Creates a type test checking whether [value] is null. | 2553 /// Creates a type test checking whether [value] is null. |
2536 ir.Primitive _buildCheckNull(ir.Primitive value) { | 2554 ir.Primitive _buildCheckNull(ir.Primitive value) { |
2537 assert(isOpen); | 2555 assert(isOpen); |
2538 ir.Primitive right = buildNullConstant(); | 2556 ir.Primitive right = buildNullConstant(); |
2539 return addPrimitive(new ir.Identical(value, right)); | 2557 return addPrimitive(new ir.Identical(value, right)); |
2540 } | 2558 } |
2541 | |
2542 /// Convert the given value to a string. | |
2543 ir.Primitive buildStringify(ir.Primitive value) { | |
2544 return buildStaticFunctionInvocation( | |
2545 program.stringifyFunction, | |
2546 new CallStructure.unnamed(1), | |
2547 <ir.Primitive>[value]); | |
2548 } | |
2549 } | 2559 } |
2550 | 2560 |
2551 | 2561 |
2552 /// Location of a variable relative to a given closure. | 2562 /// Location of a variable relative to a given closure. |
2553 class ClosureLocation { | 2563 class ClosureLocation { |
2554 /// If not `null`, this location is [box].[field]. | 2564 /// If not `null`, this location is [box].[field]. |
2555 /// The location of [box] can be obtained separately from an | 2565 /// The location of [box] can be obtained separately from an |
2556 /// enclosing [ClosureEnvironment] or [ClosureScope]. | 2566 /// enclosing [ClosureEnvironment] or [ClosureScope]. |
2557 /// If `null`, then the location is [field] on the enclosing function object. | 2567 /// If `null`, then the location is [field] on the enclosing function object. |
2558 final BoxLocal box; | 2568 final BoxLocal box; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2620 } | 2630 } |
2621 | 2631 |
2622 class SwitchCaseInfo { | 2632 class SwitchCaseInfo { |
2623 final List<ir.Primitive> constants = <ir.Primitive>[]; | 2633 final List<ir.Primitive> constants = <ir.Primitive>[]; |
2624 final SubbuildFunction buildBody; | 2634 final SubbuildFunction buildBody; |
2625 | 2635 |
2626 SwitchCaseInfo(this.buildBody); | 2636 SwitchCaseInfo(this.buildBody); |
2627 | 2637 |
2628 void addConstant(ir.Primitive constant) => constants.add(constant); | 2638 void addConstant(ir.Primitive constant) => constants.add(constant); |
2629 } | 2639 } |
OLD | NEW |