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