| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 import 'dart:math' as math; | 5 import 'dart:math' as math; |
| 6 import 'dart:collection' show Queue; | 6 import 'dart:collection' show Queue; |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 9 import '../common/tasks.dart' show CompilerTask; | 9 import '../common/tasks.dart' show CompilerTask; |
| 10 import '../constants/constant_system.dart'; | 10 import '../constants/constant_system.dart'; |
| 11 import '../constants/values.dart'; | 11 import '../constants/values.dart'; |
| 12 import '../common_elements.dart' show CommonElements; | 12 import '../common_elements.dart' show CommonElements; |
| 13 import '../elements/elements.dart' | 13 import '../elements/elements.dart' |
| 14 show AsyncMarker, JumpTarget, LabelDefinition, MethodElement, ResolvedAst; | 14 show AsyncMarker, JumpTarget, LabelDefinition, MethodElement, ResolvedAst; |
| 15 import '../elements/entities.dart'; | 15 import '../elements/entities.dart'; |
| 16 import '../elements/types.dart'; | 16 import '../elements/types.dart'; |
| 17 import '../io/source_information.dart'; | 17 import '../io/source_information.dart'; |
| 18 import '../js/js.dart' as js; | 18 import '../js/js.dart' as js; |
| 19 import '../js_backend/backend_helpers.dart' show BackendHelpers; | |
| 20 import '../js_backend/interceptor_data.dart'; | 19 import '../js_backend/interceptor_data.dart'; |
| 21 import '../js_backend/js_backend.dart'; | 20 import '../js_backend/js_backend.dart'; |
| 22 import '../js_backend/native_data.dart'; | 21 import '../js_backend/native_data.dart'; |
| 23 import '../js_emitter/code_emitter_task.dart'; | 22 import '../js_emitter/code_emitter_task.dart'; |
| 24 import '../native/native.dart' as native; | 23 import '../native/native.dart' as native; |
| 25 import '../options.dart'; | 24 import '../options.dart'; |
| 26 import '../types/types.dart'; | 25 import '../types/types.dart'; |
| 27 import '../universe/call_structure.dart' show CallStructure; | 26 import '../universe/call_structure.dart' show CallStructure; |
| 28 import '../universe/selector.dart' show Selector; | 27 import '../universe/selector.dart' show Selector; |
| 29 import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse; | 28 import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { | 72 CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { |
| 74 return measure(() { | 73 return measure(() { |
| 75 backend.tracer.traceGraph("codegen", graph); | 74 backend.tracer.traceGraph("codegen", graph); |
| 76 SourceInformation sourceInformation = sourceInformationFactory | 75 SourceInformation sourceInformation = sourceInformationFactory |
| 77 .createBuilderForContext(work.resolvedAst) | 76 .createBuilderForContext(work.resolvedAst) |
| 78 .buildDeclaration(work.resolvedAst); | 77 .buildDeclaration(work.resolvedAst); |
| 79 SsaCodeGenerator codegen = new SsaCodeGenerator( | 78 SsaCodeGenerator codegen = new SsaCodeGenerator( |
| 80 backend.compiler.options, | 79 backend.compiler.options, |
| 81 backend.emitter, | 80 backend.emitter, |
| 82 backend.nativeCodegenEnqueuer, | 81 backend.nativeCodegenEnqueuer, |
| 83 backend.helpers, | |
| 84 backend.checkedModeHelpers, | 82 backend.checkedModeHelpers, |
| 85 backend.nativeData, | 83 backend.nativeData, |
| 86 backend.interceptorData, | 84 backend.interceptorData, |
| 87 backend.oneShotInterceptorData, | 85 backend.oneShotInterceptorData, |
| 88 backend.rtiSubstitutions, | 86 backend.rtiSubstitutions, |
| 89 backend.rtiEncoder, | 87 backend.rtiEncoder, |
| 90 backend.namer, | 88 backend.namer, |
| 91 backend.superMemberData, | 89 backend.superMemberData, |
| 92 closedWorld, | 90 closedWorld, |
| 93 work); | 91 work); |
| 94 codegen.visitGraph(graph); | 92 codegen.visitGraph(graph); |
| 95 return new js.Fun(codegen.parameters, codegen.body) | 93 return new js.Fun(codegen.parameters, codegen.body) |
| 96 .withSourceInformation(sourceInformation); | 94 .withSourceInformation(sourceInformation); |
| 97 }); | 95 }); |
| 98 } | 96 } |
| 99 | 97 |
| 100 js.Expression generateMethod( | 98 js.Expression generateMethod( |
| 101 CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { | 99 CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { |
| 102 return measure(() { | 100 return measure(() { |
| 103 MethodElement element = work.element; | 101 MethodElement element = work.element; |
| 104 if (element.asyncMarker != AsyncMarker.SYNC) { | 102 if (element.asyncMarker != AsyncMarker.SYNC) { |
| 105 work.registry.registerAsyncMarker(element.asyncMarker); | 103 work.registry.registerAsyncMarker(element.asyncMarker); |
| 106 } | 104 } |
| 107 SsaCodeGenerator codegen = new SsaCodeGenerator( | 105 SsaCodeGenerator codegen = new SsaCodeGenerator( |
| 108 backend.compiler.options, | 106 backend.compiler.options, |
| 109 backend.emitter, | 107 backend.emitter, |
| 110 backend.nativeCodegenEnqueuer, | 108 backend.nativeCodegenEnqueuer, |
| 111 backend.helpers, | |
| 112 backend.checkedModeHelpers, | 109 backend.checkedModeHelpers, |
| 113 backend.nativeData, | 110 backend.nativeData, |
| 114 backend.interceptorData, | 111 backend.interceptorData, |
| 115 backend.oneShotInterceptorData, | 112 backend.oneShotInterceptorData, |
| 116 backend.rtiSubstitutions, | 113 backend.rtiSubstitutions, |
| 117 backend.rtiEncoder, | 114 backend.rtiEncoder, |
| 118 backend.namer, | 115 backend.namer, |
| 119 backend.superMemberData, | 116 backend.superMemberData, |
| 120 closedWorld, | 117 closedWorld, |
| 121 work); | 118 work); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 148 | 145 |
| 149 /** | 146 /** |
| 150 * Whether we are currently generating expressions instead of statements. | 147 * Whether we are currently generating expressions instead of statements. |
| 151 * This includes declarations, which are generated as expressions. | 148 * This includes declarations, which are generated as expressions. |
| 152 */ | 149 */ |
| 153 bool isGeneratingExpression = false; | 150 bool isGeneratingExpression = false; |
| 154 | 151 |
| 155 final CompilerOptions _options; | 152 final CompilerOptions _options; |
| 156 final CodeEmitterTask _emitter; | 153 final CodeEmitterTask _emitter; |
| 157 final native.NativeCodegenEnqueuer _nativeEnqueuer; | 154 final native.NativeCodegenEnqueuer _nativeEnqueuer; |
| 158 final BackendHelpers _helpers; | |
| 159 final CheckedModeHelpers _checkedModeHelpers; | 155 final CheckedModeHelpers _checkedModeHelpers; |
| 160 final NativeData _nativeData; | 156 final NativeData _nativeData; |
| 161 final InterceptorData _interceptorData; | 157 final InterceptorData _interceptorData; |
| 162 final OneShotInterceptorData _oneShotInterceptorData; | 158 final OneShotInterceptorData _oneShotInterceptorData; |
| 163 final RuntimeTypesSubstitutions _rtiSubstitutions; | 159 final RuntimeTypesSubstitutions _rtiSubstitutions; |
| 164 final RuntimeTypesEncoder _rtiEncoder; | 160 final RuntimeTypesEncoder _rtiEncoder; |
| 165 final Namer _namer; | 161 final Namer _namer; |
| 166 final SuperMemberData _superMemberData; | 162 final SuperMemberData _superMemberData; |
| 167 final ClosedWorld _closedWorld; | 163 final ClosedWorld _closedWorld; |
| 168 final CodegenWorkItem _work; | 164 final CodegenWorkItem _work; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 // if branches. | 203 // if branches. |
| 208 SubGraph subGraph; | 204 SubGraph subGraph; |
| 209 | 205 |
| 210 // Pending blocks than need to be visited as part of current subgraph. | 206 // Pending blocks than need to be visited as part of current subgraph. |
| 211 Queue<HBasicBlock> blockQueue; | 207 Queue<HBasicBlock> blockQueue; |
| 212 | 208 |
| 213 SsaCodeGenerator( | 209 SsaCodeGenerator( |
| 214 this._options, | 210 this._options, |
| 215 this._emitter, | 211 this._emitter, |
| 216 this._nativeEnqueuer, | 212 this._nativeEnqueuer, |
| 217 this._helpers, | |
| 218 this._checkedModeHelpers, | 213 this._checkedModeHelpers, |
| 219 this._nativeData, | 214 this._nativeData, |
| 220 this._interceptorData, | 215 this._interceptorData, |
| 221 this._oneShotInterceptorData, | 216 this._oneShotInterceptorData, |
| 222 this._rtiSubstitutions, | 217 this._rtiSubstitutions, |
| 223 this._rtiEncoder, | 218 this._rtiEncoder, |
| 224 this._namer, | 219 this._namer, |
| 225 this._superMemberData, | 220 this._superMemberData, |
| 226 this._closedWorld, | 221 this._closedWorld, |
| 227 this._work, | 222 this._work, |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 js.Block body = generateStatementsInNewBlock(info.body); | 835 js.Block body = generateStatementsInNewBlock(info.body); |
| 841 js.Catch catchPart = null; | 836 js.Catch catchPart = null; |
| 842 js.Block finallyPart = null; | 837 js.Block finallyPart = null; |
| 843 if (info.catchBlock != null) { | 838 if (info.catchBlock != null) { |
| 844 void register(ClassEntity classElement) { | 839 void register(ClassEntity classElement) { |
| 845 if (classElement != null) { | 840 if (classElement != null) { |
| 846 _registry.registerInstantiatedClass(classElement); | 841 _registry.registerInstantiatedClass(classElement); |
| 847 } | 842 } |
| 848 } | 843 } |
| 849 | 844 |
| 850 register(_helpers.jsPlainJavaScriptObjectClass); | 845 register(_commonElements.jsPlainJavaScriptObjectClass); |
| 851 register(_helpers.jsUnknownJavaScriptObjectClass); | 846 register(_commonElements.jsUnknownJavaScriptObjectClass); |
| 852 | 847 |
| 853 HLocalValue exception = info.catchVariable; | 848 HLocalValue exception = info.catchVariable; |
| 854 String name = variableNames.getName(exception); | 849 String name = variableNames.getName(exception); |
| 855 js.VariableDeclaration decl = new js.VariableDeclaration(name); | 850 js.VariableDeclaration decl = new js.VariableDeclaration(name); |
| 856 js.Block catchBlock = generateStatementsInNewBlock(info.catchBlock); | 851 js.Block catchBlock = generateStatementsInNewBlock(info.catchBlock); |
| 857 catchPart = new js.Catch(decl, catchBlock); | 852 catchPart = new js.Catch(decl, catchBlock); |
| 858 } | 853 } |
| 859 if (info.finallyBlock != null) { | 854 if (info.finallyBlock != null) { |
| 860 finallyPart = generateStatementsInNewBlock(info.finallyBlock); | 855 finallyPart = generateStatementsInNewBlock(info.finallyBlock); |
| 861 } | 856 } |
| (...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1683 use(node.receiver); | 1678 use(node.receiver); |
| 1684 js.Expression receiverExpression = pop(); | 1679 js.Expression receiverExpression = pop(); |
| 1685 use(node.conditionalConstantInterceptor); | 1680 use(node.conditionalConstantInterceptor); |
| 1686 js.Expression constant = pop(); | 1681 js.Expression constant = pop(); |
| 1687 push(js.js('# && #', [receiverExpression, constant])); | 1682 push(js.js('# && #', [receiverExpression, constant])); |
| 1688 } else { | 1683 } else { |
| 1689 assert(node.inputs.length == 1); | 1684 assert(node.inputs.length == 1); |
| 1690 _registry.registerSpecializedGetInterceptor(node.interceptedClasses); | 1685 _registry.registerSpecializedGetInterceptor(node.interceptedClasses); |
| 1691 js.Name name = _namer.nameForGetInterceptor(node.interceptedClasses); | 1686 js.Name name = _namer.nameForGetInterceptor(node.interceptedClasses); |
| 1692 var isolate = new js.VariableUse( | 1687 var isolate = new js.VariableUse( |
| 1693 _namer.globalObjectForLibrary(_helpers.interceptorsLibrary)); | 1688 _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary)); |
| 1694 use(node.receiver); | 1689 use(node.receiver); |
| 1695 List<js.Expression> arguments = <js.Expression>[pop()]; | 1690 List<js.Expression> arguments = <js.Expression>[pop()]; |
| 1696 push(js | 1691 push(js |
| 1697 .propertyCall(isolate, name, arguments) | 1692 .propertyCall(isolate, name, arguments) |
| 1698 .withSourceInformation(node.sourceInformation)); | 1693 .withSourceInformation(node.sourceInformation)); |
| 1699 _registry.registerUseInterceptor(); | 1694 _registry.registerUseInterceptor(); |
| 1700 } | 1695 } |
| 1701 } | 1696 } |
| 1702 | 1697 |
| 1703 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 1698 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 1704 use(node.receiver); | 1699 use(node.receiver); |
| 1705 js.Expression object = pop(); | 1700 js.Expression object = pop(); |
| 1706 String methodName; | 1701 String methodName; |
| 1707 List<js.Expression> arguments = visitArguments(node.inputs); | 1702 List<js.Expression> arguments = visitArguments(node.inputs); |
| 1708 MemberEntity target = node.element; | 1703 MemberEntity target = node.element; |
| 1709 | 1704 |
| 1710 // TODO(herhut): The namer should return the appropriate backendname here. | 1705 // TODO(herhut): The namer should return the appropriate backendname here. |
| 1711 if (target != null && !node.isInterceptedCall) { | 1706 if (target != null && !node.isInterceptedCall) { |
| 1712 if (target == _helpers.jsArrayAdd) { | 1707 if (target == _commonElements.jsArrayAdd) { |
| 1713 methodName = 'push'; | 1708 methodName = 'push'; |
| 1714 } else if (target == _helpers.jsArrayRemoveLast) { | 1709 } else if (target == _commonElements.jsArrayRemoveLast) { |
| 1715 methodName = 'pop'; | 1710 methodName = 'pop'; |
| 1716 } else if (target == _helpers.jsStringSplit) { | 1711 } else if (target == _commonElements.jsStringSplit) { |
| 1717 methodName = 'split'; | 1712 methodName = 'split'; |
| 1718 // Split returns a List, so we make sure the backend knows the | 1713 // Split returns a List, so we make sure the backend knows the |
| 1719 // list class is instantiated. | 1714 // list class is instantiated. |
| 1720 _registry.registerInstantiatedClass(_commonElements.listClass); | 1715 _registry.registerInstantiatedClass(_commonElements.listClass); |
| 1721 } else if (_nativeData.isNativeMember(target) && | 1716 } else if (_nativeData.isNativeMember(target) && |
| 1722 target.isFunction && | 1717 target.isFunction && |
| 1723 !node.isInterceptedCall) { | 1718 !node.isInterceptedCall) { |
| 1724 // A direct (i.e. non-interceptor) native call is the result of | 1719 // A direct (i.e. non-interceptor) native call is the result of |
| 1725 // optimization. The optimization ensures any type checks or | 1720 // optimization. The optimization ensures any type checks or |
| 1726 // conversions have been satisified. | 1721 // conversions have been satisified. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1748 push(js | 1743 push(js |
| 1749 .propertyCall(object, methodName, arguments) | 1744 .propertyCall(object, methodName, arguments) |
| 1750 .withSourceInformation(node.sourceInformation)); | 1745 .withSourceInformation(node.sourceInformation)); |
| 1751 _registry.registerStaticUse(new StaticUse.constructorBodyInvoke( | 1746 _registry.registerStaticUse(new StaticUse.constructorBodyInvoke( |
| 1752 node.element, new CallStructure.unnamed(arguments.length))); | 1747 node.element, new CallStructure.unnamed(arguments.length))); |
| 1753 } | 1748 } |
| 1754 | 1749 |
| 1755 void visitOneShotInterceptor(HOneShotInterceptor node) { | 1750 void visitOneShotInterceptor(HOneShotInterceptor node) { |
| 1756 List<js.Expression> arguments = visitArguments(node.inputs); | 1751 List<js.Expression> arguments = visitArguments(node.inputs); |
| 1757 var isolate = new js.VariableUse( | 1752 var isolate = new js.VariableUse( |
| 1758 _namer.globalObjectForLibrary(_helpers.interceptorsLibrary)); | 1753 _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary)); |
| 1759 Selector selector = node.selector; | 1754 Selector selector = node.selector; |
| 1760 js.Name methodName = | 1755 js.Name methodName = |
| 1761 _oneShotInterceptorData.registerOneShotInterceptor(selector, _namer); | 1756 _oneShotInterceptorData.registerOneShotInterceptor(selector, _namer); |
| 1762 push(js | 1757 push(js |
| 1763 .propertyCall(isolate, methodName, arguments) | 1758 .propertyCall(isolate, methodName, arguments) |
| 1764 .withSourceInformation(node.sourceInformation)); | 1759 .withSourceInformation(node.sourceInformation)); |
| 1765 if (selector.isGetter) { | 1760 if (selector.isGetter) { |
| 1766 registerGetter(node); | 1761 registerGetter(node); |
| 1767 } else if (selector.isSetter) { | 1762 } else if (selector.isSetter) { |
| 1768 registerSetter(node); | 1763 registerSetter(node); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 List<DartType> instantiatedTypes = node.instantiatedTypes; | 1883 List<DartType> instantiatedTypes = node.instantiatedTypes; |
| 1889 | 1884 |
| 1890 if (instantiatedTypes != null && !instantiatedTypes.isEmpty) { | 1885 if (instantiatedTypes != null && !instantiatedTypes.isEmpty) { |
| 1891 instantiatedTypes.forEach((type) { | 1886 instantiatedTypes.forEach((type) { |
| 1892 _registry.registerInstantiation(type); | 1887 _registry.registerInstantiation(type); |
| 1893 }); | 1888 }); |
| 1894 } | 1889 } |
| 1895 | 1890 |
| 1896 List<js.Expression> arguments = visitArguments(node.inputs, start: 0); | 1891 List<js.Expression> arguments = visitArguments(node.inputs, start: 0); |
| 1897 | 1892 |
| 1898 if (element == _helpers.checkConcurrentModificationError) { | 1893 if (element == _commonElements.checkConcurrentModificationError) { |
| 1899 // Manually inline the [checkConcurrentModificationError] function. This | 1894 // Manually inline the [checkConcurrentModificationError] function. This |
| 1900 // function is only called from a for-loop update. Ideally we would just | 1895 // function is only called from a for-loop update. Ideally we would just |
| 1901 // generate the conditionalcontrol flow in the builder but it adds basic | 1896 // generate the conditionalcontrol flow in the builder but it adds basic |
| 1902 // blocks in the loop update that interfere with other optimizations and | 1897 // blocks in the loop update that interfere with other optimizations and |
| 1903 // confuses loop recognition. | 1898 // confuses loop recognition. |
| 1904 | 1899 |
| 1905 assert(arguments.length == 2); | 1900 assert(arguments.length == 2); |
| 1906 FunctionEntity throwFunction = _helpers.throwConcurrentModificationError; | 1901 FunctionEntity throwFunction = |
| 1902 _commonElements.throwConcurrentModificationError; |
| 1907 _registry.registerStaticUse( | 1903 _registry.registerStaticUse( |
| 1908 new StaticUse.staticInvoke(throwFunction, CallStructure.ONE_ARG)); | 1904 new StaticUse.staticInvoke(throwFunction, CallStructure.ONE_ARG)); |
| 1909 | 1905 |
| 1910 // Calling using `(0, #)(#)` instead of `#(#)` separates the property load | 1906 // Calling using `(0, #)(#)` instead of `#(#)` separates the property load |
| 1911 // of the static function access from the call. For some reason this | 1907 // of the static function access from the call. For some reason this |
| 1912 // helps V8 see that the call never happens so V8 makes the call a | 1908 // helps V8 see that the call never happens so V8 makes the call a |
| 1913 // deoptimization. This removes the call from the optimized loop, making | 1909 // deoptimization. This removes the call from the optimized loop, making |
| 1914 // more optimizations available to the loop. This form is 50% faster on | 1910 // more optimizations available to the loop. This form is 50% faster on |
| 1915 // some small loop, almost as fast as loops with no concurrent | 1911 // some small loop, almost as fast as loops with no concurrent |
| 1916 // modification check. | 1912 // modification check. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 } | 1947 } |
| 1952 } else { | 1948 } else { |
| 1953 Selector selector = node.selector; | 1949 Selector selector = node.selector; |
| 1954 if (!_superMemberData.maybeRegisterAliasedSuperMember( | 1950 if (!_superMemberData.maybeRegisterAliasedSuperMember( |
| 1955 superElement, selector)) { | 1951 superElement, selector)) { |
| 1956 js.Name methodName; | 1952 js.Name methodName; |
| 1957 if (selector.isGetter && !superElement.isGetter) { | 1953 if (selector.isGetter && !superElement.isGetter) { |
| 1958 // If this is a tear-off, register the fact that a tear-off closure | 1954 // If this is a tear-off, register the fact that a tear-off closure |
| 1959 // will be created, and that this tear-off must bypass ordinary | 1955 // will be created, and that this tear-off must bypass ordinary |
| 1960 // dispatch to ensure the super method is invoked. | 1956 // dispatch to ensure the super method is invoked. |
| 1961 FunctionEntity helper = _helpers.closureFromTearOff; | 1957 FunctionEntity helper = _commonElements.closureFromTearOff; |
| 1962 _registry.registerStaticUse(new StaticUse.staticInvoke( | 1958 _registry.registerStaticUse(new StaticUse.staticInvoke( |
| 1963 helper, new CallStructure.unnamed(node.inputs.length))); | 1959 helper, new CallStructure.unnamed(node.inputs.length))); |
| 1964 _registry.registerStaticUse(new StaticUse.superTearOff(node.element)); | 1960 _registry.registerStaticUse(new StaticUse.superTearOff(node.element)); |
| 1965 methodName = _namer.invocationName(selector); | 1961 methodName = _namer.invocationName(selector); |
| 1966 } else { | 1962 } else { |
| 1967 methodName = _namer.instanceMethodName(superElement); | 1963 methodName = _namer.instanceMethodName(superElement); |
| 1968 } | 1964 } |
| 1969 _registry.registerStaticUse(new StaticUse.superInvoke( | 1965 _registry.registerStaticUse(new StaticUse.superInvoke( |
| 1970 superElement, new CallStructure.unnamed(node.inputs.length))); | 1966 superElement, new CallStructure.unnamed(node.inputs.length))); |
| 1971 push(js.js('#.#.call(#)', [ | 1967 push(js.js('#.#.call(#)', [ |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 visitThis(HThis node) { | 2262 visitThis(HThis node) { |
| 2267 push(new js.This()); | 2263 push(new js.This()); |
| 2268 } | 2264 } |
| 2269 | 2265 |
| 2270 visitThrow(HThrow node) { | 2266 visitThrow(HThrow node) { |
| 2271 if (node.isRethrow) { | 2267 if (node.isRethrow) { |
| 2272 use(node.inputs[0]); | 2268 use(node.inputs[0]); |
| 2273 pushStatement( | 2269 pushStatement( |
| 2274 new js.Throw(pop()).withSourceInformation(node.sourceInformation)); | 2270 new js.Throw(pop()).withSourceInformation(node.sourceInformation)); |
| 2275 } else { | 2271 } else { |
| 2276 generateThrowWithHelper(_helpers.wrapExceptionHelper, node.inputs[0], | 2272 generateThrowWithHelper( |
| 2273 _commonElements.wrapExceptionHelper, node.inputs[0], |
| 2277 sourceInformation: node.sourceInformation); | 2274 sourceInformation: node.sourceInformation); |
| 2278 } | 2275 } |
| 2279 } | 2276 } |
| 2280 | 2277 |
| 2281 visitAwait(HAwait node) { | 2278 visitAwait(HAwait node) { |
| 2282 use(node.inputs[0]); | 2279 use(node.inputs[0]); |
| 2283 push(new js.Await(pop()).withSourceInformation(node.sourceInformation)); | 2280 push(new js.Await(pop()).withSourceInformation(node.sourceInformation)); |
| 2284 } | 2281 } |
| 2285 | 2282 |
| 2286 visitYield(HYield node) { | 2283 visitYield(HYield node) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 use(node.length); | 2321 use(node.length); |
| 2325 over = new js.Binary(">=", jsIndex, pop()); | 2322 over = new js.Binary(">=", jsIndex, pop()); |
| 2326 } | 2323 } |
| 2327 assert(over != null || under != null); | 2324 assert(over != null || under != null); |
| 2328 js.Expression underOver = under == null | 2325 js.Expression underOver = under == null |
| 2329 ? over | 2326 ? over |
| 2330 : over == null ? under : new js.Binary("||", under, over); | 2327 : over == null ? under : new js.Binary("||", under, over); |
| 2331 js.Statement thenBody = new js.Block.empty(); | 2328 js.Statement thenBody = new js.Block.empty(); |
| 2332 js.Block oldContainer = currentContainer; | 2329 js.Block oldContainer = currentContainer; |
| 2333 currentContainer = thenBody; | 2330 currentContainer = thenBody; |
| 2334 generateThrowWithHelper(_helpers.throwIndexOutOfRangeException, | 2331 generateThrowWithHelper(_commonElements.throwIndexOutOfRangeException, |
| 2335 [node.array, node.reportedIndex]); | 2332 [node.array, node.reportedIndex]); |
| 2336 currentContainer = oldContainer; | 2333 currentContainer = oldContainer; |
| 2337 thenBody = unwrapStatement(thenBody); | 2334 thenBody = unwrapStatement(thenBody); |
| 2338 pushStatement(new js.If.noElse(underOver, thenBody) | 2335 pushStatement(new js.If.noElse(underOver, thenBody) |
| 2339 .withSourceInformation(node.sourceInformation)); | 2336 .withSourceInformation(node.sourceInformation)); |
| 2340 } else { | 2337 } else { |
| 2341 generateThrowWithHelper( | 2338 generateThrowWithHelper(_commonElements.throwIndexOutOfRangeException, |
| 2342 _helpers.throwIndexOutOfRangeException, [node.array, node.index]); | 2339 [node.array, node.index]); |
| 2343 } | 2340 } |
| 2344 } | 2341 } |
| 2345 | 2342 |
| 2346 void generateThrowWithHelper(FunctionEntity helper, argument, | 2343 void generateThrowWithHelper(FunctionEntity helper, argument, |
| 2347 {SourceInformation sourceInformation}) { | 2344 {SourceInformation sourceInformation}) { |
| 2348 js.Expression jsHelper = _emitter.staticFunctionAccess(helper); | 2345 js.Expression jsHelper = _emitter.staticFunctionAccess(helper); |
| 2349 List arguments = []; | 2346 List arguments = []; |
| 2350 if (argument is List) { | 2347 if (argument is List) { |
| 2351 argument.forEach((instruction) { | 2348 argument.forEach((instruction) { |
| 2352 use(instruction); | 2349 use(instruction); |
| 2353 arguments.add(pop()); | 2350 arguments.add(pop()); |
| 2354 }); | 2351 }); |
| 2355 } else { | 2352 } else { |
| 2356 use(argument); | 2353 use(argument); |
| 2357 arguments.add(pop()); | 2354 arguments.add(pop()); |
| 2358 } | 2355 } |
| 2359 _registry.registerStaticUse(new StaticUse.staticInvoke( | 2356 _registry.registerStaticUse(new StaticUse.staticInvoke( |
| 2360 helper, new CallStructure.unnamed(arguments.length))); | 2357 helper, new CallStructure.unnamed(arguments.length))); |
| 2361 js.Call value = new js.Call(jsHelper, arguments.toList(growable: false), | 2358 js.Call value = new js.Call(jsHelper, arguments.toList(growable: false), |
| 2362 sourceInformation: sourceInformation); | 2359 sourceInformation: sourceInformation); |
| 2363 // BUG(4906): Using throw/return here adds to the size of the generated code | 2360 // BUG(4906): Using throw/return here adds to the size of the generated code |
| 2364 // but it has the advantage of explicitly telling the JS engine that | 2361 // but it has the advantage of explicitly telling the JS engine that |
| 2365 // this code path will terminate abruptly. Needs more work. | 2362 // this code path will terminate abruptly. Needs more work. |
| 2366 if (helper == _helpers.wrapExceptionHelper) { | 2363 if (helper == _commonElements.wrapExceptionHelper) { |
| 2367 pushStatement( | 2364 pushStatement( |
| 2368 new js.Throw(value).withSourceInformation(sourceInformation)); | 2365 new js.Throw(value).withSourceInformation(sourceInformation)); |
| 2369 } else { | 2366 } else { |
| 2370 Entity element = _work.element; | 2367 Entity element = _work.element; |
| 2371 if (element is MethodElement && element.asyncMarker.isYielding) { | 2368 if (element is MethodElement && element.asyncMarker.isYielding) { |
| 2372 // `return <expr>;` is illegal in a sync* or async* function. | 2369 // `return <expr>;` is illegal in a sync* or async* function. |
| 2373 // To have the async-translator working, we avoid introducing | 2370 // To have the async-translator working, we avoid introducing |
| 2374 // `return` nodes. | 2371 // `return` nodes. |
| 2375 pushStatement(new js.ExpressionStatement(value) | 2372 pushStatement(new js.ExpressionStatement(value) |
| 2376 .withSourceInformation(sourceInformation)); | 2373 .withSourceInformation(sourceInformation)); |
| 2377 } else { | 2374 } else { |
| 2378 pushStatement( | 2375 pushStatement( |
| 2379 new js.Return(value).withSourceInformation(sourceInformation)); | 2376 new js.Return(value).withSourceInformation(sourceInformation)); |
| 2380 } | 2377 } |
| 2381 } | 2378 } |
| 2382 } | 2379 } |
| 2383 | 2380 |
| 2384 visitThrowExpression(HThrowExpression node) { | 2381 visitThrowExpression(HThrowExpression node) { |
| 2385 HInstruction argument = node.inputs[0]; | 2382 HInstruction argument = node.inputs[0]; |
| 2386 use(argument); | 2383 use(argument); |
| 2387 | 2384 |
| 2388 FunctionEntity helper = _helpers.throwExpressionHelper; | 2385 FunctionEntity helper = _commonElements.throwExpressionHelper; |
| 2389 _registry.registerStaticUse( | 2386 _registry.registerStaticUse( |
| 2390 new StaticUse.staticInvoke(helper, CallStructure.ONE_ARG)); | 2387 new StaticUse.staticInvoke(helper, CallStructure.ONE_ARG)); |
| 2391 | 2388 |
| 2392 js.Expression jsHelper = _emitter.staticFunctionAccess(helper); | 2389 js.Expression jsHelper = _emitter.staticFunctionAccess(helper); |
| 2393 js.Call value = new js.Call(jsHelper, [pop()]) | 2390 js.Call value = new js.Call(jsHelper, [pop()]) |
| 2394 .withSourceInformation(node.sourceInformation); | 2391 .withSourceInformation(node.sourceInformation); |
| 2395 push(value); | 2392 push(value); |
| 2396 } | 2393 } |
| 2397 | 2394 |
| 2398 void visitSwitch(HSwitch node) { | 2395 void visitSwitch(HSwitch node) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2451 if (node.usedBy.length == 1 && | 2448 if (node.usedBy.length == 1 && |
| 2452 node.usedBy[0] is HStringConcat && | 2449 node.usedBy[0] is HStringConcat && |
| 2453 node.usedBy[0].inputs[1] == node) { | 2450 node.usedBy[0].inputs[1] == node) { |
| 2454 // The context is already <string> + value. | 2451 // The context is already <string> + value. |
| 2455 } else { | 2452 } else { |
| 2456 // Force an empty string for the first operand. | 2453 // Force an empty string for the first operand. |
| 2457 push(new js.Binary('+', js.string(""), pop()) | 2454 push(new js.Binary('+', js.string(""), pop()) |
| 2458 .withSourceInformation(node.sourceInformation)); | 2455 .withSourceInformation(node.sourceInformation)); |
| 2459 } | 2456 } |
| 2460 } else { | 2457 } else { |
| 2461 FunctionEntity convertToString = _helpers.stringInterpolationHelper; | 2458 FunctionEntity convertToString = |
| 2459 _commonElements.stringInterpolationHelper; |
| 2462 _registry.registerStaticUse( | 2460 _registry.registerStaticUse( |
| 2463 new StaticUse.staticInvoke(convertToString, CallStructure.ONE_ARG)); | 2461 new StaticUse.staticInvoke(convertToString, CallStructure.ONE_ARG)); |
| 2464 js.Expression jsHelper = _emitter.staticFunctionAccess(convertToString); | 2462 js.Expression jsHelper = _emitter.staticFunctionAccess(convertToString); |
| 2465 use(input); | 2463 use(input); |
| 2466 push(new js.Call(jsHelper, <js.Expression>[pop()], | 2464 push(new js.Call(jsHelper, <js.Expression>[pop()], |
| 2467 sourceInformation: node.sourceInformation)); | 2465 sourceInformation: node.sourceInformation)); |
| 2468 } | 2466 } |
| 2469 } | 2467 } |
| 2470 | 2468 |
| 2471 void visitLiteralList(HLiteralList node) { | 2469 void visitLiteralList(HLiteralList node) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2612 use(input); | 2610 use(input); |
| 2613 push(new js.Binary('!=', pop(), new js.LiteralNull())); | 2611 push(new js.Binary('!=', pop(), new js.LiteralNull())); |
| 2614 } | 2612 } |
| 2615 | 2613 |
| 2616 void checkType(HInstruction input, HInstruction interceptor, DartType type, | 2614 void checkType(HInstruction input, HInstruction interceptor, DartType type, |
| 2617 SourceInformation sourceInformation, | 2615 SourceInformation sourceInformation, |
| 2618 {bool negative: false}) { | 2616 {bool negative: false}) { |
| 2619 if (type.isInterfaceType) { | 2617 if (type.isInterfaceType) { |
| 2620 InterfaceType interfaceType = type; | 2618 InterfaceType interfaceType = type; |
| 2621 ClassEntity element = interfaceType.element; | 2619 ClassEntity element = interfaceType.element; |
| 2622 if (element == _helpers.jsArrayClass) { | 2620 if (element == _commonElements.jsArrayClass) { |
| 2623 checkArray(input, negative ? '!==' : '==='); | 2621 checkArray(input, negative ? '!==' : '==='); |
| 2624 return; | 2622 return; |
| 2625 } else if (element == _helpers.jsMutableArrayClass) { | 2623 } else if (element == _commonElements.jsMutableArrayClass) { |
| 2626 if (negative) { | 2624 if (negative) { |
| 2627 checkImmutableArray(input); | 2625 checkImmutableArray(input); |
| 2628 } else { | 2626 } else { |
| 2629 checkMutableArray(input); | 2627 checkMutableArray(input); |
| 2630 } | 2628 } |
| 2631 return; | 2629 return; |
| 2632 } else if (element == _helpers.jsExtendableArrayClass) { | 2630 } else if (element == _commonElements.jsExtendableArrayClass) { |
| 2633 if (negative) { | 2631 if (negative) { |
| 2634 checkFixedArray(input); | 2632 checkFixedArray(input); |
| 2635 } else { | 2633 } else { |
| 2636 checkExtendableArray(input); | 2634 checkExtendableArray(input); |
| 2637 } | 2635 } |
| 2638 return; | 2636 return; |
| 2639 } else if (element == _helpers.jsFixedArrayClass) { | 2637 } else if (element == _commonElements.jsFixedArrayClass) { |
| 2640 if (negative) { | 2638 if (negative) { |
| 2641 checkExtendableArray(input); | 2639 checkExtendableArray(input); |
| 2642 } else { | 2640 } else { |
| 2643 checkFixedArray(input); | 2641 checkFixedArray(input); |
| 2644 } | 2642 } |
| 2645 return; | 2643 return; |
| 2646 } else if (element == _helpers.jsUnmodifiableArrayClass) { | 2644 } else if (element == _commonElements.jsUnmodifiableArrayClass) { |
| 2647 if (negative) { | 2645 if (negative) { |
| 2648 checkMutableArray(input); | 2646 checkMutableArray(input); |
| 2649 } else { | 2647 } else { |
| 2650 checkImmutableArray(input); | 2648 checkImmutableArray(input); |
| 2651 } | 2649 } |
| 2652 return; | 2650 return; |
| 2653 } | 2651 } |
| 2654 } | 2652 } |
| 2655 if (interceptor != null) { | 2653 if (interceptor != null) { |
| 2656 checkTypeViaProperty(interceptor, type, sourceInformation, | 2654 checkTypeViaProperty(interceptor, type, sourceInformation, |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2860 // Figure out if it is beneficial to turn this into a null check. | 2858 // Figure out if it is beneficial to turn this into a null check. |
| 2861 // V8 generally prefers 'typeof' checks, but for integers and | 2859 // V8 generally prefers 'typeof' checks, but for integers and |
| 2862 // indexable primitives we cannot compile this test into a single | 2860 // indexable primitives we cannot compile this test into a single |
| 2863 // typeof check so the null check is cheaper. | 2861 // typeof check so the null check is cheaper. |
| 2864 bool isIntCheck = checkedType.containsOnlyInt(_closedWorld); | 2862 bool isIntCheck = checkedType.containsOnlyInt(_closedWorld); |
| 2865 bool turnIntoNumCheck = | 2863 bool turnIntoNumCheck = |
| 2866 isIntCheck && inputType.containsOnlyInt(_closedWorld); | 2864 isIntCheck && inputType.containsOnlyInt(_closedWorld); |
| 2867 bool turnIntoNullCheck = !turnIntoNumCheck && | 2865 bool turnIntoNullCheck = !turnIntoNumCheck && |
| 2868 (checkedType.nullable() == inputType) && | 2866 (checkedType.nullable() == inputType) && |
| 2869 (isIntCheck || | 2867 (isIntCheck || |
| 2870 checkedType.satisfies(_helpers.jsIndexableClass, _closedWorld)); | 2868 checkedType.satisfies( |
| 2869 _commonElements.jsIndexableClass, _closedWorld)); |
| 2871 | 2870 |
| 2872 if (turnIntoNullCheck) { | 2871 if (turnIntoNullCheck) { |
| 2873 use(input); | 2872 use(input); |
| 2874 return new js.Binary("==", pop(), new js.LiteralNull()) | 2873 return new js.Binary("==", pop(), new js.LiteralNull()) |
| 2875 .withSourceInformation(input.sourceInformation); | 2874 .withSourceInformation(input.sourceInformation); |
| 2876 } else if (isIntCheck && !turnIntoNumCheck) { | 2875 } else if (isIntCheck && !turnIntoNumCheck) { |
| 2877 // input is !int | 2876 // input is !int |
| 2878 checkBigInt(input, '!==', input.sourceInformation); | 2877 checkBigInt(input, '!==', input.sourceInformation); |
| 2879 return pop(); | 2878 return pop(); |
| 2880 } else if (turnIntoNumCheck || checkedType.containsOnlyNum(_closedWorld)) { | 2879 } else if (turnIntoNumCheck || checkedType.containsOnlyNum(_closedWorld)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2895 } | 2894 } |
| 2896 | 2895 |
| 2897 void visitTypeConversion(HTypeConversion node) { | 2896 void visitTypeConversion(HTypeConversion node) { |
| 2898 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { | 2897 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { |
| 2899 js.Expression test = generateReceiverOrArgumentTypeTest(node); | 2898 js.Expression test = generateReceiverOrArgumentTypeTest(node); |
| 2900 js.Block oldContainer = currentContainer; | 2899 js.Block oldContainer = currentContainer; |
| 2901 js.Statement body = new js.Block.empty(); | 2900 js.Statement body = new js.Block.empty(); |
| 2902 currentContainer = body; | 2901 currentContainer = body; |
| 2903 if (node.isArgumentTypeCheck) { | 2902 if (node.isArgumentTypeCheck) { |
| 2904 generateThrowWithHelper( | 2903 generateThrowWithHelper( |
| 2905 _helpers.throwIllegalArgumentException, node.checkedInput, | 2904 _commonElements.throwIllegalArgumentException, node.checkedInput, |
| 2906 sourceInformation: node.sourceInformation); | 2905 sourceInformation: node.sourceInformation); |
| 2907 } else if (node.isReceiverTypeCheck) { | 2906 } else if (node.isReceiverTypeCheck) { |
| 2908 use(node.checkedInput); | 2907 use(node.checkedInput); |
| 2909 js.Name methodName = | 2908 js.Name methodName = |
| 2910 _namer.invocationName(node.receiverTypeCheckSelector); | 2909 _namer.invocationName(node.receiverTypeCheckSelector); |
| 2911 js.Expression call = js.propertyCall(pop(), methodName, []); | 2910 js.Expression call = js.propertyCall(pop(), methodName, []); |
| 2912 pushStatement(new js.Return(call)); | 2911 pushStatement(new js.Return(call)); |
| 2913 } | 2912 } |
| 2914 currentContainer = oldContainer; | 2913 currentContainer = oldContainer; |
| 2915 body = unwrapStatement(body); | 2914 body = unwrapStatement(body); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2931 _registry.registerTypeUse(new TypeUse.isCheck(type)); | 2930 _registry.registerTypeUse(new TypeUse.isCheck(type)); |
| 2932 | 2931 |
| 2933 CheckedModeHelper helper; | 2932 CheckedModeHelper helper; |
| 2934 if (node.isBooleanConversionCheck) { | 2933 if (node.isBooleanConversionCheck) { |
| 2935 helper = const CheckedModeHelper('boolConversionCheck'); | 2934 helper = const CheckedModeHelper('boolConversionCheck'); |
| 2936 } else { | 2935 } else { |
| 2937 helper = _checkedModeHelpers.getCheckedModeHelper(type, | 2936 helper = _checkedModeHelpers.getCheckedModeHelper(type, |
| 2938 typeCast: node.isCastTypeCheck); | 2937 typeCast: node.isCastTypeCheck); |
| 2939 } | 2938 } |
| 2940 | 2939 |
| 2941 StaticUse staticUse = helper.getStaticUse(_helpers); | 2940 StaticUse staticUse = helper.getStaticUse(_commonElements); |
| 2942 _registry.registerStaticUse(staticUse); | 2941 _registry.registerStaticUse(staticUse); |
| 2943 List<js.Expression> arguments = <js.Expression>[]; | 2942 List<js.Expression> arguments = <js.Expression>[]; |
| 2944 use(node.checkedInput); | 2943 use(node.checkedInput); |
| 2945 arguments.add(pop()); | 2944 arguments.add(pop()); |
| 2946 helper.generateAdditionalArguments(this, _namer, node, arguments); | 2945 helper.generateAdditionalArguments(this, _namer, node, arguments); |
| 2947 push(new js.Call( | 2946 push(new js.Call( |
| 2948 _emitter.staticFunctionAccess(staticUse.element), arguments)); | 2947 _emitter.staticFunctionAccess(staticUse.element), arguments)); |
| 2949 } | 2948 } |
| 2950 | 2949 |
| 2951 void visitTypeKnown(HTypeKnown node) { | 2950 void visitTypeKnown(HTypeKnown node) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2963 TypeVariableEntity element = node.variable.element; | 2962 TypeVariableEntity element = node.variable.element; |
| 2964 | 2963 |
| 2965 int index = element.index; | 2964 int index = element.index; |
| 2966 HInstruction object = node.object; | 2965 HInstruction object = node.object; |
| 2967 use(object); | 2966 use(object); |
| 2968 js.Expression receiver = pop(); | 2967 js.Expression receiver = pop(); |
| 2969 | 2968 |
| 2970 if (typeVariableAccessNeedsSubstitution(element, object.instructionType)) { | 2969 if (typeVariableAccessNeedsSubstitution(element, object.instructionType)) { |
| 2971 js.Expression typeName = | 2970 js.Expression typeName = |
| 2972 js.quoteName(_namer.runtimeTypeName(element.typeDeclaration)); | 2971 js.quoteName(_namer.runtimeTypeName(element.typeDeclaration)); |
| 2973 FunctionEntity helperElement = _helpers.getRuntimeTypeArgument; | 2972 FunctionEntity helperElement = _commonElements.getRuntimeTypeArgument; |
| 2974 _registry.registerStaticUse( | 2973 _registry.registerStaticUse( |
| 2975 new StaticUse.staticInvoke(helperElement, CallStructure.THREE_ARGS)); | 2974 new StaticUse.staticInvoke(helperElement, CallStructure.THREE_ARGS)); |
| 2976 js.Expression helper = _emitter.staticFunctionAccess(helperElement); | 2975 js.Expression helper = _emitter.staticFunctionAccess(helperElement); |
| 2977 push(js.js( | 2976 push(js.js( |
| 2978 r'#(#, #, #)', [helper, receiver, typeName, js.js.number(index)])); | 2977 r'#(#, #, #)', [helper, receiver, typeName, js.js.number(index)])); |
| 2979 } else { | 2978 } else { |
| 2980 FunctionEntity helperElement = _helpers.getTypeArgumentByIndex; | 2979 FunctionEntity helperElement = _commonElements.getTypeArgumentByIndex; |
| 2981 _registry.registerStaticUse( | 2980 _registry.registerStaticUse( |
| 2982 new StaticUse.staticInvoke(helperElement, CallStructure.TWO_ARGS)); | 2981 new StaticUse.staticInvoke(helperElement, CallStructure.TWO_ARGS)); |
| 2983 js.Expression helper = _emitter.staticFunctionAccess(helperElement); | 2982 js.Expression helper = _emitter.staticFunctionAccess(helperElement); |
| 2984 push(js.js(r'#(#, #)', [helper, receiver, js.js.number(index)])); | 2983 push(js.js(r'#(#, #)', [helper, receiver, js.js.number(index)])); |
| 2985 } | 2984 } |
| 2986 } | 2985 } |
| 2987 | 2986 |
| 2988 void visitTypeInfoExpression(HTypeInfoExpression node) { | 2987 void visitTypeInfoExpression(HTypeInfoExpression node) { |
| 2989 List<js.Expression> arguments = <js.Expression>[]; | 2988 List<js.Expression> arguments = <js.Expression>[]; |
| 2990 for (HInstruction input in node.inputs) { | 2989 for (HInstruction input in node.inputs) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3031 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { | 3030 return _closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { |
| 3032 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); | 3031 return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls); |
| 3033 }); | 3032 }); |
| 3034 } | 3033 } |
| 3035 | 3034 |
| 3036 @override | 3035 @override |
| 3037 void visitRef(HRef node) { | 3036 void visitRef(HRef node) { |
| 3038 visit(node.value); | 3037 visit(node.value); |
| 3039 } | 3038 } |
| 3040 } | 3039 } |
| OLD | NEW |