| 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/values.dart' show ConstantValue, PrimitiveConstantValue; | 9 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 assert(!element.isLocal); | 617 assert(!element.isLocal); |
| 618 assert(!element.isInstanceMember); | 618 assert(!element.isInstanceMember); |
| 619 assert(isOpen); | 619 assert(isOpen); |
| 620 return _continueWithExpression( | 620 return _continueWithExpression( |
| 621 (k) => new ir.InvokeStatic(element, selector, arguments, k, | 621 (k) => new ir.InvokeStatic(element, selector, arguments, k, |
| 622 sourceInformation)); | 622 sourceInformation)); |
| 623 } | 623 } |
| 624 | 624 |
| 625 ir.Primitive _buildInvokeSuper(Element target, | 625 ir.Primitive _buildInvokeSuper(Element target, |
| 626 Selector selector, | 626 Selector selector, |
| 627 List<ir.Primitive> arguments) { | 627 List<ir.Primitive> arguments, |
| 628 SourceInformation sourceInformation) { |
| 628 assert(target.isInstanceMember); | 629 assert(target.isInstanceMember); |
| 629 assert(isOpen); | 630 assert(isOpen); |
| 630 return _continueWithExpression( | 631 return _continueWithExpression( |
| 631 (k) => new ir.InvokeMethodDirectly( | 632 (k) => new ir.InvokeMethodDirectly( |
| 632 buildThis(), target, selector, arguments, k)); | 633 buildThis(), target, selector, arguments, k, sourceInformation)); |
| 633 } | 634 } |
| 634 | 635 |
| 635 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, | 636 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, |
| 636 Selector selector, | 637 Selector selector, |
| 637 TypeMask mask, | 638 TypeMask mask, |
| 638 List<ir.Primitive> arguments, | 639 List<ir.Primitive> arguments, |
| 639 {SourceInformation sourceInformation}) { | 640 {SourceInformation sourceInformation}) { |
| 640 assert(isOpen); | 641 assert(isOpen); |
| 641 return _continueWithExpression( | 642 return _continueWithExpression( |
| 642 (k) => new ir.InvokeMethod(receiver, selector, mask, arguments, k, | 643 (k) => new ir.InvokeMethod(receiver, selector, mask, arguments, k, |
| 643 sourceInformation)); | 644 sourceInformation)); |
| 644 } | 645 } |
| 645 | 646 |
| 646 ir.Primitive _buildInvokeCall(ir.Primitive target, | 647 ir.Primitive _buildInvokeCall(ir.Primitive target, |
| 647 CallStructure callStructure, | 648 CallStructure callStructure, |
| 648 TypeMask mask, | 649 TypeMask mask, |
| 649 List<ir.Definition> arguments, | 650 List<ir.Definition> arguments, |
| 650 {SourceInformation sourceInformation}) { | 651 {SourceInformation sourceInformation}) { |
| 651 Selector selector = callStructure.callSelector; | 652 Selector selector = callStructure.callSelector; |
| 652 return _buildInvokeDynamic(target, selector, mask, arguments, | 653 return _buildInvokeDynamic(target, selector, mask, arguments, |
| 653 sourceInformation: sourceInformation); | 654 sourceInformation: sourceInformation); |
| 654 } | 655 } |
| 655 | 656 |
| 656 | 657 |
| 657 /// Create a [ir.Constant] from [value] and add it to the CPS term. | 658 /// Create a [ir.Constant] from [value] and add it to the CPS term. |
| 658 ir.Constant buildConstant(ConstantValue value) { | 659 ir.Constant buildConstant(ConstantValue value, |
| 660 {SourceInformation sourceInformation}) { |
| 659 assert(isOpen); | 661 assert(isOpen); |
| 660 return addPrimitive(new ir.Constant(value)); | 662 return addPrimitive( |
| 663 new ir.Constant(value, sourceInformation: sourceInformation)); |
| 661 } | 664 } |
| 662 | 665 |
| 663 /// Create an integer constant and add it to the CPS term. | 666 /// Create an integer constant and add it to the CPS term. |
| 664 ir.Constant buildIntegerConstant(int value) { | 667 ir.Constant buildIntegerConstant(int value) { |
| 665 return buildConstant(state.constantSystem.createInt(value)); | 668 return buildConstant(state.constantSystem.createInt(value)); |
| 666 } | 669 } |
| 667 | 670 |
| 668 /// Create a double constant and add it to the CPS term. | 671 /// Create a double constant and add it to the CPS term. |
| 669 ir.Constant buildDoubleConstant(double value) { | 672 ir.Constant buildDoubleConstant(double value) { |
| 670 return buildConstant(state.constantSystem.createDouble(value)); | 673 return buildConstant(state.constantSystem.createDouble(value)); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 state.currentElement, | 789 state.currentElement, |
| 787 state.thisParameter, | 790 state.thisParameter, |
| 788 state.functionParameters, | 791 state.functionParameters, |
| 789 state.returnContinuation, | 792 state.returnContinuation, |
| 790 _root); | 793 _root); |
| 791 } | 794 } |
| 792 | 795 |
| 793 /// Create a invocation of the [method] on the super class where the call | 796 /// Create a invocation of the [method] on the super class where the call |
| 794 /// structure is defined [callStructure] and the argument values are defined | 797 /// structure is defined [callStructure] and the argument values are defined |
| 795 /// by [arguments]. | 798 /// by [arguments]. |
| 796 ir.Primitive buildSuperMethodInvocation(MethodElement method, | 799 ir.Primitive buildSuperMethodInvocation( |
| 797 CallStructure callStructure, | 800 MethodElement method, |
| 798 List<ir.Primitive> arguments) { | 801 CallStructure callStructure, |
| 802 List<ir.Primitive> arguments, |
| 803 {SourceInformation sourceInformation}) { |
| 799 // TODO(johnniwinther): This shouldn't be necessary. | 804 // TODO(johnniwinther): This shouldn't be necessary. |
| 800 SelectorKind kind = Elements.isOperatorName(method.name) | 805 SelectorKind kind = Elements.isOperatorName(method.name) |
| 801 ? SelectorKind.OPERATOR : SelectorKind.CALL; | 806 ? SelectorKind.OPERATOR : SelectorKind.CALL; |
| 802 Selector selector = | 807 Selector selector = |
| 803 new Selector(kind, method.memberName, callStructure); | 808 new Selector(kind, method.memberName, callStructure); |
| 804 return _buildInvokeSuper(method, selector, arguments); | 809 return _buildInvokeSuper(method, selector, arguments, sourceInformation); |
| 805 } | 810 } |
| 806 | 811 |
| 807 /// Create a read access of the [method] on the super class, i.e. a | 812 /// Create a read access of the [method] on the super class, i.e. a |
| 808 /// closurization of [method]. | 813 /// closurization of [method]. |
| 809 ir.Primitive buildSuperMethodGet(MethodElement method) { | 814 ir.Primitive buildSuperMethodGet(MethodElement method, |
| 815 {SourceInformation sourceInformation}) { |
| 810 // TODO(johnniwinther): This should have its own ir node. | 816 // TODO(johnniwinther): This should have its own ir node. |
| 811 return _buildInvokeSuper( | 817 return _buildInvokeSuper( |
| 812 method, | 818 method, |
| 813 new Selector.getter(method.name, method.library), | 819 new Selector.getter(method.name, method.library), |
| 814 const <ir.Primitive>[]); | 820 const <ir.Primitive>[], |
| 821 sourceInformation); |
| 815 } | 822 } |
| 816 | 823 |
| 817 /// Create a getter invocation of the [getter] on the super class. | 824 /// Create a getter invocation of the [getter] on the super class. |
| 818 ir.Primitive buildSuperGetterGet(MethodElement getter) { | 825 ir.Primitive buildSuperGetterGet(MethodElement getter, |
| 826 SourceInformation sourceInformation) { |
| 819 // TODO(johnniwinther): This should have its own ir node. | 827 // TODO(johnniwinther): This should have its own ir node. |
| 820 return _buildInvokeSuper( | 828 return _buildInvokeSuper( |
| 821 getter, | 829 getter, |
| 822 new Selector.getter(getter.name, getter.library), | 830 new Selector.getter(getter.name, getter.library), |
| 823 const <ir.Primitive>[]); | 831 const <ir.Primitive>[], |
| 832 sourceInformation); |
| 824 } | 833 } |
| 825 | 834 |
| 826 /// Create an setter invocation of the [setter] on the super class with | 835 /// Create an setter invocation of the [setter] on the super class with |
| 827 /// [value]. | 836 /// [value]. |
| 828 ir.Primitive buildSuperSetterSet(MethodElement setter, | 837 ir.Primitive buildSuperSetterSet(MethodElement setter, |
| 829 ir.Primitive value) { | 838 ir.Primitive value, |
| 839 {SourceInformation sourceInformation}) { |
| 830 // TODO(johnniwinther): This should have its own ir node. | 840 // TODO(johnniwinther): This should have its own ir node. |
| 831 _buildInvokeSuper( | 841 _buildInvokeSuper( |
| 832 setter, | 842 setter, |
| 833 new Selector.setter(setter.name, setter.library), | 843 new Selector.setter(setter.name, setter.library), |
| 834 <ir.Primitive>[value]); | 844 <ir.Primitive>[value], |
| 845 sourceInformation); |
| 835 return value; | 846 return value; |
| 836 } | 847 } |
| 837 | 848 |
| 838 /// Create an invocation of the index [method] on the super class with | 849 /// Create an invocation of the index [method] on the super class with |
| 839 /// the provided [index]. | 850 /// the provided [index]. |
| 840 ir.Primitive buildSuperIndex(MethodElement method, | 851 ir.Primitive buildSuperIndex(MethodElement method, |
| 841 ir.Primitive index) { | 852 ir.Primitive index, |
| 853 {SourceInformation sourceInformation}) { |
| 842 return _buildInvokeSuper( | 854 return _buildInvokeSuper( |
| 843 method, new Selector.index(), <ir.Primitive>[index]); | 855 method, new Selector.index(), <ir.Primitive>[index], |
| 856 sourceInformation); |
| 844 } | 857 } |
| 845 | 858 |
| 846 /// Create an invocation of the index set [method] on the super class with | 859 /// Create an invocation of the index set [method] on the super class with |
| 847 /// the provided [index] and [value]. | 860 /// the provided [index] and [value]. |
| 848 ir.Primitive buildSuperIndexSet(MethodElement method, | 861 ir.Primitive buildSuperIndexSet(MethodElement method, |
| 849 ir.Primitive index, | 862 ir.Primitive index, |
| 850 ir.Primitive value) { | 863 ir.Primitive value, |
| 864 {SourceInformation sourceInformation}) { |
| 851 _buildInvokeSuper(method, new Selector.indexSet(), | 865 _buildInvokeSuper(method, new Selector.indexSet(), |
| 852 <ir.Primitive>[index, value]); | 866 <ir.Primitive>[index, value], sourceInformation); |
| 853 return value; | 867 return value; |
| 854 } | 868 } |
| 855 | 869 |
| 856 /// Create a dynamic invocation on [receiver] where the method name and | 870 /// Create a dynamic invocation on [receiver] where the method name and |
| 857 /// argument structure are defined by [selector] and the argument values are | 871 /// argument structure are defined by [selector] and the argument values are |
| 858 /// defined by [arguments]. | 872 /// defined by [arguments]. |
| 859 ir.Primitive buildDynamicInvocation(ir.Primitive receiver, | 873 ir.Primitive buildDynamicInvocation(ir.Primitive receiver, |
| 860 Selector selector, | 874 Selector selector, |
| 861 TypeMask mask, | 875 TypeMask mask, |
| 862 List<ir.Primitive> arguments) { | 876 List<ir.Primitive> arguments, |
| 863 return _buildInvokeDynamic(receiver, selector, mask, arguments); | 877 {SourceInformation sourceInformation}) { |
| 878 return _buildInvokeDynamic( |
| 879 receiver, selector, mask, arguments, |
| 880 sourceInformation: sourceInformation); |
| 864 } | 881 } |
| 865 | 882 |
| 866 /// Create a dynamic getter invocation on [receiver] where the getter name is | 883 /// Create a dynamic getter invocation on [receiver] where the getter name is |
| 867 /// defined by [selector]. | 884 /// defined by [selector]. |
| 868 ir.Primitive buildDynamicGet(ir.Primitive receiver, | 885 ir.Primitive buildDynamicGet(ir.Primitive receiver, |
| 869 Selector selector, | 886 Selector selector, |
| 870 TypeMask mask) { | 887 TypeMask mask) { |
| 871 assert(selector.isGetter); | 888 assert(selector.isGetter); |
| 872 FieldElement field = program.locateSingleField(selector, mask); | 889 FieldElement field = program.locateSingleField(selector, mask); |
| 873 if (field != null) { | 890 if (field != null) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 /// Create a read access of the local [function], i.e. closurization of | 935 /// Create a read access of the local [function], i.e. closurization of |
| 919 /// [function]. | 936 /// [function]. |
| 920 ir.Primitive buildLocalFunctionGet(LocalFunctionElement function) { | 937 ir.Primitive buildLocalFunctionGet(LocalFunctionElement function) { |
| 921 // TODO(johnniwinther): Separate function access from variable access. | 938 // TODO(johnniwinther): Separate function access from variable access. |
| 922 return _buildLocalGet(function); | 939 return _buildLocalGet(function); |
| 923 } | 940 } |
| 924 | 941 |
| 925 /// Create an invocation of the the [local] variable or parameter where | 942 /// Create an invocation of the the [local] variable or parameter where |
| 926 /// argument structure is defined by [callStructure] and the argument values | 943 /// argument structure is defined by [callStructure] and the argument values |
| 927 /// are defined by [arguments]. | 944 /// are defined by [arguments]. |
| 928 ir.Primitive buildLocalVariableInvocation(LocalVariableElement local, | 945 ir.Primitive buildLocalVariableInvocation( |
| 929 CallStructure callStructure, | 946 LocalVariableElement local, |
| 930 List<ir.Primitive> arguments) { | 947 CallStructure callStructure, |
| 948 List<ir.Primitive> arguments, |
| 949 {SourceInformation callSourceInformation}) { |
| 931 return buildCallInvocation( | 950 return buildCallInvocation( |
| 932 buildLocalVariableGet(local), callStructure, arguments); | 951 buildLocalVariableGet(local), callStructure, arguments, |
| 952 sourceInformation: callSourceInformation); |
| 933 } | 953 } |
| 934 | 954 |
| 935 /// Create an invocation of the local [function] where argument structure is | 955 /// Create an invocation of the local [function] where argument structure is |
| 936 /// defined by [callStructure] and the argument values are defined by | 956 /// defined by [callStructure] and the argument values are defined by |
| 937 /// [arguments]. | 957 /// [arguments]. |
| 938 ir.Primitive buildLocalFunctionInvocation( | 958 ir.Primitive buildLocalFunctionInvocation( |
| 939 LocalFunctionElement function, | 959 LocalFunctionElement function, |
| 940 CallStructure callStructure, | 960 CallStructure callStructure, |
| 941 List<ir.Primitive> arguments) { | 961 List<ir.Primitive> arguments, |
| 962 SourceInformation sourceInformation) { |
| 942 // TODO(johnniwinther): Maybe this should have its own ir node. | 963 // TODO(johnniwinther): Maybe this should have its own ir node. |
| 943 return buildCallInvocation( | 964 return buildCallInvocation( |
| 944 buildLocalFunctionGet(function), callStructure, arguments); | 965 buildLocalFunctionGet(function), callStructure, arguments, |
| 966 sourceInformation: sourceInformation); |
| 945 } | 967 } |
| 946 | 968 |
| 947 /// Create a static invocation of [function] where argument structure is | 969 /// Create a static invocation of [function] where argument structure is |
| 948 /// defined by [callStructure] and the argument values are defined by | 970 /// defined by [callStructure] and the argument values are defined by |
| 949 /// [arguments]. | 971 /// [arguments]. |
| 950 ir.Primitive buildStaticFunctionInvocation( | 972 ir.Primitive buildStaticFunctionInvocation( |
| 951 MethodElement function, | 973 MethodElement function, |
| 952 CallStructure callStructure, | 974 CallStructure callStructure, |
| 953 List<ir.Primitive> arguments, | 975 List<ir.Primitive> arguments, |
| 954 {SourceInformation sourceInformation}) { | 976 {SourceInformation sourceInformation}) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 967 /// Create a read access of a static [field] that might not have been | 989 /// Create a read access of a static [field] that might not have been |
| 968 /// initialized yet. | 990 /// initialized yet. |
| 969 ir.Primitive buildStaticFieldLazyGet(FieldElement field, | 991 ir.Primitive buildStaticFieldLazyGet(FieldElement field, |
| 970 SourceInformation sourceInformation) { | 992 SourceInformation sourceInformation) { |
| 971 return _continueWithExpression( | 993 return _continueWithExpression( |
| 972 (k) => new ir.GetLazyStatic(field, k, sourceInformation)); | 994 (k) => new ir.GetLazyStatic(field, k, sourceInformation)); |
| 973 } | 995 } |
| 974 | 996 |
| 975 /// Create a getter invocation of the static [getter]. | 997 /// Create a getter invocation of the static [getter]. |
| 976 ir.Primitive buildStaticGetterGet(MethodElement getter, | 998 ir.Primitive buildStaticGetterGet(MethodElement getter, |
| 977 {SourceInformation sourceInformation}) { | 999 SourceInformation sourceInformation) { |
| 978 Selector selector = new Selector.getter(getter.name, getter.library); | 1000 Selector selector = new Selector.getter(getter.name, getter.library); |
| 979 return _buildInvokeStatic( | 1001 return _buildInvokeStatic( |
| 980 getter, selector, const <ir.Primitive>[], sourceInformation); | 1002 getter, selector, const <ir.Primitive>[], sourceInformation); |
| 981 } | 1003 } |
| 982 | 1004 |
| 983 /// Create a read access of the static [function], i.e. a closurization of | 1005 /// Create a read access of the static [function], i.e. a closurization of |
| 984 /// [function]. | 1006 /// [function]. |
| 985 ir.Primitive buildStaticFunctionGet(MethodElement function, | 1007 ir.Primitive buildStaticFunctionGet(MethodElement function, |
| 986 {SourceInformation sourceInformation}) { | 1008 {SourceInformation sourceInformation}) { |
| 987 return addPrimitive(new ir.GetStatic(function, sourceInformation)); | 1009 return addPrimitive(new ir.GetStatic(function, sourceInformation)); |
| (...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 for (int i = 0; i < newBreaks.length; ++i) { | 1973 for (int i = 0; i < newBreaks.length; ++i) { |
| 1952 addJump(newBreaks[i], savedBreaks[i]); | 1974 addJump(newBreaks[i], savedBreaks[i]); |
| 1953 } | 1975 } |
| 1954 for (int i = 0; i < newContinues.length; ++i) { | 1976 for (int i = 0; i < newContinues.length; ++i) { |
| 1955 addJump(newContinues[i], savedContinues[i]); | 1977 addJump(newContinues[i], savedContinues[i]); |
| 1956 } | 1978 } |
| 1957 if (!newReturn.isEmpty) { | 1979 if (!newReturn.isEmpty) { |
| 1958 IrBuilder builder = makeDelimitedBuilder(newReturn.environment); | 1980 IrBuilder builder = makeDelimitedBuilder(newReturn.environment); |
| 1959 ir.Primitive value = builder.environment.discard(1); | 1981 ir.Primitive value = builder.environment.discard(1); |
| 1960 buildFinallyBlock(builder); | 1982 buildFinallyBlock(builder); |
| 1961 if (builder.isOpen) builder.buildReturn(value); | 1983 if (builder.isOpen) builder.buildReturn(value: value); |
| 1962 newReturn.continuation.body = builder._root; | 1984 newReturn.continuation.body = builder._root; |
| 1963 exits.add(newReturn.continuation); | 1985 exits.add(newReturn.continuation); |
| 1964 } | 1986 } |
| 1965 builder.add(new ir.LetCont.many(exits, body)); | 1987 builder.add(new ir.LetCont.many(exits, body)); |
| 1966 builder.environment = join.environment; | 1988 builder.environment = join.environment; |
| 1967 buildFinallyBlock(builder); | 1989 buildFinallyBlock(builder); |
| 1968 } | 1990 } |
| 1969 | 1991 |
| 1970 _helpBuildTryCatch(variables, enterTry, buildTryBlock, leaveTry, | 1992 _helpBuildTryCatch(variables, enterTry, buildTryBlock, leaveTry, |
| 1971 buildCatch, leaveTryCatch); | 1993 buildCatch, leaveTryCatch); |
| 1972 } | 1994 } |
| 1973 | 1995 |
| 1974 /// Create a return statement `return value;` or `return;` if [value] is | 1996 /// Create a return statement `return value;` or `return;` if [value] is |
| 1975 /// null. | 1997 /// null. |
| 1976 void buildReturn([ir.Primitive value]) { | 1998 void buildReturn({ir.Primitive value, SourceInformation sourceInformation}) { |
| 1977 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] | 1999 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] |
| 1978 // where (C', x) = Build(e, C) | 2000 // where (C', x) = Build(e, C) |
| 1979 // | 2001 // |
| 1980 // Return without a subexpression is translated as if it were return null. | 2002 // Return without a subexpression is translated as if it were return null. |
| 1981 assert(isOpen); | 2003 assert(isOpen); |
| 1982 if (value == null) { | 2004 if (value == null) { |
| 1983 value = buildNullConstant(); | 2005 value = buildNullConstant(); |
| 1984 } | 2006 } |
| 1985 if (state.returnCollector == null) { | 2007 if (state.returnCollector == null) { |
| 1986 add(new ir.InvokeContinuation(state.returnContinuation, [value])); | 2008 add(new ir.InvokeContinuation(state.returnContinuation, [value], |
| 2009 sourceInformation: sourceInformation)); |
| 1987 _current = null; | 2010 _current = null; |
| 1988 } else { | 2011 } else { |
| 1989 // Inside the try block of try/finally, all returns go to a join-point | 2012 // Inside the try block of try/finally, all returns go to a join-point |
| 1990 // continuation that contains the finally code. The return value is | 2013 // continuation that contains the finally code. The return value is |
| 1991 // passed as an extra argument. | 2014 // passed as an extra argument. |
| 1992 jumpTo(state.returnCollector, value); | 2015 jumpTo(state.returnCollector, value); |
| 1993 } | 2016 } |
| 1994 } | 2017 } |
| 1995 | 2018 |
| 1996 /// Create a blocks of [statements] by applying [build] to all reachable | 2019 /// Create a blocks of [statements] by applying [build] to all reachable |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2298 add(new ir.LetMutable(getMutableVariable(variableElement), | 2321 add(new ir.LetMutable(getMutableVariable(variableElement), |
| 2299 initialValue)); | 2322 initialValue)); |
| 2300 } else { | 2323 } else { |
| 2301 initialValue.useElementAsHint(variableElement); | 2324 initialValue.useElementAsHint(variableElement); |
| 2302 environment.extend(variableElement, initialValue); | 2325 environment.extend(variableElement, initialValue); |
| 2303 } | 2326 } |
| 2304 } | 2327 } |
| 2305 | 2328 |
| 2306 /// Add [functionElement] to the environment with provided [definition]. | 2329 /// Add [functionElement] to the environment with provided [definition]. |
| 2307 void declareLocalFunction(LocalFunctionElement functionElement, | 2330 void declareLocalFunction(LocalFunctionElement functionElement, |
| 2308 ClosureClassElement classElement) { | 2331 ClosureClassElement classElement, |
| 2309 ir.Primitive closure = buildFunctionExpression(classElement); | 2332 SourceInformation sourceInformation) { |
| 2333 ir.Primitive closure = |
| 2334 buildFunctionExpression(classElement, sourceInformation); |
| 2310 declareLocalVariable(functionElement, initialValue: closure); | 2335 declareLocalVariable(functionElement, initialValue: closure); |
| 2311 } | 2336 } |
| 2312 | 2337 |
| 2313 ir.Primitive buildFunctionExpression(ClosureClassElement classElement) { | 2338 ir.Primitive buildFunctionExpression(ClosureClassElement classElement, |
| 2339 SourceInformation sourceInformation) { |
| 2314 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2340 List<ir.Primitive> arguments = <ir.Primitive>[]; |
| 2315 for (ClosureFieldElement field in classElement.closureFields) { | 2341 for (ClosureFieldElement field in classElement.closureFields) { |
| 2316 // Captured 'this' is not available as a local in the current environment, | 2342 // Captured 'this' is not available as a local in the current environment, |
| 2317 // so treat that specially. | 2343 // so treat that specially. |
| 2318 ir.Primitive value = field.local is ThisLocal | 2344 ir.Primitive value = field.local is ThisLocal |
| 2319 ? buildThis() | 2345 ? buildThis() |
| 2320 : environment.lookup(field.local); | 2346 : environment.lookup(field.local); |
| 2321 arguments.add(value); | 2347 arguments.add(value); |
| 2322 } | 2348 } |
| 2323 return addPrimitive( | 2349 return addPrimitive(new ir.CreateInstance( |
| 2324 new ir.CreateInstance(classElement, arguments, const <ir.Primitive>[])); | 2350 classElement, arguments, const <ir.Primitive>[], sourceInformation)); |
| 2325 } | 2351 } |
| 2326 | 2352 |
| 2327 /// Create a read access of [local] variable or parameter. | 2353 /// Create a read access of [local] variable or parameter. |
| 2328 ir.Primitive _buildLocalGet(LocalElement local) { | 2354 ir.Primitive _buildLocalGet(LocalElement local) { |
| 2329 assert(isOpen); | 2355 assert(isOpen); |
| 2330 ClosureLocation location = state.boxedVariables[local]; | 2356 ClosureLocation location = state.boxedVariables[local]; |
| 2331 if (location != null) { | 2357 if (location != null) { |
| 2332 ir.Primitive result = new ir.GetField(environment.lookup(location.box), | 2358 ir.Primitive result = new ir.GetField(environment.lookup(location.box), |
| 2333 location.field); | 2359 location.field); |
| 2334 result.useElementAsHint(local); | 2360 result.useElementAsHint(local); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2423 return addPrimitive(new ir.GetField(buildThis(), target)); | 2449 return addPrimitive(new ir.GetField(buildThis(), target)); |
| 2424 } | 2450 } |
| 2425 | 2451 |
| 2426 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { | 2452 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { |
| 2427 add(new ir.SetField(buildThis(), target, value)); | 2453 add(new ir.SetField(buildThis(), target, value)); |
| 2428 return value; | 2454 return value; |
| 2429 } | 2455 } |
| 2430 | 2456 |
| 2431 ir.Primitive buildInvokeDirectly(FunctionElement target, | 2457 ir.Primitive buildInvokeDirectly(FunctionElement target, |
| 2432 ir.Primitive receiver, | 2458 ir.Primitive receiver, |
| 2433 List<ir.Primitive> arguments) { | 2459 List<ir.Primitive> arguments, |
| 2460 {SourceInformation sourceInformation}) { |
| 2434 assert(isOpen); | 2461 assert(isOpen); |
| 2435 Selector selector = | 2462 Selector selector = |
| 2436 new Selector.call(target.name, target.library, arguments.length); | 2463 new Selector.call(target.name, target.library, arguments.length); |
| 2437 return _continueWithExpression( | 2464 return _continueWithExpression( |
| 2438 (k) => new ir.InvokeMethodDirectly( | 2465 (k) => new ir.InvokeMethodDirectly( |
| 2439 receiver, target, selector, arguments, k)); | 2466 receiver, target, selector, arguments, k, sourceInformation)); |
| 2440 } | 2467 } |
| 2441 | 2468 |
| 2442 /// Loads parameters to a constructor body into the environment. | 2469 /// Loads parameters to a constructor body into the environment. |
| 2443 /// | 2470 /// |
| 2444 /// The header for a constructor body differs from other functions in that | 2471 /// The header for a constructor body differs from other functions in that |
| 2445 /// some parameters are already boxed, and the box is passed as an argument | 2472 /// some parameters are already boxed, and the box is passed as an argument |
| 2446 /// instead of being created in the header. | 2473 /// instead of being created in the header. |
| 2447 void buildConstructorBodyHeader(Iterable<Local> parameters, | 2474 void buildConstructorBodyHeader(Iterable<Local> parameters, |
| 2448 ClosureScope closureScope) { | 2475 ClosureScope closureScope) { |
| 2449 _createThisParameter(); | 2476 _createThisParameter(); |
| 2450 for (Local param in parameters) { | 2477 for (Local param in parameters) { |
| 2451 ir.Parameter parameter = _createLocalParameter(param); | 2478 ir.Parameter parameter = _createLocalParameter(param); |
| 2452 state.functionParameters.add(parameter); | 2479 state.functionParameters.add(parameter); |
| 2453 } | 2480 } |
| 2454 if (closureScope != null) { | 2481 if (closureScope != null) { |
| 2455 state.boxedVariables.addAll(closureScope.capturedVariables); | 2482 state.boxedVariables.addAll(closureScope.capturedVariables); |
| 2456 } | 2483 } |
| 2457 } | 2484 } |
| 2458 | 2485 |
| 2459 /// Create a constructor invocation of [element] on [type] where the | 2486 /// Create a constructor invocation of [element] on [type] where the |
| 2460 /// constructor name and argument structure are defined by [callStructure] and | 2487 /// constructor name and argument structure are defined by [callStructure] and |
| 2461 /// the argument values are defined by [arguments]. | 2488 /// the argument values are defined by [arguments]. |
| 2462 ir.Primitive buildConstructorInvocation(ConstructorElement element, | 2489 ir.Primitive buildConstructorInvocation( |
| 2463 CallStructure callStructure, | 2490 ConstructorElement element, |
| 2464 DartType type, | 2491 CallStructure callStructure, |
| 2465 List<ir.Primitive> arguments) { | 2492 DartType type, |
| 2493 List<ir.Primitive> arguments, |
| 2494 SourceInformation sourceInformation) { |
| 2466 assert(isOpen); | 2495 assert(isOpen); |
| 2467 Selector selector = | 2496 Selector selector = |
| 2468 new Selector(SelectorKind.CALL, element.memberName, callStructure); | 2497 new Selector(SelectorKind.CALL, element.memberName, callStructure); |
| 2469 ClassElement cls = element.enclosingClass; | 2498 ClassElement cls = element.enclosingClass; |
| 2470 if (program.requiresRuntimeTypesFor(cls)) { | 2499 if (program.requiresRuntimeTypesFor(cls)) { |
| 2471 InterfaceType interface = type; | 2500 InterfaceType interface = type; |
| 2472 Iterable<ir.Primitive> typeArguments = | 2501 Iterable<ir.Primitive> typeArguments = |
| 2473 interface.typeArguments.map((DartType argument) { | 2502 interface.typeArguments.map((DartType argument) { |
| 2474 return type.treatAsRaw | 2503 return type.treatAsRaw |
| 2475 ? buildNullConstant() | 2504 ? buildNullConstant() |
| 2476 : buildTypeExpression(argument); | 2505 : buildTypeExpression(argument); |
| 2477 }); | 2506 }); |
| 2478 arguments = new List<ir.Primitive>.from(arguments) | 2507 arguments = new List<ir.Primitive>.from(arguments) |
| 2479 ..addAll(typeArguments); | 2508 ..addAll(typeArguments); |
| 2480 } | 2509 } |
| 2481 return _continueWithExpression( | 2510 return _continueWithExpression( |
| 2482 (k) => new ir.InvokeConstructor(type, element, selector, | 2511 (k) => new ir.InvokeConstructor( |
| 2483 arguments, k)); | 2512 type, element, selector, arguments, k, sourceInformation)); |
| 2484 } | 2513 } |
| 2485 | 2514 |
| 2486 ir.Primitive buildTypeExpression(DartType type) { | 2515 ir.Primitive buildTypeExpression(DartType type) { |
| 2487 type = program.unaliasType(type); | 2516 type = program.unaliasType(type); |
| 2488 if (type is TypeVariableType) { | 2517 if (type is TypeVariableType) { |
| 2489 return buildTypeVariableAccess(type); | 2518 return buildTypeVariableAccess(type); |
| 2490 } else if (type is InterfaceType || type is FunctionType) { | 2519 } else if (type is InterfaceType || type is FunctionType) { |
| 2491 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2520 List<ir.Primitive> arguments = <ir.Primitive>[]; |
| 2492 type.forEachTypeVariable((TypeVariableType variable) { | 2521 type.forEachTypeVariable((TypeVariableType variable) { |
| 2493 ir.Primitive value = buildTypeVariableAccess(variable); | 2522 ir.Primitive value = buildTypeVariableAccess(variable); |
| 2494 arguments.add(value); | 2523 arguments.add(value); |
| 2495 }); | 2524 }); |
| 2496 return addPrimitive(new ir.TypeExpression(type, arguments)); | 2525 return addPrimitive(new ir.TypeExpression(type, arguments)); |
| 2497 } else if (type.treatAsDynamic) { | 2526 } else if (type.treatAsDynamic) { |
| 2498 return buildNullConstant(); | 2527 return buildNullConstant(); |
| 2499 } else { | 2528 } else { |
| 2500 // TypedefType can reach here, and possibly other things. | 2529 // TypedefType can reach here, and possibly other things. |
| 2501 throw 'unimplemented translation of type expression $type (${type.kind})'; | 2530 throw 'unimplemented translation of type expression $type (${type.kind})'; |
| 2502 } | 2531 } |
| 2503 } | 2532 } |
| 2504 | 2533 |
| 2505 /// Obtains the internal type representation of the type held in [variable]. | 2534 /// Obtains the internal type representation of the type held in [variable]. |
| 2506 /// | 2535 /// |
| 2507 /// The value of [variable] is taken from the current receiver object, or | 2536 /// The value of [variable] is taken from the current receiver object, or |
| 2508 /// if we are currently building a constructor field initializer, from the | 2537 /// if we are currently building a constructor field initializer, from the |
| 2509 /// corresponding type argument (field initializers are evaluated before the | 2538 /// corresponding type argument (field initializers are evaluated before the |
| 2510 /// receiver object is created). | 2539 /// receiver object is created). |
| 2511 ir.Primitive buildTypeVariableAccess(TypeVariableType variable) { | 2540 ir.Primitive buildTypeVariableAccess(TypeVariableType variable, |
| 2541 {SourceInformation sourceInformation}) { |
| 2512 // If the local exists in the environment, use that. | 2542 // If the local exists in the environment, use that. |
| 2513 // This is put here when we are inside a constructor or field initializer, | 2543 // This is put here when we are inside a constructor or field initializer, |
| 2514 // (or possibly a closure inside one of these). | 2544 // (or possibly a closure inside one of these). |
| 2515 Local local = new TypeVariableLocal(variable, state.currentElement); | 2545 Local local = new TypeVariableLocal(variable, state.currentElement); |
| 2516 if (environment.contains(local)) { | 2546 if (environment.contains(local)) { |
| 2517 return environment.lookup(local); | 2547 return environment.lookup(local); |
| 2518 } | 2548 } |
| 2519 | 2549 |
| 2520 // If the type variable is not in a local, read its value from the | 2550 // If the type variable is not in a local, read its value from the |
| 2521 // receiver object. | 2551 // receiver object. |
| 2522 ir.Primitive target = buildThis(); | 2552 ir.Primitive target = buildThis(); |
| 2523 return addPrimitive(new ir.ReadTypeVariable(variable, target)); | 2553 return addPrimitive( |
| 2554 new ir.ReadTypeVariable(variable, target, sourceInformation)); |
| 2524 } | 2555 } |
| 2525 | 2556 |
| 2526 /// Make the given type variable accessible through the local environment | 2557 /// Make the given type variable accessible through the local environment |
| 2527 /// with the value of [binding]. | 2558 /// with the value of [binding]. |
| 2528 void declareTypeVariable(TypeVariableType variable, DartType binding) { | 2559 void declareTypeVariable(TypeVariableType variable, DartType binding) { |
| 2529 environment.extend( | 2560 environment.extend( |
| 2530 new TypeVariableLocal(variable, state.currentElement), | 2561 new TypeVariableLocal(variable, state.currentElement), |
| 2531 buildTypeExpression(binding)); | 2562 buildTypeExpression(binding)); |
| 2532 } | 2563 } |
| 2533 | 2564 |
| 2534 /// Reifies the value of [variable] on the current receiver object. | 2565 /// Reifies the value of [variable] on the current receiver object. |
| 2535 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { | 2566 ir.Primitive buildReifyTypeVariable(TypeVariableType variable, |
| 2536 ir.Primitive typeArgument = buildTypeVariableAccess(variable); | 2567 SourceInformation sourceInformation) { |
| 2537 return addPrimitive(new ir.ReifyRuntimeType(typeArgument)); | 2568 ir.Primitive typeArgument = |
| 2569 buildTypeVariableAccess(variable, sourceInformation: sourceInformation); |
| 2570 return addPrimitive( |
| 2571 new ir.ReifyRuntimeType(typeArgument, sourceInformation)); |
| 2538 } | 2572 } |
| 2539 | 2573 |
| 2540 ir.Primitive buildInvocationMirror(Selector selector, | 2574 ir.Primitive buildInvocationMirror(Selector selector, |
| 2541 List<ir.Primitive> arguments) { | 2575 List<ir.Primitive> arguments) { |
| 2542 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); | 2576 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); |
| 2543 } | 2577 } |
| 2544 | 2578 |
| 2545 ir.Primitive buildForeignCode(js.Template codeTemplate, | 2579 ir.Primitive buildForeignCode(js.Template codeTemplate, |
| 2546 List<ir.Primitive> arguments, | 2580 List<ir.Primitive> arguments, |
| 2547 NativeBehavior behavior, | 2581 NativeBehavior behavior, |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2722 } | 2756 } |
| 2723 | 2757 |
| 2724 class SwitchCaseInfo { | 2758 class SwitchCaseInfo { |
| 2725 final List<ir.Primitive> constants = <ir.Primitive>[]; | 2759 final List<ir.Primitive> constants = <ir.Primitive>[]; |
| 2726 final SubbuildFunction buildBody; | 2760 final SubbuildFunction buildBody; |
| 2727 | 2761 |
| 2728 SwitchCaseInfo(this.buildBody); | 2762 SwitchCaseInfo(this.buildBody); |
| 2729 | 2763 |
| 2730 void addConstant(ir.Primitive constant) => constants.add(constant); | 2764 void addConstant(ir.Primitive constant) => constants.add(constant); |
| 2731 } | 2765 } |
| OLD | NEW |