blob: b00e25a998c26b3499e09c73dde8adef5b4aee37 [file] [edit]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of "core_patch.dart";
/// Base class for closure objects.
final class _Closure implements Function {
@pragma("wasm:entry-point")
final WasmStructRef context;
@pragma("wasm:entry-point")
_Closure._(this.context);
@override
bool operator ==(Object other) {
if (other is! _Closure) {
return false;
}
if (identical(this, other)) {
return true;
}
final thisIsInstantiation = _isInstantiationClosure;
final otherIsInstantiation = other._isInstantiationClosure;
if (thisIsInstantiation != otherIsInstantiation) {
return false;
}
if (thisIsInstantiation) {
final thisInstantiatedClosure = _instantiatedClosure;
final otherInstantiatedClosure = other._instantiatedClosure;
return thisInstantiatedClosure == otherInstantiatedClosure &&
_instantiationClosureTypeEquals(other);
}
if (_vtable != other._vtable) {
return false;
}
final thisIsTearOff = _isInstanceTearOff;
final otherIsTearOff = other._isInstanceTearOff;
if (thisIsTearOff != otherIsTearOff) {
return false;
}
if (thisIsTearOff) {
return _instanceTearOffReceiver == other._instanceTearOffReceiver;
}
return false;
}
@pragma("wasm:entry-point")
@pragma("wasm:prefer-inline")
@pragma("wasm:intrinsic")
external static _FunctionType _getClosureRuntimeType(_Closure closure);
@override
int get hashCode {
if (_isInstantiationClosure) {
return Object.hash(_instantiatedClosure, _instantiationClosureTypeHash());
}
if (_isInstanceTearOff) {
return Object.hash(
_instanceTearOffReceiver,
_getClosureRuntimeType(this),
);
}
return Object._objectHashCode(this); // identity hash
}
// Support dynamic tear-off of `.call` on functions
@pragma("wasm:entry-point")
Function get call => this;
@override
String toString() => 'Closure: $runtimeType';
// Helpers for implementing `hashCode`, `operator ==`.
/// Whether the closure is an instantiation.
@pragma("wasm:intrinsic")
external bool get _isInstantiationClosure;
/// When the closure is an instantiation, get the instantiated closure.
///
/// Traps when the closure is not an instantiation.
@pragma("wasm:intrinsic")
external _Closure get _instantiatedClosure;
/// When the closure is an instantiation, returns the combined hash code of
/// the captured types.
///
/// Traps when the closure is not an instantiation.
@pragma("wasm:intrinsic")
external int _instantiationClosureTypeHash();
/// When this [_Closure] and [other] are instantiations, compare captured
/// types for equality.
///
/// Traps when one or both of the closures are not an instantiation.
@pragma("wasm:intrinsic")
external bool _instantiationClosureTypeEquals(_Closure other);
/// Whether the closure is an instance tear-off.
///
/// Instance tear-offs will have receivers.
@pragma("wasm:intrinsic")
external bool get _isInstanceTearOff;
/// When the closure is an instance tear-off, returns the receiver.
///
/// Traps when the closure is not an instance tear-off.
@pragma("wasm:intrinsic")
external Object? get _instanceTearOffReceiver;
/// The vtable of the closure.
@pragma("wasm:intrinsic")
external WasmAnyRef get _vtable;
}