Chromium Code Reviews| Index: pkg/compiler/lib/src/js_emitter/old_emitter/nsm_emitter.dart |
| diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/nsm_emitter.dart |
| index 3096ff76f7413b5267a04ecf3c949aa4d7f32294..89b1e268861b815cc00b05da26d75ca76b4f6126 100644 |
| --- a/pkg/compiler/lib/src/js_emitter/old_emitter/nsm_emitter.dart |
| +++ b/pkg/compiler/lib/src/js_emitter/old_emitter/nsm_emitter.dart |
| @@ -19,48 +19,34 @@ class NsmEmitter extends CodeEmitterHelper { |
| static const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4; |
| void emitNoSuchMethodHandlers(AddPropertyFunction addProperty) { |
| - // Do not generate no such method handlers if there is no class. |
| - if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) return; |
| - String noSuchMethodName = namer.publicInstanceMethodNameByArity( |
| - Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); |
| + void computeSelectorsForNsmHandlers(Map<String, Selector> jsNames) { |
| - // Keep track of the JavaScript names we've already added so we |
| - // do not introduce duplicates (bad for code size). |
| - Map<String, Selector> addedJsNames = new Map<String, Selector>(); |
| + // Do not generate no such method handlers if there is no class. |
| + if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) return; |
| - void addNoSuchMethodHandlers(String ignore, Set<Selector> selectors) { |
| - // Cache the object class and type. |
| - ClassElement objectClass = compiler.objectClass; |
| - DartType objectType = objectClass.rawType; |
| + void addNoSuchMethodHandlers(String ignore, Set<Selector> selectors) { |
| + TypeMask objectSubclassTypeMask = |
| + new TypeMask.subclass(compiler.objectClass, compiler.world); |
| - for (Selector selector in selectors) { |
| - TypeMask mask = selector.mask; |
| - if (mask == null) { |
| - mask = new TypeMask.subclass(compiler.objectClass, compiler.world); |
| - } |
| + for (Selector selector in selectors) { |
| + TypeMask mask = selector.mask; |
| + if (mask == null) mask = objectSubclassTypeMask; |
| - if (!mask.needsNoSuchMethodHandling(selector, compiler.world)) continue; |
| - String jsName = namer.invocationMirrorInternalName(selector); |
| - addedJsNames[jsName] = selector; |
| - String reflectionName = emitter.getReflectionName(selector, jsName); |
| - if (reflectionName != null) { |
| - emitter.mangledFieldNames[jsName] = reflectionName; |
| + if (!mask.needsNoSuchMethodHandling(selector, compiler.world)) { |
| + continue; |
| + } |
| + String jsName = namer.invocationMirrorInternalName(selector); |
| + jsNames[jsName] = selector; |
| } |
| } |
| - } |
| - |
| - compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); |
| - compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); |
| - compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); |
| - // Set flag used by generateMethod helper below. If we have very few |
| - // handlers we use addProperty for them all, rather than try to generate |
| - // them at runtime. |
| - bool haveVeryFewNoSuchMemberHandlers = |
| - (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS); |
| + compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); |
| + compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); |
| + compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); |
| + } |
| - jsAst.Expression generateMethod(String jsName, Selector selector) { |
| + jsAst.Expression generateMethod(Selector selector) { |
| // Values match JSInvocationMirror in js-helper library. |
| int type = selector.invocationMirrorKind; |
| List<String> parameterNames = |
| @@ -72,13 +58,6 @@ class NsmEmitter extends CodeEmitterHelper { |
| String methodName = selector.invocationMirrorMemberName; |
| String internalName = namer.invocationMirrorInternalName(selector); |
| - String reflectionName = emitter.getReflectionName(selector, internalName); |
| - if (!haveVeryFewNoSuchMemberHandlers && |
| - isTrivialNsmHandler(type, argNames, selector, internalName) && |
| - reflectionName == null) { |
| - trivialNsmHandlers.add(selector); |
| - return null; |
| - } |
| assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD)); |
| jsAst.Expression expression = |
| @@ -88,7 +67,7 @@ class NsmEmitter extends CodeEmitterHelper { |
| #type, |
| #arguments, |
| #namedArguments))''', |
| - {'noSuchMethodName': noSuchMethodName, |
| + {'noSuchMethodName': namer.noSuchMethodName, |
| 'createInvocationMirror': |
| backend.emitter.staticFunctionAccess( |
| backend.getCreateInvocationMirror()), |
| @@ -109,12 +88,37 @@ class NsmEmitter extends CodeEmitterHelper { |
| } |
| } |
| + // Keep track of the JavaScript names we've already added so we |
| + // do not introduce duplicates (bad for code size). |
| + Map<String, Selector> addedJsNames = new Map<String, Selector>(); |
| + computeSelectorsForNsmHandlers(addedJsNames); |
|
floitsch
2015/02/03 10:56:02
Let the computeSelectors return the map.
zarah
2015/02/03 11:06:50
Done.
|
| + |
| + // Set flag used by generateMethod helper below. If we have very few |
| + // handlers we use addProperty for them all, rather than try to generate |
| + // them at runtime. |
| + bool haveVeryFewNoSuchMemberHandlers = |
| + (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS); |
| for (String jsName in addedJsNames.keys.toList()..sort()) { |
| Selector selector = addedJsNames[jsName]; |
| - jsAst.Expression method = generateMethod(jsName, selector); |
| + String reflectionName = emitter.getReflectionName(selector, jsName); |
| + |
| + if (reflectionName != null) { |
| + emitter.mangledFieldNames[jsName] = reflectionName; |
| + } |
| + |
| + List<jsAst.Expression> argNames = |
| + selector.getOrderedNamedArguments().map((String name) => |
| + js.string(name)).toList(); |
| + int type = selector.invocationMirrorKind; |
| + if (!haveVeryFewNoSuchMemberHandlers && |
| + isTrivialNsmHandler(type, argNames, selector, jsName) && |
| + reflectionName == null) { |
| + trivialNsmHandlers.add(selector); |
| + } |
| + |
| + jsAst.Expression method = generateMethod(selector); |
| if (method != null) { |
| addProperty(jsName, method); |
| - String reflectionName = emitter.getReflectionName(selector, jsName); |
| if (reflectionName != null) { |
| bool accessible = compiler.world.allFunctions.filter(selector).any( |
| (Element e) => backend.isAccessibleByReflection(e)); |
| @@ -281,8 +285,7 @@ class NsmEmitter extends CodeEmitterHelper { |
| ClassElement objectClass = compiler.objectClass; |
| jsAst.Expression createInvocationMirror = backend.emitter |
| .staticFunctionAccess(backend.getCreateInvocationMirror()); |
| - String noSuchMethodName = namer.publicInstanceMethodNameByArity( |
| - Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); |
| + String noSuchMethodName = namer.noSuchMethodName; |
|
floitsch
2015/02/03 10:56:02
might as well inline it to its use site.
zarah
2015/02/03 11:06:50
Done.
|
| var type = 0; |
| if (useDiffEncoding) { |
| statements.add(js.statement('''{ |