[ddc] Move null check to JS foreign function in isDartClass and isDartFunction

The Dart != check lowers to !== in JS. The RTI property doesn't
exist in the JS function, so the result is undefined. However,
undefined !== null returns true, so JS functions are accidentally
treated as Dart functions. This fixes that.

Change-Id: I4c4e0018768c0ac29f4b5ee228c504b7cb0b7232
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/369200
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
Srujan Gaddam
2024-06-14 20:46:20 +00:00
committed by Commit Queue
parent 2cd388617e
commit 25a9fc0aab
@@ -137,8 +137,12 @@ F assertInterop<F extends Function?>(F f) {
bool isDartClass(Object? obj) {
// All Dart classes are instances of JavaScript functions.
if (!JS<bool>('!', '# instanceof Function', obj)) return false;
// All Dart classes have an interface type recipe attached to them.
return JS('', '#.#', obj, rti.interfaceTypeRecipePropertyName) != null;
// All Dart classes have an interface type recipe attached to them. We put the
// `!=` check in the foreign function call, since the Dart `!=` check would
// lower to `!==`. In the case where [obj] is a JS function, the result of
// getting this property would be `undefined`, and therefore `!== null` would
// be true, which is not what we want.
return JS<bool>('!', '#.# != null', obj, rti.interfaceTypeRecipePropertyName);
}
/// Returns `true` when [obj] represents a Dart function.
@@ -146,8 +150,13 @@ bool isDartClass(Object? obj) {
bool isDartFunction(Object? obj) {
// All Dart functions are instances of JavaScript functions.
if (!JS<bool>('!', '# instanceof Function', obj)) return false;
// All Dart functions have a signature attached to them.
return JS('!', '#[#]', obj, JS_GET_NAME(JsGetName.SIGNATURE_NAME)) != null;
// All Dart functions have a signature attached to them. We put the `!=` check
// in the foreign function call, since the Dart `!=` check would lower to
// `!==`. In the case where [obj] is a JS function, the result of getting this
// property would be `undefined`, and therefore `!== null` would be true,
// which is not what we want.
return JS<bool>(
'!', '#[#] != null', obj, JS_GET_NAME(JsGetName.SIGNATURE_NAME));
}
Expando<Function> _assertInteropExpando = Expando<Function>();