LibJS: Remove FinalizationRegistry cleanupSome
The cleanupSome proposal was withdrawn, and other engines no longer expose this method by default. Stop installing it on FinalizationRegistry.prototype while keeping the internal cleanup path used for queued cleanup jobs. Add a test-js helper for invoking that internal cleanup path directly. Move the FinalizationRegistry cleanup coverage onto it so callbacks unregistering later dead records remain covered without exposing the withdrawn API to JavaScript programs. Fixes #2228
This commit is contained in:
parent
209579c964
commit
8ff0577dea
5 changed files with 30 additions and 32 deletions
|
|
@ -74,7 +74,6 @@ namespace JS {
|
|||
P(ceil) \
|
||||
P(charAt) \
|
||||
P(charCodeAt) \
|
||||
P(cleanupSome) \
|
||||
P(clear) \
|
||||
P(clz32) \
|
||||
P(codePointAt) \
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ void FinalizationRegistryPrototype::initialize(Realm& realm)
|
|||
Base::initialize(realm);
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
|
||||
define_native_function(realm, vm.names.cleanupSome, cleanup_some, 0, attr);
|
||||
define_native_function(realm, vm.names.register_, register_, 2, attr);
|
||||
define_native_function(realm, vm.names.unregister, unregister, 1, attr);
|
||||
|
||||
|
|
@ -31,28 +30,6 @@ void FinalizationRegistryPrototype::initialize(Realm& realm)
|
|||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, vm.names.FinalizationRegistry.as_string()), Attribute::Configurable);
|
||||
}
|
||||
|
||||
// @STAGE 2@ FinalizationRegistry.prototype.cleanupSome ( [ callback ] ), https://github.com/tc39/proposal-cleanup-some/blob/master/spec/finalization-registry.html
|
||||
JS_DEFINE_NATIVE_FUNCTION(FinalizationRegistryPrototype::cleanup_some)
|
||||
{
|
||||
auto callback = vm.argument(0);
|
||||
|
||||
// 1. Let finalizationRegistry be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(finalizationRegistry, [[Cells]]).
|
||||
auto finalization_registry = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If callback is present and IsCallable(callback) is false, throw a TypeError exception.
|
||||
if (vm.argument_count() > 0 && !callback.is_function())
|
||||
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, callback);
|
||||
|
||||
// IMPLEMENTATION DEFINED: The specification for this function hasn't been updated to accommodate for JobCallback records.
|
||||
// This just follows how the constructor immediately converts the callback to a JobCallback using HostMakeJobCallback.
|
||||
// 4. Perform ? CleanupFinalizationRegistry(finalizationRegistry, callback).
|
||||
TRY(finalization_registry->cleanup(callback.is_undefined() ? GC::Ptr<JobCallback> {} : vm.host_make_job_callback(callback.as_function())));
|
||||
|
||||
// 5. Return undefined.
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
// 26.2.3.2 FinalizationRegistry.prototype.register ( target, heldValue [ , unregisterToken ] ), https://tc39.es/ecma262/#sec-finalization-registry.prototype.register
|
||||
JS_DEFINE_NATIVE_FUNCTION(FinalizationRegistryPrototype::register_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ public:
|
|||
private:
|
||||
explicit FinalizationRegistryPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(cleanup_some);
|
||||
JS_DECLARE_NATIVE_FUNCTION(register_);
|
||||
JS_DECLARE_NATIVE_FUNCTION(unregister);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
test("length is 0", () => {
|
||||
expect(FinalizationRegistry.prototype.cleanupSome).toHaveLength(0);
|
||||
test("cleanupSome is not exposed", () => {
|
||||
expect(FinalizationRegistry.prototype.cleanupSome).toBeUndefined();
|
||||
});
|
||||
|
||||
function registerInDifferentScope(registry) {
|
||||
|
|
@ -16,7 +16,7 @@ test.xfail("basic functionality", () => {
|
|||
count++;
|
||||
};
|
||||
|
||||
registry.cleanupSome(increment);
|
||||
cleanupFinalizationRegistry(registry, increment);
|
||||
|
||||
expect(count).toBe(0);
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ test.xfail("basic functionality", () => {
|
|||
markAsGarbage("target");
|
||||
gc();
|
||||
|
||||
registry.cleanupSome(increment);
|
||||
cleanupFinalizationRegistry(registry, increment);
|
||||
|
||||
expect(count).toBe(1);
|
||||
});
|
||||
|
|
@ -45,16 +45,20 @@ test("callback can unregister the next record after the current record dies", ()
|
|||
markAsGarbage("__finalizationRegistrySecond");
|
||||
gc();
|
||||
|
||||
registry.cleanupSome();
|
||||
cleanupFinalizationRegistry(registry);
|
||||
|
||||
expect(heldValues).toEqual(["first"]);
|
||||
expect(registry.unregister(token2)).toBeFalse();
|
||||
});
|
||||
|
||||
test("errors", () => {
|
||||
test("cleanup helper errors", () => {
|
||||
var registry = new FinalizationRegistry(() => {});
|
||||
|
||||
expect(() => {
|
||||
registry.cleanupSome(5);
|
||||
cleanupFinalizationRegistry(registry, 5);
|
||||
}).toThrowWithMessage(TypeError, "is not a function");
|
||||
|
||||
expect(() => {
|
||||
cleanupFinalizationRegistry({});
|
||||
}).toThrowWithMessage(TypeError, "Not an object of type FinalizationRegistry");
|
||||
});
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/StringView.h>
|
||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibJS/Runtime/FinalizationRegistry.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibJS/Runtime/ValueInlines.h>
|
||||
#include <LibTest/JavaScriptTestRunner.h>
|
||||
|
|
@ -98,6 +99,24 @@ TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage)
|
|||
return JS::js_undefined();
|
||||
}
|
||||
|
||||
TESTJS_GLOBAL_FUNCTION(cleanup_finalization_registry, cleanupFinalizationRegistry)
|
||||
{
|
||||
auto finalization_registry = vm.argument(0).as_if<JS::FinalizationRegistry>();
|
||||
if (!finalization_registry)
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "FinalizationRegistry");
|
||||
|
||||
auto callback = vm.argument(1);
|
||||
if (vm.argument_count() > 1 && !callback.is_function())
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunction, callback);
|
||||
|
||||
GC::Ptr<JS::JobCallback> cleanup_callback;
|
||||
if (!callback.is_undefined())
|
||||
cleanup_callback = vm.host_make_job_callback(callback.as_function());
|
||||
|
||||
TRY(finalization_registry->cleanup(cleanup_callback));
|
||||
return JS::js_undefined();
|
||||
}
|
||||
|
||||
TESTJS_GLOBAL_FUNCTION(detach_array_buffer, detachArrayBuffer)
|
||||
{
|
||||
auto array_buffer = vm.argument(0).as_if<JS::ArrayBuffer>();
|
||||
|
|
|
|||
Loading…
Reference in a new issue