Chromium Code Reviews| Index: tests/compiler/dart2js/closure/closure_test.dart |
| diff --git a/tests/compiler/dart2js/closure/closure_test.dart b/tests/compiler/dart2js/closure/closure_test.dart |
| index c3611f95310ba54d382290cf3123b014e9a39f46..85959c8439e2612b0835fa69edfcc3f6de841aab 100644 |
| --- a/tests/compiler/dart2js/closure/closure_test.dart |
| +++ b/tests/compiler/dart2js/closure/closure_test.dart |
| @@ -27,7 +27,12 @@ main(List<String> args) { |
| Directory dataDir = new Directory.fromUri(Platform.script.resolve('data')); |
| await checkTests(dataDir, computeClosureData, computeKernelClosureData, |
| // TODO(johnnniwinther,efortuna): Enable these tests for .dill. |
| - skipForKernel: ['captured_variable.dart'], |
| + skipForKernel: [ |
| + 'captured_variable.dart', |
| + 'mixed.dart', |
| + 'mutations.dart', |
| + 'nested_closures.dart' |
| + ], |
| options: [Flags.disableTypeInference], |
| verbose: verbose); |
| }); |
| @@ -84,9 +89,11 @@ class ClosureAstComputer extends AstDataExtractor with ComputeValueMixin { |
| visitFunctionExpression(ast.FunctionExpression node) { |
| Entity localFunction = resolvedAst.elements.getFunctionDefinition(node); |
| if (localFunction is LocalFunctionElement) { |
| + pushMember(localFunction.callMethod); |
| pushLocalFunction(node); |
| super.visitFunctionExpression(node); |
| popLocalFunction(); |
| + popMember(); |
| } else { |
| super.visitFunctionExpression(node); |
| } |
| @@ -96,7 +103,8 @@ class ClosureAstComputer extends AstDataExtractor with ComputeValueMixin { |
| String computeNodeValue(ast.Node node, [AstElement element]) { |
| if (element != null && element.isLocal) { |
| if (element.isFunction) { |
| - return computeObjectValue(element); |
| + LocalFunctionElement localFunction = element; |
| + return computeObjectValue(localFunction.callMethod); |
| } else { |
| LocalElement local = element; |
| return computeLocalValue(local); |
| @@ -107,7 +115,7 @@ class ClosureAstComputer extends AstDataExtractor with ComputeValueMixin { |
| } |
| @override |
| - String computeElementValue(AstElement element) { |
| + String computeElementValue(covariant MemberElement element) { |
| // TODO(johnniwinther,efortuna): Collect data for the member |
| // (has thisLocal, has box, etc.). |
| return computeObjectValue(element); |
| @@ -133,27 +141,36 @@ class ClosureIrChecker extends IrDataExtractor with ComputeValueMixin<ir.Node> { |
| } |
| visitFunctionExpression(ir.FunctionExpression node) { |
| + ClosureRepresentationInfo info = closureDataLookup.getClosureInfo(node); |
| + pushMember(info.callMethod); |
| pushLocalFunction(node); |
| super.visitFunctionExpression(node); |
| popLocalFunction(); |
| + popMember(); |
| } |
| visitFunctionDeclaration(ir.FunctionDeclaration node) { |
| + ClosureRepresentationInfo info = closureDataLookup.getClosureInfo(node); |
| + pushMember(info.callMethod); |
| pushLocalFunction(node); |
| super.visitFunctionDeclaration(node); |
| popLocalFunction(); |
| + popMember(); |
| } |
| @override |
| String computeNodeValue(ir.Node node) { |
| if (node is ir.VariableDeclaration) { |
| if (node.parent is ir.FunctionDeclaration) { |
| - return computeObjectValue(node.parent); |
| + ClosureRepresentationInfo info = |
| + closureDataLookup.getClosureInfo(node.parent); |
| + return computeObjectValue(info.callMethod); |
| } |
| Local local = _localsMap.getLocalVariable(node); |
| return computeLocalValue(local); |
| } else if (node is ir.FunctionExpression) { |
| - return computeObjectValue(node); |
| + ClosureRepresentationInfo info = closureDataLookup.getClosureInfo(node); |
| + return computeObjectValue(info.callMethod); |
| } |
| return null; |
| } |
| @@ -166,10 +183,12 @@ class ClosureIrChecker extends IrDataExtractor with ComputeValueMixin<ir.Node> { |
| abstract class ComputeValueMixin<T> { |
| bool get verbose; |
| + Map<BoxLocal, String> boxNames = <BoxLocal, String>{}; |
| ClosureDataLookup<T> get closureDataLookup; |
| Link<ScopeInfo> scopeInfoStack = const Link<ScopeInfo>(); |
| ScopeInfo get scopeInfo => scopeInfoStack.head; |
| - CapturedScope capturedScope; |
| + CapturedScope get capturedScope => capturedScopeStack.head; |
| + Link<CapturedScope> capturedScopeStack = const Link<CapturedScope>(); |
| Link<ClosureRepresentationInfo> closureRepresentationInfoStack = |
| const Link<ClosureRepresentationInfo>(); |
| ClosureRepresentationInfo get closureRepresentationInfo => |
| @@ -180,12 +199,17 @@ abstract class ComputeValueMixin<T> { |
| void pushMember(MemberEntity member) { |
| scopeInfoStack = |
| scopeInfoStack.prepend(closureDataLookup.getScopeInfo(member)); |
| - capturedScope = closureDataLookup.getCapturedScope(member); |
| + capturedScopeStack = |
| + capturedScopeStack.prepend(closureDataLookup.getCapturedScope(member)); |
| + if (capturedScope.requiresContextBox) { |
| + boxNames[capturedScope.context] = 'box${boxNames.length}'; |
| + } |
| dump(member); |
| } |
| void popMember() { |
| scopeInfoStack = scopeInfoStack.tail; |
| + capturedScopeStack = capturedScopeStack.tail; |
| } |
| void pushLocalFunction(T node) { |
| @@ -203,8 +227,6 @@ abstract class ComputeValueMixin<T> { |
| print('object: $object'); |
| if (object is MemberEntity) { |
| - print(' scopeInfo (${scopeInfo.runtimeType})'); |
| - scopeInfo.forEachBoxedVariable((a, b) => print(' boxed1: $a->$b')); |
| print(' capturedScope (${capturedScope.runtimeType})'); |
| capturedScope.forEachBoxedVariable((a, b) => print(' boxed2: $a->$b')); |
| } |
| @@ -228,14 +250,12 @@ abstract class ComputeValueMixin<T> { |
| } else { |
| //Expect.isFalse(capturedScope.localIsUsedInTryOrSync(local)); |
| } |
| - if (scopeInfo.isBoxed(local)) { |
| + if (capturedScope.isBoxed(local)) { |
| features.add('boxed'); |
| - Expect.isTrue(capturedScope.isBoxed(local)); |
| - } else { |
| - Expect.isFalse(capturedScope.isBoxed(local)); |
| } |
| if (capturedScope.context == local) { |
| - features.add('local'); |
| + // TODO(johnniwinther): This can't happen! |
|
Siggi Cherem (dart-lang)
2017/08/28 17:33:45
nit: rewrite to explain what this means? not sure
|
| + features.add('box'); |
|
Siggi Cherem (dart-lang)
2017/08/28 17:33:45
maybe use a different string to denote this is an
|
| } |
| if (capturedScope is CapturedLoopScope) { |
| CapturedLoopScope loopScope = capturedScope; |
| @@ -247,22 +267,19 @@ abstract class ComputeValueMixin<T> { |
| if (closureRepresentationInfo.createdFieldEntities.contains(local)) { |
| features.add('field'); |
| } |
| - if (closureRepresentationInfo.isVariableBoxed(local)) { |
| - features.add('variable-boxed'); |
| - } |
| } |
| // TODO(johnniwinther,efortuna): Add more info? |
| return (features.toList()..sort()).join(','); |
| } |
| - String computeObjectValue(Object object) { |
| + String computeObjectValue(MemberEntity member) { |
| Map<String, String> features = <String, String>{}; |
| void addLocals(String name, forEach(f(Local local, _))) { |
| List<String> names = <String>[]; |
| forEach((Local local, _) { |
| if (local is BoxLocal) { |
| - names.add('box'); |
| + names.add(boxNames[local]); |
| } else { |
| names.add(local.name); |
| } |
| @@ -270,26 +287,21 @@ abstract class ComputeValueMixin<T> { |
| String value = names.isEmpty ? null : '[${(names..sort()).join(',')}]'; |
| if (features.containsKey(name)) { |
| Expect.equals( |
| - features[name], value, "Inconsistent values for $name on $object."); |
| + features[name], value, "Inconsistent values for $name on $member."); |
| } |
| features[name] = value; |
| } |
| - if (object is MemberEntity) { |
| - if (scopeInfo.thisLocal != null) { |
| - features['hasThis'] = ''; |
| - } |
| - addLocals('boxed', scopeInfo.forEachBoxedVariable); |
| - |
| - if (capturedScope.requiresContextBox) { |
| - features['requiresBox'] = ''; |
| - } |
| - addLocals('boxed', capturedScope.forEachBoxedVariable); |
| + if (scopeInfo.thisLocal != null) { |
| + features['hasThis'] = ''; |
| + } |
| + if (capturedScope.requiresContextBox) { |
| + //print('------------- $object from $capturedScope'); |
|
Siggi Cherem (dart-lang)
2017/08/28 17:33:45
delete
|
| + features['box'] = boxNames[capturedScope.context]; |
| } |
| + addLocals('boxed', capturedScope.forEachBoxedVariable); |
|
Siggi Cherem (dart-lang)
2017/08/28 17:33:45
an idea: since this and requiresContextBox are cor
|
| if (closureRepresentationInfo != null) { |
| - addLocals('boxed', closureRepresentationInfo.forEachBoxedVariable); |
| - addLocals('captured', closureRepresentationInfo.forEachCapturedVariable); |
| addLocals('free', closureRepresentationInfo.forEachFreeVariable); |
| } |