Remove JsInvocationMirror._invokeOn
I believe this was code only used via dart:mirrors
Soon we might want to rename JSInvocationMirror to just JsInvocation (so it's
clear that it is only used for nsm)
Change-Id: I0e0f836b18e6f290311c7173cfafedfcccab5c6f
Reviewed-on: https://dart-review.googlesource.com/69246
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 1f8bf50..fe6d994 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -892,10 +892,6 @@
ConstructorEntity get typeVariableConstructor => _typeVariableConstructor ??=
_env.lookupConstructor(typeVariableClass, '');
- FunctionEntity _invokeOnMethod;
- FunctionEntity get invokeOnMethod => _invokeOnMethod ??= _env
- .lookupLocalClassMember(jsInvocationMirrorClass, '_getCachedInvocation');
-
FunctionEntity _assertTest;
FunctionEntity get assertTest =>
_assertTest ??= _findHelperFunction('assertTest');
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index fa962df..6487088a 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -1184,21 +1184,9 @@
inferrer.updateSelectorInMember(
caller, _callType, _call, selector, typeMask);
- AbstractValue maskToUse =
- closedWorld.extendMaskIfReachesAll(selector, typeMask);
- bool canReachAll =
- closedWorld.backendUsage.isInvokeOnUsed && (maskToUse != typeMask);
-
- // If this call could potentially reach all methods that satisfy
- // the untyped selector (through noSuchMethod's `Invocation`
- // and a call to `delegate`), we iterate over all these methods to
- // update their parameter types.
_hasClosureCallTargets =
- closedWorld.includesClosureCall(selector, maskToUse);
- _concreteTargets = closedWorld.locateMembers(selector, maskToUse);
- Iterable<MemberEntity> typedTargets = canReachAll
- ? closedWorld.locateMembers(selector, typeMask)
- : _concreteTargets;
+ closedWorld.includesClosureCall(selector, typeMask);
+ _concreteTargets = closedWorld.locateMembers(selector, typeMask);
// Update the call graph if the targets could have changed.
if (!identical(_concreteTargets, oldTargets)) {
@@ -1237,14 +1225,6 @@
} else {
result = inferrer.types
.joinTypeMasks(_concreteTargets.map((MemberEntity element) {
- // If [canReachAll] is true, then we are iterating over all
- // targets that satisfy the untyped selector. We skip the return
- // type of the targets that can only be reached through
- // `Invocation.delegate`. Note that the `noSuchMethod` targets
- // are included in [typedTargets].
- if (canReachAll && !typedTargets.contains(element)) {
- return abstractValueDomain.emptyType;
- }
if (inferrer.returnsListElementType(selector, typeMask)) {
return abstractValueDomain.getContainerElementType(receiver.type);
} else if (inferrer.returnsMapValueType(selector, typeMask)) {
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index 3b7503c..75186d5 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -33,9 +33,6 @@
/// `true` if a core-library function requires the preamble file to function.
bool get requiresPreamble;
- /// `true` if [CommonElements.invokeOnMethod] is used.
- bool get isInvokeOnUsed;
-
/// `true` of `Object.runtimeType` is used.
bool get isRuntimeTypeUsed;
@@ -107,9 +104,6 @@
/// `true` if a core-library function requires the preamble file to function.
bool requiresPreamble = false;
- /// `true` if [CommonElements.invokeOnMethod] is used.
- bool isInvokeOnUsed = false;
-
/// `true` if `Function.apply` is used.
bool isFunctionApplyUsed = false;
@@ -227,8 +221,6 @@
_needToInitializeIsolateAffinityTag = true;
} else if (member == _commonElements.requiresPreambleMarker) {
requiresPreamble = true;
- } else if (member == _commonElements.invokeOnMethod) {
- isInvokeOnUsed = true;
} else if (_commonElements.isFunctionApplyMethod(member)) {
isFunctionApplyUsed = true;
} else if (member.library == _commonElements.mirrorsLibrary) {
@@ -266,7 +258,6 @@
needToInitializeIsolateAffinityTag: _needToInitializeIsolateAffinityTag,
needToInitializeDispatchProperty: _needToInitializeDispatchProperty,
requiresPreamble: requiresPreamble,
- isInvokeOnUsed: isInvokeOnUsed,
runtimeTypeUses: _runtimeTypeUses,
isFunctionApplyUsed: isFunctionApplyUsed,
isMirrorsUsed: isMirrorsUsed,
@@ -293,9 +284,6 @@
/// `true` if a core-library function requires the preamble file to function.
final bool requiresPreamble;
- /// `true` if [CommonElements.invokeOnMethod] is used.
- final bool isInvokeOnUsed;
-
/// `true` if `Function.apply` is used.
final bool isFunctionApplyUsed;
@@ -313,7 +301,6 @@
this.needToInitializeIsolateAffinityTag,
this.needToInitializeDispatchProperty,
this.requiresPreamble,
- this.isInvokeOnUsed,
Set<RuntimeTypeUse> runtimeTypeUses,
this.isFunctionApplyUsed,
this.isMirrorsUsed,
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index ad31900..8dd194e 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -377,10 +377,6 @@
subclassReadGenerator, interceptorsByTagAccess, leafTagsAccess);
}
- jsAst.ObjectInitializer generateInterceptedNamesSet() {
- return interceptorEmitter.generateInterceptedNamesSet();
- }
-
/// In minified mode we want to keep the name for the most common core types.
bool _isNativeTypeNeedingReflectionName(ClassEntity element) {
return (element == commonElements.intClass ||
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
index dc2f3c3..e7afba7 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/interceptor_emitter.dart
@@ -94,28 +94,6 @@
}
/**
- * If [JSInvocationMirror._invokeOn] has been compiled, emit all the
- * possible selector names that are intercepted into the
- * [interceptedNames] embedded global. The implementation of
- * [_invokeOn] will use it to determine whether it should call the
- * method with an extra parameter.
- */
- jsAst.ObjectInitializer generateInterceptedNamesSet() {
- // We could also generate the list of intercepted names at
- // runtime, by running through the subclasses of Interceptor
- // (which can easily be identified).
- if (!closedWorld.backendUsage.isInvokeOnUsed) return null;
-
- Iterable<jsAst.Name> invocationNames = interceptorInvocationNames.toList()
- ..sort();
- ;
- List<jsAst.Property> properties = invocationNames.map((jsAst.Name name) {
- return new jsAst.Property(js.quoteName(name), js.number(1));
- }).toList();
- return new jsAst.ObjectInitializer(properties, isOneLiner: true);
- }
-
- /**
* Emit initializer for `typeToInterceptorMap` data structure used by
* `findInterceptorForType`. See declaration of `typeToInterceptor` in
* `interceptors.dart`.
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
index 3017abe..a6a0143 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -37,8 +37,6 @@
emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPE_INFORMATION);
jsAst.Expression staticsAccess =
emitter.generateEmbeddedGlobalAccess(embeddedNames.STATICS);
- jsAst.Expression interceptedNamesAccess =
- emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES);
jsAst.Expression mangledGlobalNamesAccess =
emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
jsAst.Expression mangledNamesAccess =
@@ -94,9 +92,6 @@
'staticsPropertyName': namer.staticsPropertyName,
'staticsPropertyNameString': js.quoteName(namer.staticsPropertyName),
'typeInformation': typeInformationAccess,
- 'enabledInvokeOn': closedWorld.backendUsage.isInvokeOnUsed,
- 'interceptedNames': interceptedNamesAccess,
- 'interceptedNamesSet': emitter.generateInterceptedNamesSet(),
'notInCspMode': !compiler.options.useContentSecurityPolicy,
'inCspMode': compiler.options.useContentSecurityPolicy,
'deferredAction': namer.deferredAction,
@@ -681,10 +676,6 @@
funcs.push(f);
f.\$stubName = getterStubName;
f.\$callName = null;
- // Update the interceptedNames map (which only exists if `invokeOn` was
- // enabled).
- if (#enabledInvokeOn)
- if (isIntercepted) #interceptedNames[getterStubName] = 1;
}
if (#usesMangledNames) {
@@ -735,8 +726,6 @@
if (!#mangledGlobalNames) #mangledGlobalNames = map();
if (!#statics) #statics = map();
if (!#typeInformation) #typeInformation = map();
- if (#enabledInvokeOn)
- if (!#interceptedNames) #interceptedNames = #interceptedNamesSet;
var libraries = #libraries;
var mangledNames = #mangledNames;
var mangledGlobalNames = #mangledGlobalNames;
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 29f780b..2f434b5 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -439,7 +439,6 @@
needToInitializeDispatchProperty:
backendUsage.needToInitializeDispatchProperty,
requiresPreamble: backendUsage.requiresPreamble,
- isInvokeOnUsed: backendUsage.isInvokeOnUsed,
runtimeTypeUses: runtimeTypeUses,
isFunctionApplyUsed: backendUsage.isFunctionApplyUsed,
isMirrorsUsed: backendUsage.isMirrorsUsed,
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index fb37283..4e5b4ee 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -40,8 +40,7 @@
import '../universe/selector.dart';
import '../universe/side_effects.dart' show SideEffects;
import '../universe/target_checks.dart' show TargetChecks;
-import '../universe/use.dart'
- show ConstantUse, ConstrainedDynamicUse, StaticUse;
+import '../universe/use.dart' show ConstantUse, StaticUse;
import '../universe/world_builder.dart' show CodegenWorldBuilder;
import '../world.dart';
import 'graph_builder.dart';
@@ -4469,17 +4468,6 @@
_elementMap.getClass(_containingClass(invocation));
FunctionEntity noSuchMethod =
_elementMap.getSuperNoSuchMethod(containingClass);
- if (backendUsage.isInvokeOnUsed &&
- noSuchMethod.enclosingClass != _commonElements.objectClass) {
- // Register the call as dynamic if [noSuchMethod] on the super
- // class is _not_ the default implementation from [Object] (it might be
- // overridden in the super class, but it might have a different number of
- // arguments), in case the [noSuchMethod] implementation calls
- // [JSInvocationMirror._invokeOn].
- // TODO(johnniwinther): Register this more precisely.
- registry
- ?.registerDynamicUse(new ConstrainedDynamicUse(selector, null, null));
- }
ConstantValue nameConstant = constantSystem.createString(publicName);
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 2b1adbc..b92ef53 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -1849,9 +1849,7 @@
return _abstractValueDomain.createNonNullSubtype(enclosing);
}
}
- // If [JSInvocationMirror._invokeOn] is enabled, and this call
- // might hit a `noSuchMethod`, we register an untyped selector.
- return _closedWorld.extendMaskIfReachesAll(selector, mask);
+ return mask ?? _abstractValueDomain.dynamicType;
}
void registerMethodInvoke(HInvokeDynamic node) {
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 652cde7..3fa6e2e 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -161,11 +161,6 @@
/// Returns `true` if the field [element] is known to be effectively final.
bool fieldNeverChanges(MemberEntity element);
- /// Extends the [receiver] type for calling [selector] to take live
- /// `noSuchMethod` handlers into account.
- AbstractValue extendMaskIfReachesAll(
- Selector selector, AbstractValue receiver);
-
/// Returns `true` if [selector] on [receiver] can hit a `call` method on a
/// subclass of `Closure`.
///
@@ -570,16 +565,6 @@
return abstractValueDomain.locateSingleMember(receiver, selector);
}
- AbstractValue extendMaskIfReachesAll(
- Selector selector, AbstractValue receiver) {
- bool canReachAll = true;
- if (receiver != null) {
- canReachAll = backendUsage.isInvokeOnUsed &&
- abstractValueDomain.needsNoSuchMethodHandling(receiver, selector);
- }
- return canReachAll ? abstractValueDomain.dynamicType : receiver;
- }
-
bool fieldNeverChanges(MemberEntity element) {
if (!element.isField) return false;
if (nativeData.isNativeMember(element)) {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index f656680..e1f8946 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -377,171 +377,6 @@
}
return new ConstantMapView<Symbol, dynamic>(map);
}
-
- _getCachedInvocation(Object object) {
- var interceptor = getInterceptor(object);
- var receiver = object;
- var name = _internalName;
- var arguments = _arguments;
- var interceptedNames = JS_EMBEDDED_GLOBAL('', INTERCEPTED_NAMES);
- bool isIntercepted = JS('bool',
- 'Object.prototype.hasOwnProperty.call(#, #)', interceptedNames, name);
- if (isIntercepted) {
- receiver = interceptor;
- if (JS('bool', '# === #', object, interceptor)) {
- interceptor = null;
- }
- } else {
- interceptor = null;
- }
- bool isCatchAll = false;
- var method = JS('var', '#[#]', receiver, name);
- if (JS('bool', 'typeof # != "function"', method)) {
- String baseName = _symbol_dev.Symbol.getName(memberName);
- method = JS('', '#[# + "*"]', receiver, baseName);
- if (method == null) {
- interceptor = getInterceptor(object);
- method = JS('', '#[# + "*"]', interceptor, baseName);
- if (method != null) {
- isIntercepted = true;
- receiver = interceptor;
- } else {
- interceptor = null;
- }
- }
- isCatchAll = true;
- }
- if (JS('bool', 'typeof # == "function"', method)) {
- if (isCatchAll) {
- return new CachedCatchAllInvocation(
- name, method, isIntercepted, interceptor);
- } else {
- return new CachedInvocation(name, method, isIntercepted, interceptor);
- }
- } else {
- // In this case, receiver doesn't implement name. So we should
- // invoke noSuchMethod instead (which will often throw a
- // NoSuchMethodError).
- return new CachedNoSuchMethodInvocation(interceptor);
- }
- }
-
- /// This method is called by [InstanceMirror.delegate].
- static invokeFromMirror(JSInvocationMirror invocation, Object victim) {
- var cached = invocation._getCachedInvocation(victim);
- if (cached.isNoSuchMethod) {
- return cached.invokeOn(victim, invocation);
- } else {
- return cached.invokeOn(victim, invocation._arguments);
- }
- }
-
- static getCachedInvocation(JSInvocationMirror invocation, Object victim) {
- return invocation._getCachedInvocation(victim);
- }
-}
-
-class CachedInvocation {
- // The mangled name of this invocation.
- String mangledName;
-
- /// The JS function to call.
- var jsFunction;
-
- /// True if this is an intercepted call.
- bool isIntercepted;
-
- /// Non-null interceptor if this is an intercepted call through an
- /// [Interceptor].
- Interceptor cachedInterceptor;
-
- CachedInvocation(this.mangledName, this.jsFunction, this.isIntercepted,
- this.cachedInterceptor);
-
- bool get isNoSuchMethod => false;
- bool get isGetterStub => JS('bool', '!!#.\$getterStub', jsFunction);
-
- /// Applies [jsFunction] to [victim] with [arguments].
- /// Users of this class must take care to check the arguments first.
- invokeOn(Object victim, List arguments) {
- var receiver = victim;
- if (!isIntercepted) {
- if (arguments is! JSArray) arguments = new List.from(arguments);
- } else {
- arguments = [victim]..addAll(arguments);
- if (cachedInterceptor != null) receiver = cachedInterceptor;
- }
- return JS('var', '#.apply(#, #)', jsFunction, receiver, arguments);
- }
-}
-
-class CachedCatchAllInvocation extends CachedInvocation {
- final ReflectionInfo info;
-
- CachedCatchAllInvocation(String name, jsFunction, bool isIntercepted,
- Interceptor cachedInterceptor)
- : info = new ReflectionInfo(jsFunction),
- super(name, jsFunction, isIntercepted, cachedInterceptor);
-
- bool get isGetterStub => false;
-
- invokeOn(Object victim, List arguments) {
- var receiver = victim;
- int providedArgumentCount;
- int fullParameterCount =
- info.requiredParameterCount + info.optionalParameterCount;
- if (!isIntercepted) {
- if (arguments is JSArray) {
- providedArgumentCount = arguments.length;
- // If we need to add extra arguments before calling, we have
- // to copy the arguments array.
- if (providedArgumentCount < fullParameterCount) {
- arguments = new List.from(arguments);
- }
- } else {
- arguments = new List.from(arguments);
- providedArgumentCount = arguments.length;
- }
- } else {
- arguments = [victim]..addAll(arguments);
- if (cachedInterceptor != null) receiver = cachedInterceptor;
- providedArgumentCount = arguments.length - 1;
- }
- if (info.areOptionalParametersNamed &&
- (providedArgumentCount > info.requiredParameterCount)) {
- throw new UnimplementedNoSuchMethodError(
- "Invocation of unstubbed method '${info.reflectionName}'"
- " with ${arguments.length} arguments.");
- } else if (providedArgumentCount < info.requiredParameterCount) {
- throw new UnimplementedNoSuchMethodError(
- "Invocation of unstubbed method '${info.reflectionName}'"
- " with $providedArgumentCount arguments (too few).");
- } else if (providedArgumentCount > fullParameterCount) {
- throw new UnimplementedNoSuchMethodError(
- "Invocation of unstubbed method '${info.reflectionName}'"
- " with $providedArgumentCount arguments (too many).");
- }
- for (int i = providedArgumentCount; i < fullParameterCount; i++) {
- arguments.add(getMetadata(info.defaultValue(i)));
- }
- return JS('var', '#.apply(#, #)', jsFunction, receiver, arguments);
- }
-}
-
-class CachedNoSuchMethodInvocation {
- /// Non-null interceptor if this is an intercepted call through an
- /// [Interceptor].
- var interceptor;
-
- CachedNoSuchMethodInvocation(this.interceptor);
-
- bool get isNoSuchMethod => true;
- bool get isGetterStub => false;
-
- invokeOn(Object victim, Invocation invocation) {
- var receiver = (interceptor == null) ? victim : interceptor;
- return receiver.noSuchMethod(invocation);
- }
}
class ReflectionInfo {
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index 284232a..bc10677 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -65,11 +65,6 @@
/// runtime-type-information (rti) object.
const GET_TYPE_FROM_NAME = 'getTypeFromName';
-/// If [JSInvocationMirror._invokeOn] is being used, this embedded global
-/// contains a JavaScript map with the names of methods that are
-/// intercepted.
-const INTERCEPTED_NAMES = 'interceptedNames';
-
/// A JS map from mangled global names to their unmangled names.
///
/// If the program does not use reflection, this embedded global may be empty