diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-02-07 23:18:25 +0300 |
---|---|---|
committer | Daniel Bevenius <daniel.bevenius@gmail.com> | 2019-02-12 07:38:18 +0300 |
commit | 86799326077611d694f37753ee3ab6903397f893 (patch) | |
tree | 8f0f721bbac1929faec8e03fdbb7db4de445bb07 /src | |
parent | 0a4c69a5c5e8ba93b7c9f67d08ef6c859eb1f86a (diff) |
src: add WeakReference utility
Add a simple `WeakReference` utility that we can use until the
language provides something on its own.
PR-URL: https://github.com/nodejs/node/pull/25993
Fixes: https://github.com/nodejs/node/issues/23862
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/node_util.cc | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/node_util.cc b/src/node_util.cc index 2a7d90cfe2b..4cca0cbb72a 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -1,6 +1,7 @@ #include "node_errors.h" #include "node_watchdog.h" #include "util.h" +#include "base_object-inl.h" namespace node { namespace util { @@ -11,6 +12,7 @@ using v8::Boolean; using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; using v8::IndexFilter; using v8::Integer; using v8::Isolate; @@ -181,6 +183,37 @@ void EnqueueMicrotask(const FunctionCallbackInfo<Value>& args) { isolate->EnqueueMicrotask(args[0].As<Function>()); } +class WeakReference : public BaseObject { + public: + WeakReference(Environment* env, Local<Object> object, Local<Object> target) + : BaseObject(env, object) { + MakeWeak(); + target_.Reset(env->isolate(), target); + target_.SetWeak(); + } + + static void New(const FunctionCallbackInfo<Value>& args) { + Environment* env = Environment::GetCurrent(args); + CHECK(args.IsConstructCall()); + CHECK(args[0]->IsObject()); + new WeakReference(env, args.This(), args[0].As<Object>()); + } + + static void Get(const FunctionCallbackInfo<Value>& args) { + WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder()); + Isolate* isolate = args.GetIsolate(); + if (!weak_ref->target_.IsEmpty()) + args.GetReturnValue().Set(weak_ref->target_.Get(isolate)); + } + + SET_MEMORY_INFO_NAME(WeakReference) + SET_SELF_SIZE(WeakReference) + SET_NO_MEMORY_INFO() + + private: + Persistent<Object> target_; +}; + void Initialize(Local<Object> target, Local<Value> unused, Local<Context> context, @@ -241,6 +274,16 @@ void Initialize(Local<Object> target, should_abort_on_uncaught_toggle, env->should_abort_on_uncaught_toggle().GetJSArray()) .FromJust()); + + Local<String> weak_ref_string = + FIXED_ONE_BYTE_STRING(env->isolate(), "WeakReference"); + Local<FunctionTemplate> weak_ref = + env->NewFunctionTemplate(WeakReference::New); + weak_ref->InstanceTemplate()->SetInternalFieldCount(1); + weak_ref->SetClassName(weak_ref_string); + env->SetProtoMethod(weak_ref, "get", WeakReference::Get); + target->Set(context, weak_ref_string, + weak_ref->GetFunction(context).ToLocalChecked()).FromJust(); } } // namespace util |