diff options
author | davidot <davidot@serenityos.org> | 2022-02-07 14:42:24 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-02-08 09:12:42 +0000 |
commit | f324d911069a3950670827f7667b49b5e54fd212 (patch) | |
tree | a6b1d3f44b00918589796929d565bee90eef7376 | |
parent | dcc284705b496d7f83c012888a439f7162f251f7 (diff) | |
download | serenity-f324d911069a3950670827f7667b49b5e54fd212.zip |
LibJS: Convert FinalizationRegistry::cleanup to ThrowCompletionOr
3 files changed, 19 insertions, 7 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp b/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp index aa2026fe33..42ddfe47d3 100644 --- a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp +++ b/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp @@ -58,18 +58,30 @@ void FinalizationRegistry::remove_dead_cells(Badge<Heap>) } // 9.13 CleanupFinalizationRegistry ( finalizationRegistry ), https://tc39.es/ecma262/#sec-cleanup-finalization-registry -void FinalizationRegistry::cleanup(FunctionObject* callback) +ThrowCompletionOr<void> FinalizationRegistry::cleanup(FunctionObject* callback) { - auto& vm = this->vm(); + // 1. Assert: finalizationRegistry has [[Cells]] and [[CleanupCallback]] internal slots. + // Note: Ensured by type. + + // 2. Let callback be finalizationRegistry.[[CleanupCallback]]. auto cleanup_callback = callback ?: m_cleanup_callback; + + // 3. While finalizationRegistry.[[Cells]] contains a Record cell such that cell.[[WeakRefTarget]] is empty, an implementation may perform the following steps: for (auto it = m_records.begin(); it != m_records.end(); ++it) { + // a. Choose any such cell. if (it->target != nullptr) continue; - (void)call(global_object(), *cleanup_callback, js_undefined(), it->held_value); + auto cell = *it; + + // b. Remove cell from finalizationRegistry.[[Cells]]. it.remove(m_records); - if (vm.exception()) - return; + + // c. Perform ? HostCallJobCallback(callback, undefined, ยซ cell.[[HeldValue]] ยป). + (void)TRY(call(global_object(), *cleanup_callback, js_undefined(), cell.held_value)); } + + // 4. Return NormalCompletion(empty). + return {}; } void FinalizationRegistry::visit_edges(Cell::Visitor& visitor) diff --git a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h b/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h index 53f008f51e..a4b9a9696f 100644 --- a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h +++ b/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h @@ -28,7 +28,7 @@ public: void add_finalization_record(Cell& target, Value held_value, Object* unregister_token); bool remove_by_token(Object& unregister_token); - void cleanup(FunctionObject* callback = nullptr); + ThrowCompletionOr<void> cleanup(FunctionObject* callback = nullptr); virtual void remove_dead_cells(Badge<Heap>) override; diff --git a/Userland/Libraries/LibJS/Runtime/FinalizationRegistryPrototype.cpp b/Userland/Libraries/LibJS/Runtime/FinalizationRegistryPrototype.cpp index 2a610d5c9e..7d90b8c797 100644 --- a/Userland/Libraries/LibJS/Runtime/FinalizationRegistryPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/FinalizationRegistryPrototype.cpp @@ -41,7 +41,7 @@ JS_DEFINE_NATIVE_FUNCTION(FinalizationRegistryPrototype::cleanup_some) if (vm.argument_count() > 0 && !callback.is_function()) return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, callback.to_string_without_side_effects()); - finalization_registry->cleanup(callback.is_undefined() ? nullptr : &callback.as_function()); + TRY(finalization_registry->cleanup(callback.is_undefined() ? nullptr : &callback.as_function())); return js_undefined(); } |