From b9d4dd685022d11d1567f82e0b69333b0e2b3576 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Sat, 12 Jun 2021 17:40:33 +0300 Subject: [PATCH] LibJS: Add the WeakRef.prototype.deref method This is the only exposed method of the WeakRef built-in. --- .../LibJS/Runtime/WeakRefPrototype.cpp | 17 +++++++++++++++ .../LibJS/Runtime/WeakRefPrototype.h | 3 +++ .../WeakRef/WeakRef.prototype.deref.js | 21 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 Userland/Libraries/LibJS/Tests/builtins/WeakRef/WeakRef.prototype.deref.js diff --git a/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.cpp b/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.cpp index 2967ee4aa4..8e1e020bb0 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.cpp @@ -18,6 +18,8 @@ void WeakRefPrototype::initialize(GlobalObject& global_object) auto& vm = this->vm(); Object::initialize(global_object); + define_native_function(vm.names.deref, deref, 0, Attribute::Writable | Attribute::Configurable); + define_property(vm.well_known_symbol_to_string_tag(), js_string(global_object.heap(), vm.names.WeakRef), Attribute::Configurable); } @@ -25,4 +27,19 @@ WeakRefPrototype::~WeakRefPrototype() { } +// 26.1.3.2 WeakRef.prototype.deref ( ), https://tc39.es/ecma262/#sec-weak-ref.prototype.deref +JS_DEFINE_NATIVE_FUNCTION(WeakRefPrototype::deref) +{ + auto* this_object = vm.this_value(global_object).to_object(global_object); + if (!this_object) + return {}; + if (!is(this_object)) { + vm.throw_exception(global_object, ErrorType::NotA, "WeakRef"); + return {}; + } + auto& weak_ref = static_cast(*this_object); + weak_ref.update_execution_generation(); + return weak_ref.value() ?: js_undefined(); +} + } diff --git a/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.h b/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.h index 56cac90c88..9d7cddb97f 100644 --- a/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/WeakRefPrototype.h @@ -17,6 +17,9 @@ public: WeakRefPrototype(GlobalObject&); virtual void initialize(GlobalObject&) override; virtual ~WeakRefPrototype() override; + +private: + JS_DECLARE_NATIVE_FUNCTION(deref); }; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/WeakRef/WeakRef.prototype.deref.js b/Userland/Libraries/LibJS/Tests/builtins/WeakRef/WeakRef.prototype.deref.js new file mode 100644 index 0000000000..e616cff77a --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/WeakRef/WeakRef.prototype.deref.js @@ -0,0 +1,21 @@ +test("length is 0", () => { + expect(WeakRef.prototype.deref).toHaveLength(0); +}); + +test("basic functionality", () => { + var original = { a: 1 }; + var weakRef = new WeakRef(original); + + expect(weakRef.deref()).toBe(original); +}); + +test("kept alive for current synchronous execution sequence", () => { + var weakRef; + { + weakRef = new WeakRef({ a: 1 }); + } + weakRef.deref(); + gc(); + // This is fine 🔥 + expect(weakRef.deref()).not.toBe(undefined); +});