aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/Weak.cpp
blob: a1b6693437246efb3e6de905e152aef6f9d8f864 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "root.h"
#include "BunClientData.h"
#include <JavaScriptCore/Weak.h>
#include <JavaScriptCore/WeakInlines.h>

namespace Bun {
using WeakRefFinalizerTag = uintptr_t;

template<void (*finalizer)(void*)>
class WeakRefFinalizerClass : public JSC::WeakHandleOwner {
public:
    WeakRefFinalizerClass()
        : JSC::WeakHandleOwner()
    {
    }

    void finalize(JSC::Handle<JSC::Unknown>, void* context)
    {
        finalizer(context);
    }

    static WeakHandleOwner& singleton()
    {
        static NeverDestroyed<WeakRefFinalizerClass<finalizer>> s_singleton;
        return s_singleton;
    }
};

extern "C" void Bun__PostgreSQLQueryClient__target_onFinalize(void*);

using PostgreSQLQueryClient__targetWeakRefFinalizer = WeakRefFinalizerClass<Bun__PostgreSQLQueryClient__target_onFinalize>;

static inline JSC::WeakHandleOwner* getOwner(WeakRefFinalizerTag tag)
{
    if (tag == reinterpret_cast<uintptr_t>(Bun__PostgreSQLQueryClient__target_onFinalize))
        return &PostgreSQLQueryClient__targetWeakRefFinalizer::singleton();

    if (tag == 0)
        return nullptr;

    RELEASE_ASSERT_NOT_REACHED_WITH_MESSAGE("Unknown WeakRefFinalizerTag");
    return nullptr;
}

class WeakRef {
    WTF_MAKE_ISO_ALLOCATED(WeakRef);

public:
    WeakRef()
        : m_weak()
    {
    }

    static inline WeakRef* create(JSC::JSObject* value, WeakRefFinalizerTag tag, void* context)
    {
        return new WeakRef(value, tag, context);
    }

    WeakRef(JSC::JSObject* value, WeakRefFinalizerTag tag, void* context)
    {
        m_weak = JSC::Weak<JSC::JSObject>(value, getOwner(tag), context);
    }

    JSC::Weak<JSC::JSObject> m_weak;
};

WTF_MAKE_ISO_ALLOCATED_IMPL(WeakRef);

extern "C" void Bun__WeakRef__delete(Bun::WeakRef* ref)
{
    delete ref;
}

extern "C" Bun::WeakRef* Bun__WeakRef__new(JSC::EncodedJSValue encodedValue, WeakRefFinalizerTag tag, void* context)
{
    return Bun::WeakRef::create(JSC::JSValue::decode(encodedValue).getObject(), tag, context);
}

extern "C" JSC::EncodedJSValue Bun__WeakRef__get(Bun::WeakRef* weakRef)
{
    return JSC::JSValue::encode(weakRef->m_weak.get());
}

extern "C" void Bun__WeakRef__set(Bun::WeakRef* weakRef, JSC::EncodedJSValue encodedValue, WeakRefFinalizerTag tag, void* context)
{
    weakRef->m_weak = JSC::Weak<JSC::JSObject>(JSC::JSValue::decode(encodedValue).getObject(), getOwner(tag), context);
}

extern "C" void Bun__WeakRef__clear(Bun::WeakRef* weakRef)
{
    weakRef->m_weak.clear();
}

}