| 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..948741fc5964f789a18e4dbb7d8430974537977a 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,38 @@ 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);
|
| + Map<String, Selector> jsNames = <String, Selector>{};
|
|
|
| - // 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>();
|
| + Map<String, Selector> computeSelectorsForNsmHandlers() {
|
| + // Do not generate no such method handlers if there is no class.
|
| + if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) {
|
| + return jsNames;
|
| + }
|
|
|
| - 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);
|
| + return jsNames;
|
| + }
|
|
|
| - 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 +62,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 +71,7 @@ class NsmEmitter extends CodeEmitterHelper {
|
| #type,
|
| #arguments,
|
| #namedArguments))''',
|
| - {'noSuchMethodName': noSuchMethodName,
|
| + {'noSuchMethodName': namer.noSuchMethodName,
|
| 'createInvocationMirror':
|
| backend.emitter.staticFunctionAccess(
|
| backend.getCreateInvocationMirror()),
|
| @@ -109,12 +92,36 @@ 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 = computeSelectorsForNsmHandlers();
|
| +
|
| + // 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 +288,6 @@ 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);
|
| var type = 0;
|
| if (useDiffEncoding) {
|
| statements.add(js.statement('''{
|
| @@ -386,7 +391,7 @@ class NsmEmitter extends CodeEmitterHelper {
|
| }
|
| }''', {
|
| 'sliceOffsetParams': sliceOffsetParams,
|
| - 'noSuchMethodName': noSuchMethodName,
|
| + 'noSuchMethodName': namer.noSuchMethodName,
|
| 'createInvocationMirror': createInvocationMirror,
|
| 'names': minify ? 'shortNames' : 'longNames',
|
| 'sliceOffsetArguments': sliceOffsetArguments}));
|
|
|