Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 11628009: Re-apply "support for typedef in checked mode" and fix the checked mode failures on drt by not shar… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 new js.VariableUse('receiver') 1105 new js.VariableUse('receiver')
1106 .dot(name) 1106 .dot(name)
1107 .callWith(arguments))])); 1107 .callWith(arguments))]));
1108 1108
1109 CodeBuffer code = new CodeBuffer(); 1109 CodeBuffer code = new CodeBuffer();
1110 code.add(js.prettyPrint(function, compiler)); 1110 code.add(js.prettyPrint(function, compiler));
1111 defineInstanceMember(name, code); 1111 defineInstanceMember(name, code);
1112 } 1112 }
1113 } 1113 }
1114 1114
1115 void emitTypedefChecksOn(DartType type, void emitTest(Element element)) {
floitsch 2012/12/19 10:39:34 Rename to forEachTypedefCheckOf Ideally this shou
1116 for (TypedefElement typedef in checkedTypedefs) {
1117 FunctionType typedefType =
1118 typedef.computeType(compiler).unalias(compiler);
1119 if (compiler.types.isSubtype(type, typedefType)) {
1120 emitTest(typedef);
1121 }
1122 }
1123 }
1124
1115 /** 1125 /**
1116 * Generate "is tests" for [cls]: itself, and the "is tests" for the 1126 * Generate "is tests" for [cls]: itself, and the "is tests" for the
1117 * classes it implements. We don't need to add the "is tests" of the 1127 * classes it implements. We don't need to add the "is tests" of the
1118 * super class because they will be inherited at runtime. 1128 * super class because they will be inherited at runtime.
1119 */ 1129 */
1120 void generateIsTestsOn(ClassElement cls, 1130 void generateIsTestsOn(ClassElement cls,
1121 void emitIsTest(Element element)) { 1131 void emitIsTest(Element element)) {
1122 if (checkedClasses.contains(cls)) { 1132 if (checkedClasses.contains(cls)) {
1123 emitIsTest(cls); 1133 emitIsTest(cls);
1124 } 1134 }
1125 1135
1126 Set<Element> generated = new Set<Element>(); 1136 Set<Element> generated = new Set<Element>();
1127 // A class that defines a [:call:] method implicitly implements 1137 // A class that defines a [:call:] method implicitly implements
1128 // [Function] and needs checks for all typedefs that are used in is-checks. 1138 // [Function] and needs checks for all typedefs that are used in is-checks.
1129 if (checkedClasses.contains(compiler.functionClass) || 1139 if (checkedClasses.contains(compiler.functionClass) ||
1130 !checkedTypedefs.isEmpty) { 1140 !checkedTypedefs.isEmpty) {
1131 FunctionElement call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME); 1141 FunctionElement call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
1132 if (call == null) { 1142 if (call == null) {
1133 // If [cls] is a closure, it has a synthetic call operator method. 1143 // If [cls] is a closure, it has a synthetic call operator method.
1134 call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME); 1144 call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME);
1135 } 1145 }
1136 if (call != null) { 1146 if (call != null) {
1137 generateInterfacesIsTests(compiler.functionClass, 1147 generateInterfacesIsTests(compiler.functionClass,
1138 emitIsTest, 1148 emitIsTest,
1139 generated); 1149 generated);
1140 FunctionType callType = call.computeType(compiler); 1150 emitTypedefChecksOn(call.computeType(compiler), emitIsTest);
1141 for (TypedefElement typedef in checkedTypedefs) {
1142 FunctionType typedefType =
1143 typedef.computeType(compiler).unalias(compiler);
1144 if (compiler.types.isSubtype(callType, typedefType)) {
1145 emitIsTest(typedef);
1146 }
1147 }
1148 } 1151 }
1149 } 1152 }
1150 for (DartType interfaceType in cls.interfaces) { 1153 for (DartType interfaceType in cls.interfaces) {
1151 generateInterfacesIsTests(interfaceType.element, emitIsTest, generated); 1154 generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);
1152 } 1155 }
1153 } 1156 }
1154 1157
1155 /** 1158 /**
1156 * Generate "is tests" where [cls] is being implemented. 1159 * Generate "is tests" where [cls] is being implemented.
1157 */ 1160 */
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 String invocationName = namer.instanceMethodName(callElement); 1337 String invocationName = namer.instanceMethodName(callElement);
1335 String fieldAccess = '$isolateProperties.$staticName'; 1338 String fieldAccess = '$isolateProperties.$staticName';
1336 buffer.add("$fieldAccess.$invocationName$_=$_$fieldAccess$N"); 1339 buffer.add("$fieldAccess.$invocationName$_=$_$fieldAccess$N");
1337 addParameterStubs(callElement, (String name, CodeBuffer value) { 1340 addParameterStubs(callElement, (String name, CodeBuffer value) {
1338 buffer.add('$fieldAccess.$name$_=$_$value$N'); 1341 buffer.add('$fieldAccess.$name$_=$_$value$N');
1339 }); 1342 });
1340 // If a static function is used as a closure we need to add its name 1343 // If a static function is used as a closure we need to add its name
1341 // in case it is used in spawnFunction. 1344 // in case it is used in spawnFunction.
1342 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; 1345 String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
1343 buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N'); 1346 buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N');
1347 emitTypedefChecksOn(element.computeType(compiler), (Element typedef) {
1348 String operator = namer.operatorIs(typedef);
1349 buffer.add('$fieldAccess.$operator$_=${_}true$N');
1350 });
1344 } 1351 }
1345 } 1352 }
1346 1353
1347 void emitBoundClosureClassHeader(String mangledName, 1354 void emitBoundClosureClassHeader(String mangledName,
1348 String superName, 1355 String superName,
1349 List<String> fieldNames, 1356 List<String> fieldNames,
1350 CodeBuffer buffer) { 1357 CodeBuffer buffer) {
1351 buffer.add('$classesCollector.$mangledName$_=$_' 1358 buffer.add('$classesCollector.$mangledName$_=$_'
1352 '{"":"$superName;${Strings.join(fieldNames,',')}",'); 1359 '{"":"$superName;${Strings.join(fieldNames,',')}",');
1353 } 1360 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 extraArg = 'receiver'; 1402 extraArg = 'receiver';
1396 } else { 1403 } else {
1397 cache = boundClosureCache; 1404 cache = boundClosureCache;
1398 } 1405 }
1399 List<String> fieldNames = compiler.enableMinification 1406 List<String> fieldNames = compiler.enableMinification
1400 ? inInterceptor ? const ['a', 'b', 'c'] 1407 ? inInterceptor ? const ['a', 'b', 'c']
1401 : const ['a', 'b'] 1408 : const ['a', 'b']
1402 : inInterceptor ? const ['self', 'target', 'receiver'] 1409 : inInterceptor ? const ['self', 'target', 'receiver']
1403 : const ['self', 'target']; 1410 : const ['self', 'target'];
1404 1411
1405 String closureClass = hasOptionalParameters ? null : cache[parameterCount]; 1412 bool hasTypedefChecks = false;
1413 emitTypedefChecksOn(member.computeType(compiler), (Element typedef) {
1414 hasTypedefChecks = true;
1415 });
1416
1417 bool canBeShared = !hasOptionalParameters && !hasTypedefChecks;
1418
1419 String closureClass = canBeShared ? cache[parameterCount] : null;
1406 if (closureClass == null) { 1420 if (closureClass == null) {
1407 // Either the class was not cached yet, or there are optional parameters. 1421 // Either the class was not cached yet, or there are optional parameters.
1408 // Create a new closure class. 1422 // Create a new closure class.
1409 SourceString name = const SourceString("BoundClosure"); 1423 SourceString name = const SourceString("BoundClosure");
1410 ClassElement closureClassElement = new ClosureClassElement( 1424 ClassElement closureClassElement = new ClosureClassElement(
1411 name, compiler, member, member.getCompilationUnit()); 1425 name, compiler, member, member.getCompilationUnit());
1412 String mangledName = namer.getName(closureClassElement); 1426 String mangledName = namer.getName(closureClassElement);
1413 String superName = namer.getName(closureClassElement.superclass); 1427 String superName = namer.getName(closureClassElement.superclass);
1414 needsClosureClass = true; 1428 needsClosureClass = true;
1415 1429
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 new js.This().dot(fieldNames[0]), 1461 new js.This().dot(fieldNames[0]),
1448 new js.This().dot(fieldNames[1])) 1462 new js.This().dot(fieldNames[1]))
1449 .callWith(arguments))])); 1463 .callWith(arguments))]));
1450 1464
1451 boundClosureBuffer.add( 1465 boundClosureBuffer.add(
1452 '$_$invocationName:$_${js.prettyPrint(fun,compiler)}'); 1466 '$_$invocationName:$_${js.prettyPrint(fun,compiler)}');
1453 1467
1454 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) { 1468 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) {
1455 boundClosureBuffer.add(',\n$_$stubName:$_$memberValue'); 1469 boundClosureBuffer.add(',\n$_$stubName:$_$memberValue');
1456 }); 1470 });
1471
1472 emitTypedefChecksOn(member.computeType(compiler), (Element typedef) {
1473 String operator = namer.operatorIs(typedef);
1474 boundClosureBuffer.add(',\n$_$operator$_:${_}true');
1475 });
1476
1457 boundClosureBuffer.add("$n}$N"); 1477 boundClosureBuffer.add("$n}$N");
1458 1478
1459 closureClass = namer.isolateAccess(closureClassElement); 1479 closureClass = namer.isolateAccess(closureClassElement);
1460 1480
1461 // Cache it. 1481 // Cache it.
1462 if (!hasOptionalParameters) { 1482 if (canBeShared) {
1463 cache[parameterCount] = closureClass; 1483 cache[parameterCount] = closureClass;
1464 } 1484 }
1465 } 1485 }
1466 1486
1467 // And finally the getter. 1487 // And finally the getter.
1468 String getterName = namer.getterName(member.getLibrary(), member.name); 1488 String getterName = namer.getterName(member.getLibrary(), member.name);
1469 String targetName = namer.instanceMethodName(member); 1489 String targetName = namer.instanceMethodName(member);
1470 1490
1471 List<js.Parameter> parameters = <js.Parameter>[]; 1491 List<js.Parameter> parameters = <js.Parameter>[];
1472 List<js.Expression> arguments = <js.Expression>[]; 1492 List<js.Expression> arguments = <js.Expression>[];
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
2084 """; 2104 """;
2085 const String HOOKS_API_USAGE = """ 2105 const String HOOKS_API_USAGE = """
2086 // The code supports the following hooks: 2106 // The code supports the following hooks:
2087 // dartPrint(message) - if this function is defined it is called 2107 // dartPrint(message) - if this function is defined it is called
2088 // instead of the Dart [print] method. 2108 // instead of the Dart [print] method.
2089 // dartMainRunner(main) - if this function is defined, the Dart [main] 2109 // dartMainRunner(main) - if this function is defined, the Dart [main]
2090 // method will not be invoked directly. 2110 // method will not be invoked directly.
2091 // Instead, a closure that will invoke [main] is 2111 // Instead, a closure that will invoke [main] is
2092 // passed to [dartMainRunner]. 2112 // passed to [dartMainRunner].
2093 """; 2113 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698