| 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 /// Enables debugging of fast/slow objects using V8-specific primitives. | 7 /// Enables debugging of fast/slow objects using V8-specific primitives. |
| 8 const DEBUG_FAST_OBJECTS = false; | 8 const DEBUG_FAST_OBJECTS = false; |
| 9 | 9 |
| 10 /** | 10 /** |
| (...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 // (2) foo$3$c(a, b, c) => foo$4$c$d(a, b, c, null); | 1127 // (2) foo$3$c(a, b, c) => foo$4$c$d(a, b, c, null); |
| 1128 // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d); | 1128 // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d); |
| 1129 // (4) No stub generated, call is direct. | 1129 // (4) No stub generated, call is direct. |
| 1130 // (5) No stub generated, call is direct. | 1130 // (5) No stub generated, call is direct. |
| 1131 | 1131 |
| 1132 // Keep a cache of which stubs have already been generated, to | 1132 // Keep a cache of which stubs have already been generated, to |
| 1133 // avoid duplicates. Note that even if selectors are | 1133 // avoid duplicates. Note that even if selectors are |
| 1134 // canonicalized, we would still need this cache: a typed selector | 1134 // canonicalized, we would still need this cache: a typed selector |
| 1135 // on A and a typed selector on B could yield the same stub. | 1135 // on A and a typed selector on B could yield the same stub. |
| 1136 Set<String> generatedStubNames = new Set<String>(); | 1136 Set<String> generatedStubNames = new Set<String>(); |
| 1137 if (compiler.enabledFunctionApply | 1137 bool isClosureInvocation = |
| 1138 && member.name == namer.closureInvocationSelectorName) { | 1138 member.name == namer.closureInvocationSelectorName; |
| 1139 if (backend.isNeededForReflection(member) || |
| 1140 (compiler.enabledFunctionApply && isClosureInvocation)) { |
| 1139 // If [Function.apply] is called, we pessimistically compile all | 1141 // If [Function.apply] is called, we pessimistically compile all |
| 1140 // possible stubs for this closure. | 1142 // possible stubs for this closure. |
| 1141 FunctionSignature signature = member.computeSignature(compiler); | 1143 FunctionSignature signature = member.computeSignature(compiler); |
| 1142 Set<Selector> selectors = signature.optionalParametersAreNamed | 1144 Set<Selector> selectors = signature.optionalParametersAreNamed |
| 1143 ? computeSeenNamedSelectors(member) | 1145 ? computeSeenNamedSelectors(member) |
| 1144 : computeOptionalSelectors(signature, member); | 1146 : computeOptionalSelectors(signature, member); |
| 1145 for (Selector selector in selectors) { | 1147 for (Selector selector in selectors) { |
| 1146 addParameterStub(member, selector, defineStub, generatedStubNames); | 1148 addParameterStub(member, selector, defineStub, generatedStubNames); |
| 1147 } | 1149 } |
| 1148 if (signature.optionalParametersAreNamed) { | 1150 if (signature.optionalParametersAreNamed && isClosureInvocation) { |
| 1149 addCatchAllParameterStub(member, signature, defineStub); | 1151 addCatchAllParameterStub(member, signature, defineStub); |
| 1150 } | 1152 } |
| 1151 } else { | 1153 } else { |
| 1152 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; | 1154 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; |
| 1153 if (selectors == null) return; | 1155 if (selectors == null) return; |
| 1154 for (Selector selector in selectors) { | 1156 for (Selector selector in selectors) { |
| 1155 if (!selector.applies(member, compiler)) continue; | 1157 if (!selector.applies(member, compiler)) continue; |
| 1156 addParameterStub(member, selector, defineStub, generatedStubNames); | 1158 addParameterStub(member, selector, defineStub, generatedStubNames); |
| 1157 } | 1159 } |
| 1158 } | 1160 } |
| 1159 } | 1161 } |
| 1160 | 1162 |
| 1161 Set<Selector> computeSeenNamedSelectors(FunctionElement element) { | 1163 Set<Selector> computeSeenNamedSelectors(FunctionElement element) { |
| 1162 Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name]; | 1164 Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name]; |
| 1163 if (selectors == null) return null; | |
| 1164 Set<Selector> result = new Set<Selector>(); | 1165 Set<Selector> result = new Set<Selector>(); |
| 1166 if (selectors == null) return result; |
| 1165 for (Selector selector in selectors) { | 1167 for (Selector selector in selectors) { |
| 1166 if (!selector.applies(element, compiler)) continue; | 1168 if (!selector.applies(element, compiler)) continue; |
| 1167 result.add(selector); | 1169 result.add(selector); |
| 1168 } | 1170 } |
| 1169 return result; | 1171 return result; |
| 1170 } | 1172 } |
| 1171 | 1173 |
| 1172 void addCatchAllParameterStub(FunctionElement member, | 1174 void addCatchAllParameterStub(FunctionElement member, |
| 1173 FunctionSignature signature, | 1175 FunctionSignature signature, |
| 1174 DefineStubFunction defineStub) { | 1176 DefineStubFunction defineStub) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1354 var names = []; | 1356 var names = []; |
| 1355 for (Element e in signature.optionalParameters) { | 1357 for (Element e in signature.optionalParameters) { |
| 1356 names.add(e.name); | 1358 names.add(e.name); |
| 1357 } | 1359 } |
| 1358 Selector selector = new Selector.call( | 1360 Selector selector = new Selector.call( |
| 1359 function.name, | 1361 function.name, |
| 1360 function.getLibrary(), | 1362 function.getLibrary(), |
| 1361 requiredParameterCount, | 1363 requiredParameterCount, |
| 1362 names); | 1364 names); |
| 1363 namedArguments = namedParametersAsReflectionNames(selector); | 1365 namedArguments = namedParametersAsReflectionNames(selector); |
| 1366 } else { |
| 1367 // Named parameters are handled differently by mirrors. For unnamed |
| 1368 // parameters, they are actually required if invoked |
| 1369 // reflectively. Also, if you have a method c(x) and c([x]) they both |
| 1370 // get the same mangled name, so they must have the same reflection |
| 1371 // name. |
| 1372 requiredParameterCount += optionalParameterCount; |
| 1373 optionalParameterCount = 0; |
| 1364 } | 1374 } |
| 1365 } | 1375 } |
| 1366 String suffix = | 1376 String suffix = |
| 1377 // TODO(ahe): We probably don't need optionalParameterCount in the |
| 1378 // reflection name. |
| 1367 '$name:$requiredParameterCount:$optionalParameterCount' | 1379 '$name:$requiredParameterCount:$optionalParameterCount' |
| 1368 '$namedArguments'; | 1380 '$namedArguments'; |
| 1369 return (isConstructor) ? 'new $suffix' : suffix; | 1381 return (isConstructor) ? 'new $suffix' : suffix; |
| 1370 } | 1382 } |
| 1371 Element element = elementOrSelector; | 1383 Element element = elementOrSelector; |
| 1372 if (element.isGenerativeConstructorBody()) { | 1384 if (element.isGenerativeConstructorBody()) { |
| 1373 return null; | 1385 return null; |
| 1374 } else if (element.isClass()) { | 1386 } else if (element.isClass()) { |
| 1375 ClassElement cls = element; | 1387 ClassElement cls = element; |
| 1376 if (cls.isUnnamedMixinApplication) return null; | 1388 if (cls.isUnnamedMixinApplication) return null; |
| (...skipping 3034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4411 | 4423 |
| 4412 const String HOOKS_API_USAGE = """ | 4424 const String HOOKS_API_USAGE = """ |
| 4413 // The code supports the following hooks: | 4425 // The code supports the following hooks: |
| 4414 // dartPrint(message) - if this function is defined it is called | 4426 // dartPrint(message) - if this function is defined it is called |
| 4415 // instead of the Dart [print] method. | 4427 // instead of the Dart [print] method. |
| 4416 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4428 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4417 // method will not be invoked directly. | 4429 // method will not be invoked directly. |
| 4418 // Instead, a closure that will invoke [main] is | 4430 // Instead, a closure that will invoke [main] is |
| 4419 // passed to [dartMainRunner]. | 4431 // passed to [dartMainRunner]. |
| 4420 """; | 4432 """; |
| OLD | NEW |