Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart (revision 16252) |
| +++ sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart (working copy) |
| @@ -1112,6 +1112,16 @@ |
| } |
| } |
| + void emitTypedefChecksOn(DartType type, void emitTest(Element element)) { |
|
floitsch
2012/12/19 10:39:34
Rename to forEachTypedefCheckOf
Ideally this shou
|
| + for (TypedefElement typedef in checkedTypedefs) { |
| + FunctionType typedefType = |
| + typedef.computeType(compiler).unalias(compiler); |
| + if (compiler.types.isSubtype(type, typedefType)) { |
| + emitTest(typedef); |
| + } |
| + } |
| + } |
| + |
| /** |
| * Generate "is tests" for [cls]: itself, and the "is tests" for the |
| * classes it implements. We don't need to add the "is tests" of the |
| @@ -1137,14 +1147,7 @@ |
| generateInterfacesIsTests(compiler.functionClass, |
| emitIsTest, |
| generated); |
| - FunctionType callType = call.computeType(compiler); |
| - for (TypedefElement typedef in checkedTypedefs) { |
| - FunctionType typedefType = |
| - typedef.computeType(compiler).unalias(compiler); |
| - if (compiler.types.isSubtype(callType, typedefType)) { |
| - emitIsTest(typedef); |
| - } |
| - } |
| + emitTypedefChecksOn(call.computeType(compiler), emitIsTest); |
| } |
| } |
| for (DartType interfaceType in cls.interfaces) { |
| @@ -1341,6 +1344,10 @@ |
| // in case it is used in spawnFunction. |
| String fieldName = namer.STATIC_CLOSURE_NAME_NAME; |
| buffer.add('$fieldAccess.$fieldName$_=$_"$staticName"$N'); |
| + emitTypedefChecksOn(element.computeType(compiler), (Element typedef) { |
| + String operator = namer.operatorIs(typedef); |
| + buffer.add('$fieldAccess.$operator$_=${_}true$N'); |
| + }); |
| } |
| } |
| @@ -1402,7 +1409,14 @@ |
| : inInterceptor ? const ['self', 'target', 'receiver'] |
| : const ['self', 'target']; |
| - String closureClass = hasOptionalParameters ? null : cache[parameterCount]; |
| + bool hasTypedefChecks = false; |
| + emitTypedefChecksOn(member.computeType(compiler), (Element typedef) { |
| + hasTypedefChecks = true; |
| + }); |
| + |
| + bool canBeShared = !hasOptionalParameters && !hasTypedefChecks; |
| + |
| + String closureClass = canBeShared ? cache[parameterCount] : null; |
| if (closureClass == null) { |
| // Either the class was not cached yet, or there are optional parameters. |
| // Create a new closure class. |
| @@ -1454,12 +1468,18 @@ |
| addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) { |
| boundClosureBuffer.add(',\n$_$stubName:$_$memberValue'); |
| }); |
| + |
| + emitTypedefChecksOn(member.computeType(compiler), (Element typedef) { |
| + String operator = namer.operatorIs(typedef); |
| + boundClosureBuffer.add(',\n$_$operator$_:${_}true'); |
| + }); |
| + |
| boundClosureBuffer.add("$n}$N"); |
| closureClass = namer.isolateAccess(closureClassElement); |
| // Cache it. |
| - if (!hasOptionalParameters) { |
| + if (canBeShared) { |
| cache[parameterCount] = closureClass; |
| } |
| } |