mirror of
https://github.com/dart-lang/sdk
synced 2024-10-05 03:25:51 +00:00
Do not track parameter types of closures, since closure calls can be generated during the emitter.
Review URL: https://codereview.chromium.org//11958009 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@17134 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
8e4757a782
commit
26e11c6263
|
@ -485,6 +485,13 @@ class ArgumentTypesRegistry {
|
|||
void registerDynamicInvocation(HInvokeDynamic node,
|
||||
Selector selector,
|
||||
HTypeMap types) {
|
||||
if (selector.isClosureCall()) {
|
||||
// We cannot use the current framework to do optimizations based
|
||||
// on the 'call' selector because we are also generating closure
|
||||
// calls during the emitter phase, which at this point, does not
|
||||
// track parameter types, nor invalidates optimized methods.
|
||||
return;
|
||||
}
|
||||
HTypeList providedTypes =
|
||||
new HTypeList.fromDynamicInvocation(node, selector, types);
|
||||
if (!selectorTypeMap.containsKey(selector)) {
|
||||
|
|
|
@ -1649,11 +1649,6 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
visitArguments(node.inputs)),
|
||||
node);
|
||||
world.registerDynamicInvocation(call.name, call);
|
||||
// A closure can also be invoked through [HInvokeDynamicMethod] by
|
||||
// explicitly calling the [:call:] method. Therefore, we must also
|
||||
// register types here to let the backend invalidate wrong
|
||||
// optimizations.
|
||||
backend.registerDynamicInvocation(node, call, types);
|
||||
}
|
||||
|
||||
visitInvokeStatic(HInvokeStatic node) {
|
||||
|
|
|
@ -215,6 +215,10 @@ class Selector {
|
|||
bool isGetter() => identical(kind, SelectorKind.GETTER);
|
||||
bool isSetter() => identical(kind, SelectorKind.SETTER);
|
||||
bool isCall() => identical(kind, SelectorKind.CALL);
|
||||
bool isClosureCall() {
|
||||
SourceString callName = Compiler.CALL_OPERATOR_NAME;
|
||||
return isCall() && name == callName;
|
||||
}
|
||||
|
||||
bool isIndex() => identical(kind, SelectorKind.INDEX) && argumentCount == 1;
|
||||
bool isIndexSet() => identical(kind, SelectorKind.INDEX) && argumentCount == 2;
|
||||
|
|
24
tests/language/closure_parameter_types_test.dart
Normal file
24
tests/language/closure_parameter_types_test.dart
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Regression test for dart2js, where the optimizer was too agressive
|
||||
// about parameter types of closures.
|
||||
|
||||
class A {
|
||||
Function f;
|
||||
A(this.f);
|
||||
_do() => f(1);
|
||||
}
|
||||
|
||||
main() {
|
||||
int invokeCount = 0;
|
||||
closure(a) {
|
||||
if (invokeCount++ == 1) {
|
||||
Expect.isTrue(a is int);
|
||||
}
|
||||
}
|
||||
closure('s');
|
||||
new A(closure)._do();
|
||||
Expect.equals(2, invokeCount);
|
||||
}
|
Loading…
Reference in a new issue