| 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 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 // avoid duplicates. Note that even if selectors are | 1136 // avoid duplicates. Note that even if selectors are |
| 1137 // canonicalized, we would still need this cache: a typed selector | 1137 // canonicalized, we would still need this cache: a typed selector |
| 1138 // on A and a typed selector on B could yield the same stub. | 1138 // on A and a typed selector on B could yield the same stub. |
| 1139 Set<String> generatedStubNames = new Set<String>(); | 1139 Set<String> generatedStubNames = new Set<String>(); |
| 1140 if (compiler.enabledFunctionApply | 1140 if (compiler.enabledFunctionApply |
| 1141 && member.name == namer.closureInvocationSelectorName) { | 1141 && member.name == namer.closureInvocationSelectorName) { |
| 1142 // If [Function.apply] is called, we pessimistically compile all | 1142 // If [Function.apply] is called, we pessimistically compile all |
| 1143 // possible stubs for this closure. | 1143 // possible stubs for this closure. |
| 1144 FunctionSignature signature = member.computeSignature(compiler); | 1144 FunctionSignature signature = member.computeSignature(compiler); |
| 1145 Set<Selector> selectors = signature.optionalParametersAreNamed | 1145 Set<Selector> selectors = signature.optionalParametersAreNamed |
| 1146 ? computeNamedSelectors(signature, member) | 1146 ? computeSeenNamedSelectors(member) |
| 1147 : computeOptionalSelectors(signature, member); | 1147 : computeOptionalSelectors(signature, member); |
| 1148 for (Selector selector in selectors) { | 1148 for (Selector selector in selectors) { |
| 1149 addParameterStub(member, selector, defineStub, generatedStubNames); | 1149 addParameterStub(member, selector, defineStub, generatedStubNames); |
| 1150 } | 1150 } |
| 1151 if (signature.optionalParametersAreNamed) { |
| 1152 addCatchAllParameterStub(member, signature, defineStub); |
| 1153 } |
| 1151 } else { | 1154 } else { |
| 1152 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; | 1155 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; |
| 1153 if (selectors == null) return; | 1156 if (selectors == null) return; |
| 1154 for (Selector selector in selectors) { | 1157 for (Selector selector in selectors) { |
| 1155 if (!selector.applies(member, compiler)) continue; | 1158 if (!selector.applies(member, compiler)) continue; |
| 1156 addParameterStub(member, selector, defineStub, generatedStubNames); | 1159 addParameterStub(member, selector, defineStub, generatedStubNames); |
| 1157 } | 1160 } |
| 1158 } | 1161 } |
| 1159 } | 1162 } |
| 1160 | 1163 |
| 1161 /** | 1164 Set<Selector> computeSeenNamedSelectors(FunctionElement element) { |
| 1162 * Compute the set of possible selectors in the presence of named | 1165 Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name]; |
| 1163 * parameters. | 1166 if (selectors == null) return null; |
| 1164 */ | 1167 Set<Selector> result = new Set<Selector>(); |
| 1165 Set<Selector> computeNamedSelectors(FunctionSignature signature, | 1168 for (Selector selector in selectors) { |
| 1166 FunctionElement element) { | 1169 if (!selector.applies(element, compiler)) continue; |
| 1167 Set<Selector> selectors = new Set<Selector>(); | 1170 result.add(selector); |
| 1168 // Add the selector that does not have any optional argument. | 1171 } |
| 1169 selectors.add(new Selector(SelectorKind.CALL, | 1172 return result; |
| 1170 element.name, | 1173 } |
| 1171 element.getLibrary(), | |
| 1172 signature.requiredParameterCount, | |
| 1173 <SourceString>[])); | |
| 1174 | 1174 |
| 1175 // For each optional parameter, we iterator over the set of | 1175 void addCatchAllParameterStub(FunctionElement member, |
| 1176 // already computed selectors and create new selectors with that | 1176 FunctionSignature signature, |
| 1177 // parameter now being passed. | 1177 DefineStubFunction defineStub) { |
| 1178 signature.forEachOptionalParameter((Element element) { | 1178 // See Primities.applyFunction in js_helper.dart for details. |
| 1179 Set<Selector> newSet = new Set<Selector>(); | 1179 List<jsAst.Property> properties = <jsAst.Property>[]; |
| 1180 selectors.forEach((Selector other) { | 1180 for (Element element in signature.orderedOptionalParameters) { |
| 1181 List<SourceString> namedArguments = [element.name]; | 1181 String jsName = backend.namer.safeName(element.name.slowToString()); |
| 1182 namedArguments.addAll(other.namedArguments); | 1182 Constant value = compiler.constantHandler.initialVariableValues[element]; |
| 1183 newSet.add(new Selector(other.kind, | 1183 jsAst.Expression reference = null; |
| 1184 other.name, | 1184 if (value == null) { |
| 1185 other.library, | 1185 reference = new jsAst.LiteralNull(); |
| 1186 other.argumentCount + 1, | 1186 } else { |
| 1187 namedArguments)); | 1187 reference = constantReference(value); |
| 1188 }); | 1188 } |
| 1189 selectors.addAll(newSet); | 1189 properties.add(new jsAst.Property(js.string(jsName), reference)); |
| 1190 }); | 1190 } |
| 1191 return selectors; | 1191 defineStub( |
| 1192 r'call$catchAll', // TODO(ahe): Get from namer. |
| 1193 js.fun([], js.return_(new jsAst.ObjectInitializer(properties)))); |
| 1192 } | 1194 } |
| 1193 | 1195 |
| 1194 /** | 1196 /** |
| 1195 * Compute the set of possible selectors in the presence of optional | 1197 * Compute the set of possible selectors in the presence of optional |
| 1196 * non-named parameters. | 1198 * non-named parameters. |
| 1197 */ | 1199 */ |
| 1198 Set<Selector> computeOptionalSelectors(FunctionSignature signature, | 1200 Set<Selector> computeOptionalSelectors(FunctionSignature signature, |
| 1199 FunctionElement element) { | 1201 FunctionElement element) { |
| 1200 Set<Selector> selectors = new Set<Selector>(); | 1202 Set<Selector> selectors = new Set<Selector>(); |
| 1201 // Add the selector that does not have any optional argument. | 1203 // Add the selector that does not have any optional argument. |
| (...skipping 2827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4029 | 4031 |
| 4030 const String HOOKS_API_USAGE = """ | 4032 const String HOOKS_API_USAGE = """ |
| 4031 // The code supports the following hooks: | 4033 // The code supports the following hooks: |
| 4032 // dartPrint(message) - if this function is defined it is called | 4034 // dartPrint(message) - if this function is defined it is called |
| 4033 // instead of the Dart [print] method. | 4035 // instead of the Dart [print] method. |
| 4034 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4036 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4035 // method will not be invoked directly. | 4037 // method will not be invoked directly. |
| 4036 // Instead, a closure that will invoke [main] is | 4038 // Instead, a closure that will invoke [main] is |
| 4037 // passed to [dartMainRunner]. | 4039 // passed to [dartMainRunner]. |
| 4038 """; | 4040 """; |
| OLD | NEW |