Branch data Line data Source code
1 : : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 : : // SPDX-FileCopyrightText: 2023 Marco Trevisan <marco.trevisan@canonical.com>
4 : :
5 : : #include <config.h>
6 : :
7 : : #include <js/Class.h>
8 : : #include <js/Object.h>
9 : : #include <jsapi.h>
10 : :
11 : : #include "gjs/jsapi-simple-wrapper.h"
12 : :
13 : : namespace Gjs {
14 : :
15 : : static const size_t DATA_SLOT = 0;
16 : : static const size_t DESTROY_NOTIFY_SLOT = 1;
17 : :
18 : : static const JSClassOps class_ops = {
19 : : .finalize =
20 : 101 : [](JS::GCContext*, JSObject* obj) {
21 : : void* destroy_notify =
22 : 101 : JS::GetMaybePtrFromReservedSlot<void>(obj, DESTROY_NOTIFY_SLOT);
23 : 101 : void* data = JS::GetMaybePtrFromReservedSlot<void>(obj, DATA_SLOT);
24 : 101 : reinterpret_cast<SimpleWrapper::DestroyNotify>(destroy_notify)(
25 : : data);
26 : 101 : },
27 : : };
28 : :
29 : : static const JSClass data_class = {
30 : : .name = "Object", // user-visible
31 : : .flags = JSCLASS_HAS_RESERVED_SLOTS(1),
32 : : };
33 : :
34 : : static const JSClass destroy_notify_class = {
35 : : .name = "Object", // user-visible
36 : : .flags = JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_FOREGROUND_FINALIZE,
37 : : .cOps = &class_ops,
38 : : };
39 : :
40 : 102 : JSObject* SimpleWrapper::new_for_ptr(JSContext* cx, void* ptr,
41 : : DestroyNotify destroy_notify) {
42 [ + + ]: 102 : if (!destroy_notify) {
43 : 1 : JSObject* retval = JS_NewObject(cx, &data_class);
44 [ - + ]: 1 : if (!retval)
45 : 0 : return nullptr;
46 : 1 : JS::SetReservedSlot(retval, DATA_SLOT, JS::PrivateValue(ptr));
47 : 1 : return retval;
48 : : }
49 : :
50 : 101 : JSObject* retval = JS_NewObject(cx, &destroy_notify_class);
51 [ - + ]: 101 : if (!retval)
52 : 0 : return nullptr;
53 : 101 : JS::SetReservedSlot(retval, DATA_SLOT, JS::PrivateValue(ptr));
54 : 101 : JS::SetReservedSlot(
55 : : retval, DESTROY_NOTIFY_SLOT,
56 : 101 : JS::PrivateValue(reinterpret_cast<void*>(destroy_notify)));
57 : 101 : return retval;
58 : : }
59 : :
60 : 418 : void* SimpleWrapper::get_ptr(JSContext* cx, JS::HandleObject obj) {
61 [ + + + + ]: 420 : if (!JS_InstanceOf(cx, obj, &destroy_notify_class, nullptr) &&
62 [ + + ]: 2 : !JS_InstanceOf(cx, obj, &data_class, nullptr))
63 : 1 : return nullptr;
64 : 417 : return JS::GetMaybePtrFromReservedSlot<void>(obj, DATA_SLOT);
65 : : }
66 : :
67 : : } // namespace Gjs
|