[dart2js] new-rti: experiment - fault in '$is' test Change-Id: Ie6d17e3439fb67fe79e9dec4dc7cb5437d1f6915 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121766 Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Stephen Adams <sra@google.com>
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart index c797e3b..fd7df4d 100644 --- a/pkg/compiler/lib/src/js_backend/namer.dart +++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -2571,6 +2571,8 @@ return asName(fixedNames.deferredAction); case JsGetName.OPERATOR_AS_PREFIX: return asName(fixedNames.operatorAsPrefix); + case JsGetName.OPERATOR_IS_PREFIX: + return asName(fixedNames.operatorIsPrefix); case JsGetName.SIGNATURE_NAME: return asName(fixedNames.operatorSignature); case JsGetName.RTI_NAME:
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart index 30b9964..5a8d3b9 100644 --- a/sdk/lib/_internal/js_runtime/lib/rti.dart +++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -109,6 +109,18 @@ rti._precomputed1 = precomputed; } + // Data value used by some tests. + @pragma('dart2js:noElision') + Object _specializedTestResource; + + static Object _getSpecializedTestResource(Rti rti) { + return rti._specializedTestResource; + } + + static void _setSpecializedTestResource(Rti rti, Object value) { + rti._specializedTestResource = value; + } + // The Type object corresponding to this Rti. Object _cachedRuntimeType; static _Type _getCachedRuntimeType(Rti rti) => @@ -549,6 +561,9 @@ return result; } +bool _isDartObject(object) => _Utils.instanceOf(object, + JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartObjectConstructor)); + bool _isClosure(object) => _Utils.instanceOf(object, JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor)); @@ -597,10 +612,7 @@ // called, similar to a one-shot interceptor call. This would improve type // lookup in ListMixin code as the interceptor is JavaScript 'this'. - if (_Utils.instanceOf( - object, - JS_BUILTIN( - 'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) { + if (_isDartObject(object)) { return _instanceType(object); } @@ -762,6 +774,16 @@ isFn = RAW_DART_FUNCTION_REF(_isString); } else if (JS_GET_NAME(JsGetName.BOOL_RECIPE) == key) { isFn = RAW_DART_FUNCTION_REF(_isBool); + } else { + String name = Rti._getInterfaceName(testRti); + var arguments = Rti._getInterfaceTypeArguments(testRti); + if (JS( + 'bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) { + String propertyName = + '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}'; + Rti._setSpecializedTestResource(testRti, propertyName); + isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty); + } } } @@ -779,6 +801,24 @@ } /// Called from generated code. +bool _isTestViaProperty(object) { + // This static method is installed on an Rti object as a JavaScript instance + // method. The Rti object is 'this'. + Rti testRti = _castToRti(JS('', 'this')); + var tag = Rti._getSpecializedTestResource(testRti); + + // This test is redundant with getInterceptor below, but getInterceptor does + // the tests in the wrong order for most tags, so it is usually faster to have + // this check. + if (_isDartObject(object)) { + return JS('bool', '!!#[#]', object, tag); + } + + var interceptor = getInterceptor(object); + return JS('bool', '!!#[#]', interceptor, tag); +} + +/// Called from generated code. _generalAsCheckImplementation(object) { if (object == null) return object; // This static method is installed on an Rti object as a JavaScript instance
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart index 2b00f2f..9b9e648 100644 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart +++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -111,6 +111,18 @@ rti._precomputed1 = precomputed; } + // Data value used by some tests. + @pragma('dart2js:noElision') + Object _specializedTestResource; + + static Object _getSpecializedTestResource(Rti rti) { + return rti._specializedTestResource; + } + + static void _setSpecializedTestResource(Rti rti, Object value) { + rti._specializedTestResource = value; + } + // The Type object corresponding to this Rti. Object _cachedRuntimeType; static _Type _getCachedRuntimeType(Rti rti) => @@ -551,6 +563,9 @@ return result; } +bool _isDartObject(object) => _Utils.instanceOf(object, + JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartObjectConstructor)); + bool _isClosure(object) => _Utils.instanceOf(object, JS_BUILTIN('depends:none;effects:none;', JsBuiltin.dartClosureConstructor)); @@ -599,10 +614,7 @@ // called, similar to a one-shot interceptor call. This would improve type // lookup in ListMixin code as the interceptor is JavaScript 'this'. - if (_Utils.instanceOf( - object, - JS_BUILTIN( - 'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) { + if (_isDartObject(object)) { return _instanceType(object); } @@ -764,6 +776,16 @@ isFn = RAW_DART_FUNCTION_REF(_isString); } else if (JS_GET_NAME(JsGetName.BOOL_RECIPE) == key) { isFn = RAW_DART_FUNCTION_REF(_isBool); + } else { + String name = Rti._getInterfaceName(testRti); + var arguments = Rti._getInterfaceTypeArguments(testRti); + if (JS( + 'bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) { + String propertyName = + '${JS_GET_NAME(JsGetName.OPERATOR_IS_PREFIX)}${name}'; + Rti._setSpecializedTestResource(testRti, propertyName); + isFn = RAW_DART_FUNCTION_REF(_isTestViaProperty); + } } } @@ -781,6 +803,24 @@ } /// Called from generated code. +bool _isTestViaProperty(object) { + // This static method is installed on an Rti object as a JavaScript instance + // method. The Rti object is 'this'. + Rti testRti = _castToRti(JS('', 'this')); + var tag = Rti._getSpecializedTestResource(testRti); + + // This test is redundant with getInterceptor below, but getInterceptor does + // the tests in the wrong order for most tags, so it is usually faster to have + // this check. + if (_isDartObject(object)) { + return JS('bool', '!!#[#]', object, tag); + } + + var interceptor = getInterceptor(object); + return JS('bool', '!!#[#]', interceptor, tag); +} + +/// Called from generated code. _generalAsCheckImplementation(object) { if (object == null) return object; // This static method is installed on an Rti object as a JavaScript instance