@auto_js/napi 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +4 -0
- package/_module.cc +2 -0
- package/api/api.cc +1 -0
- package/api/callback_info.cc +1 -1
- package/api/napi_scheduler.cc +21 -0
- package/api/napi_scheduler.h.cc +16 -0
- package/api/threadsafe_function.cc +6 -6
- package/api/unmaybe.cc +36 -0
- package/handle/remote.cc +22 -17
- package/handle/value.cc +14 -3
- package/package.json +4 -4
- package/support/callback.cc +52 -48
- package/support/callback_storage.cc +11 -4
- package/support/class_template_storage.cc +6 -5
- package/support/environment.cc +1 -0
- package/support/environment.h.cc +8 -3
- package/support/environment_fwd.cc +4 -2
- package/support/error_scope.cc +11 -5
- package/support/host.cc +43 -5
- package/support/host.h.cc +13 -2
- package/support/initialize.h.cc +3 -1
- package/support/lock.cc +40 -0
- package/support/lock.h.cc +64 -0
- package/support/promise.cc +28 -18
- package/transfer/accept.cc +1 -1
- package/transfer/accept.h.cc +21 -18
- package/transfer/transfer_list.cc +132 -0
- package/transfer/visit.cc +183 -123
- package/value/array.cc +6 -1
- package/value/array.h.cc +8 -3
- package/value/array_buffer.cc +19 -15
- package/value/array_buffer.h.cc +18 -16
- package/value/class.cc +37 -16
- package/value/class.h.cc +5 -4
- package/value/external.cc +7 -7
- package/value/function.cc +15 -15
- package/value/function.h.cc +6 -5
- package/value/object.cc +2 -2
- package/value/object.h.cc +2 -2
- package/value/record.cc +8 -2
- package/value/record.h.cc +8 -2
package/value/array_buffer.cc
CHANGED
|
@@ -5,6 +5,10 @@ import v8;
|
|
|
5
5
|
namespace js::napi {
|
|
6
6
|
|
|
7
7
|
// `value_for_data_block`
|
|
8
|
+
auto value_for_data_block::detach() const -> void {
|
|
9
|
+
napi::invoke0(napi_detach_arraybuffer, env(), napi_value{*this});
|
|
10
|
+
}
|
|
11
|
+
|
|
8
12
|
value_for_data_block::operator std::span<std::byte>() const {
|
|
9
13
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
10
14
|
void* bytes;
|
|
@@ -27,12 +31,12 @@ value_for_shared_array_buffer::operator js::shared_array_buffer() const {
|
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
// `local_for_typed_array`
|
|
30
|
-
auto local_for_typed_array::make(
|
|
31
|
-
return local_of<typed_array_tag>::from(napi::invoke(napi_create_typedarray, napi_env{
|
|
34
|
+
auto local_for_typed_array::make(environment_lock_witness lock, napi_typedarray_type type_tag, local_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag> {
|
|
35
|
+
return local_of<typed_array_tag>::from(napi::invoke(napi_create_typedarray, napi_env{lock}, type_tag, length, napi_value{buffer}, byte_offset));
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
// `value_for_typed_array`
|
|
35
|
-
auto value_for_typed_array::make_bound(
|
|
39
|
+
auto value_for_typed_array::make_bound(environment_lock_witness lock, local_of<typed_array_tag> typed_array) -> any_value_typed_array {
|
|
36
40
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
37
41
|
napi_typedarray_type type_tag;
|
|
38
42
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
@@ -41,9 +45,9 @@ auto value_for_typed_array::make_bound(const environment& env, local_of<typed_ar
|
|
|
41
45
|
std::size_t length;
|
|
42
46
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
43
47
|
std::size_t byte_offset;
|
|
44
|
-
napi::invoke0(napi_get_typedarray_info,
|
|
48
|
+
napi::invoke0(napi_get_typedarray_info, napi_env{lock}, napi_value{typed_array}, &type_tag, &length, nullptr, &array_buffer, &byte_offset);
|
|
45
49
|
const auto make = [ & ]<class Tag>(Tag /*tag*/) -> any_value_typed_array {
|
|
46
|
-
return value_of<Tag>{
|
|
50
|
+
return value_of<Tag>{lock, local_of<Tag>::from(typed_array), std::tuple{local_of<data_block_tag>::from(array_buffer), byte_offset, length}};
|
|
47
51
|
};
|
|
48
52
|
switch (type_tag) {
|
|
49
53
|
case napi_bigint64_array: return make(typed_array_tag_of<std::int64_t>{});
|
|
@@ -63,26 +67,26 @@ auto value_for_typed_array::make_bound(const environment& env, local_of<typed_ar
|
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
// `local_for_data_view`
|
|
66
|
-
auto local_for_data_view::make(
|
|
67
|
-
if (napi::invoke(napi_is_arraybuffer, napi_env{
|
|
68
|
-
return make(
|
|
70
|
+
auto local_for_data_view::make(environment_lock_witness lock, local_of<data_block_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> {
|
|
71
|
+
if (napi::invoke(napi_is_arraybuffer, napi_env{lock}, buffer)) {
|
|
72
|
+
return make(lock, local_of<array_buffer_tag>::from(buffer), byte_offset, length);
|
|
69
73
|
} else {
|
|
70
|
-
return make(
|
|
74
|
+
return make(lock, local_of<shared_array_buffer_tag>::from(buffer), byte_offset, length);
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
auto local_for_data_view::make(
|
|
75
|
-
return local_of<data_view_tag>::from(napi::invoke(napi_create_dataview, napi_env{
|
|
78
|
+
auto local_for_data_view::make(environment_lock_witness lock, local_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> {
|
|
79
|
+
return local_of<data_view_tag>::from(napi::invoke(napi_create_dataview, napi_env{lock}, length, napi_value{buffer}, byte_offset));
|
|
76
80
|
}
|
|
77
81
|
|
|
78
|
-
auto local_for_data_view::make(
|
|
82
|
+
auto local_for_data_view::make(environment_lock_witness /*lock*/, local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> {
|
|
79
83
|
return make_sab_data_view(buffer, byte_offset, length);
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
// `value_for_data_view`
|
|
83
|
-
value_for_data_view::value_for_data_view(
|
|
87
|
+
value_for_data_view::value_for_data_view(environment_lock_witness lock, local_of<data_view_tag> data_view) :
|
|
84
88
|
value_next{
|
|
85
|
-
|
|
89
|
+
lock,
|
|
86
90
|
data_view,
|
|
87
91
|
[ & ] -> auto {
|
|
88
92
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
@@ -91,7 +95,7 @@ value_for_data_view::value_for_data_view(napi_env env, local_of<data_view_tag> d
|
|
|
91
95
|
std::size_t length;
|
|
92
96
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
93
97
|
std::size_t byte_offset;
|
|
94
|
-
napi::invoke0(napi_get_dataview_info,
|
|
98
|
+
napi::invoke0(napi_get_dataview_info, napi_env{lock}, napi_value{data_view}, &length, nullptr, &array_buffer, &byte_offset);
|
|
95
99
|
return std::tuple{local_of<data_block_tag>::from(array_buffer), byte_offset, length};
|
|
96
100
|
}(),
|
|
97
101
|
} {}
|
package/value/array_buffer.h.cc
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export module napi_js:array_buffer;
|
|
2
2
|
import :object;
|
|
3
|
+
import :support.host;
|
|
3
4
|
import std;
|
|
4
5
|
import v8;
|
|
5
6
|
|
|
@@ -11,6 +12,7 @@ class value_for_data_block : public value_next<data_block_tag> {
|
|
|
11
12
|
using value_next<data_block_tag>::value_next;
|
|
12
13
|
[[nodiscard]] constexpr auto byte_length() const -> std::size_t { return std::span<std::byte>{*this}.size(); }
|
|
13
14
|
[[nodiscard]] constexpr auto data() const -> const std::byte* { return std::span<std::byte>{*this}.data(); }
|
|
15
|
+
auto detach() const -> void;
|
|
14
16
|
explicit operator std::span<std::byte>() const;
|
|
15
17
|
};
|
|
16
18
|
|
|
@@ -32,11 +34,11 @@ class value_for_shared_array_buffer : public value_next<shared_array_buffer_tag>
|
|
|
32
34
|
class value_for_array_buffer_view : public value_next<array_buffer_view_tag> {
|
|
33
35
|
protected:
|
|
34
36
|
value_for_array_buffer_view(
|
|
35
|
-
|
|
37
|
+
environment_lock_witness lock,
|
|
36
38
|
local_of<array_buffer_view_tag> typed_array,
|
|
37
39
|
std::tuple<local_of<data_block_tag>, std::size_t, std::size_t> array_buffer_info
|
|
38
40
|
) :
|
|
39
|
-
value_next<array_buffer_view_tag>{
|
|
41
|
+
value_next<array_buffer_view_tag>{lock, typed_array},
|
|
40
42
|
array_buffer_{std::get<0>(array_buffer_info)},
|
|
41
43
|
byte_offset_{std::get<1>(array_buffer_info)},
|
|
42
44
|
length_{std::get<2>(array_buffer_info)} {}
|
|
@@ -55,8 +57,8 @@ class value_for_array_buffer_view : public value_next<array_buffer_view_tag> {
|
|
|
55
57
|
// `TypedArray`
|
|
56
58
|
class local_for_typed_array : public local_next<typed_array_tag> {
|
|
57
59
|
protected:
|
|
58
|
-
static auto make(
|
|
59
|
-
static auto make(
|
|
60
|
+
static auto make(environment_lock_witness lock, napi_typedarray_type type, local_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag>;
|
|
61
|
+
static auto make(environment_lock_witness lock, napi_typedarray_type type, local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag>;
|
|
60
62
|
};
|
|
61
63
|
|
|
62
64
|
class value_for_typed_array : public value_next<typed_array_tag> {
|
|
@@ -76,7 +78,7 @@ class value_for_typed_array : public value_next<typed_array_tag> {
|
|
|
76
78
|
value_of<typed_array_tag_of<std::uint64_t>>,
|
|
77
79
|
value_of<typed_array_tag_of<std::uint8_t>>>;
|
|
78
80
|
|
|
79
|
-
static auto make_bound(
|
|
81
|
+
static auto make_bound(environment_lock_witness lock, local_of<typed_array_tag> typed_array) -> any_value_typed_array;
|
|
80
82
|
};
|
|
81
83
|
|
|
82
84
|
template <class Type>
|
|
@@ -84,15 +86,15 @@ class local_for_typed_array_of : public local_next<typed_array_tag_of<Type>> {
|
|
|
84
86
|
public:
|
|
85
87
|
using local_next<typed_array_tag_of<Type>>::local_next;
|
|
86
88
|
|
|
87
|
-
static auto make(
|
|
88
|
-
if (napi::invoke(napi_is_arraybuffer, napi_env{
|
|
89
|
-
return make(
|
|
89
|
+
static auto make(environment_lock_witness lock, local_of<data_block_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag_of<Type>> {
|
|
90
|
+
if (napi::invoke(napi_is_arraybuffer, napi_env{lock}, buffer)) {
|
|
91
|
+
return make(lock, local_of<array_buffer_tag>::from(buffer), byte_offset, length);
|
|
90
92
|
} else {
|
|
91
|
-
return make(
|
|
93
|
+
return make(lock, local_of<shared_array_buffer_tag>::from(buffer), byte_offset, length);
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
static auto make(
|
|
97
|
+
static auto make(environment_lock_witness lock, local_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag_of<Type>> {
|
|
96
98
|
constexpr auto type_tag = util::overloaded{
|
|
97
99
|
[](std::type_identity<double>) -> napi_typedarray_type { return napi_float64_array; },
|
|
98
100
|
[](std::type_identity<float>) -> napi_typedarray_type { return napi_float32_array; },
|
|
@@ -107,11 +109,11 @@ class local_for_typed_array_of : public local_next<typed_array_tag_of<Type>> {
|
|
|
107
109
|
[](std::type_identity<std::uint64_t>) -> napi_typedarray_type { return napi_biguint64_array; },
|
|
108
110
|
[](std::type_identity<std::uint8_t>) -> napi_typedarray_type { return napi_uint8_array; },
|
|
109
111
|
}(type<Type>);
|
|
110
|
-
return local_of<typed_array_tag_of<Type>>::from(local_for_typed_array::make(
|
|
112
|
+
return local_of<typed_array_tag_of<Type>>::from(local_for_typed_array::make(lock, type_tag, buffer, byte_offset, length));
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
// napi doesn't provide a way to make a typed array view on a shared array buffer
|
|
114
|
-
static auto make(
|
|
116
|
+
static auto make(environment_lock_witness /*lock*/, local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag_of<Type>> {
|
|
115
117
|
return make_sab_typed_array_of<Type>(buffer, byte_offset, length);
|
|
116
118
|
}
|
|
117
119
|
};
|
|
@@ -127,14 +129,14 @@ class local_for_data_view : public local_next<data_view_tag> {
|
|
|
127
129
|
public:
|
|
128
130
|
using local_next<data_view_tag>::local_next;
|
|
129
131
|
|
|
130
|
-
static auto make(
|
|
131
|
-
static auto make(
|
|
132
|
-
static auto make(
|
|
132
|
+
static auto make(environment_lock_witness lock, local_of<data_block_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag>;
|
|
133
|
+
static auto make(environment_lock_witness lock, local_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag>;
|
|
134
|
+
static auto make(environment_lock_witness lock, local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag>;
|
|
133
135
|
};
|
|
134
136
|
|
|
135
137
|
class value_for_data_view : public value_next<data_view_tag> {
|
|
136
138
|
public:
|
|
137
|
-
value_for_data_view(
|
|
139
|
+
value_for_data_view(environment_lock_witness lock, local_of<data_view_tag> data_view);
|
|
138
140
|
};
|
|
139
141
|
|
|
140
142
|
} // namespace js::napi
|
package/value/class.cc
CHANGED
|
@@ -8,7 +8,7 @@ namespace js::napi {
|
|
|
8
8
|
|
|
9
9
|
template <class Type>
|
|
10
10
|
template <class... Args>
|
|
11
|
-
auto local_for_class_of<Type>::construct(auto&
|
|
11
|
+
auto local_for_class_of<Type>::construct(const auto& lock, Args&&... args) const -> local_of<object_tag>
|
|
12
12
|
requires std::constructible_from<Type, Args...> {
|
|
13
13
|
// NOLINTNEXTLINE(readability-simplify-boolean-expr)
|
|
14
14
|
if (false) {
|
|
@@ -16,33 +16,33 @@ auto local_for_class_of<Type>::construct(auto& env, Args&&... args) const -> loc
|
|
|
16
16
|
std::ignore = std::tuple<std::remove_cvref_t<Args>...>{std::forward<Args>(args)...};
|
|
17
17
|
}
|
|
18
18
|
// NOLINTNEXTLINE(bugprone-use-after-move)
|
|
19
|
-
return runtime_construct(
|
|
19
|
+
return runtime_construct(lock, std::forward_as_tuple(std::forward<Args>(args)...), std::tuple{});
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
template <class Type>
|
|
23
23
|
template <class... HostArgs, class... RuntimeArgs>
|
|
24
24
|
auto local_for_class_of<Type>::runtime_construct(
|
|
25
|
-
auto&
|
|
25
|
+
const auto& lock,
|
|
26
26
|
std::tuple<HostArgs...> host_args,
|
|
27
27
|
std::tuple<RuntimeArgs...> runtime_args
|
|
28
28
|
) const -> local_of<object_tag>
|
|
29
29
|
requires std::constructible_from<Type, HostArgs...> {
|
|
30
30
|
constexpr auto [... indices ] = util::sequence<sizeof...(HostArgs)>;
|
|
31
31
|
auto instance = std::make_unique<Type>(std::get<indices>(std::move(host_args))...);
|
|
32
|
-
return transfer_construct(
|
|
32
|
+
return transfer_construct(lock, std::move(instance), std::move(runtime_args));
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
template <class Type>
|
|
36
36
|
template <class... Args>
|
|
37
|
-
auto local_for_class_of<Type>::transfer_construct(auto&
|
|
37
|
+
auto local_for_class_of<Type>::transfer_construct(const auto& lock, auto instance, std::tuple<Args...> runtime_args) const -> local_of<object_tag> {
|
|
38
38
|
using element_type = decltype(instance)::element_type;
|
|
39
39
|
auto construct = [ & ](napi_value this_arg) -> napi_value {
|
|
40
40
|
// Tag `this_arg`
|
|
41
|
-
napi::invoke0(napi_type_tag_object, napi_env{
|
|
41
|
+
napi::invoke0(napi_type_tag_object, napi_env{lock}, this_arg, &type_tag_for<element_type>);
|
|
42
42
|
|
|
43
43
|
// Wrap w/ finalizer
|
|
44
44
|
return apply_finalizer(std::move(instance), [ & ](element_type* instance, node_api_basic_finalize finalize, void* hint) -> napi_value {
|
|
45
|
-
napi::invoke0(napi_wrap, napi_env{
|
|
45
|
+
napi::invoke0(napi_wrap, napi_env{lock}, this_arg, instance, finalize, hint, nullptr);
|
|
46
46
|
return this_arg;
|
|
47
47
|
});
|
|
48
48
|
};
|
|
@@ -50,27 +50,27 @@ auto local_for_class_of<Type>::transfer_construct(auto& env, auto instance, std:
|
|
|
50
50
|
// Now an external (of `internal_constructor`) gets passed to JavaScript for a moment and
|
|
51
51
|
// hopefully it jumps into `construct`
|
|
52
52
|
auto construct_ref = internal_constructor{construct};
|
|
53
|
-
auto* construct_external = napi_value{local_of<external_tag>::make(
|
|
54
|
-
auto [... runtime_arg_values ] = js::transfer_in_strict<std::array<napi_value, sizeof...(Args)>>(std::move(runtime_args),
|
|
53
|
+
auto* construct_external = napi_value{local_of<external_tag>::make(lock, &construct_ref)};
|
|
54
|
+
auto [... runtime_arg_values ] = js::transfer_in_strict<std::array<napi_value, sizeof...(Args)>>(std::move(runtime_args), lock);
|
|
55
55
|
auto arg_vector = std::array{construct_external, runtime_arg_values...};
|
|
56
|
-
auto* this_arg = napi::invoke(napi_new_instance, napi_env{
|
|
56
|
+
auto* this_arg = napi::invoke(napi_new_instance, napi_env{lock}, napi_value{*this}, arg_vector.size(), arg_vector.data());
|
|
57
57
|
return local_of<object_tag>::from(this_arg);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
template <class Type>
|
|
61
61
|
template <class Environment>
|
|
62
|
-
auto local_for_class_of<Type>::make(Environment
|
|
62
|
+
auto local_for_class_of<Type>::make(const environment_lock_witness_of<Environment>& lock, const auto& class_template) -> local_of<class_tag_of<Type>> {
|
|
63
63
|
// Make constructor callback
|
|
64
64
|
auto [ construct_ptr, constructor_data ] =
|
|
65
|
-
make_callback_storage(
|
|
65
|
+
make_callback_storage(lock, make_constructor_function<Environment, Type>(class_template.constructor.function));
|
|
66
66
|
static_assert(std::remove_cvref_t<decltype(class_template.constructor)>::disposition == property_disposition::function);
|
|
67
67
|
static_assert(!requires { typename decltype(constructor_data)::element_type; });
|
|
68
68
|
|
|
69
69
|
// Member function property descriptor
|
|
70
70
|
const auto make_member_function_descriptor = [ & ]<class Property>(const Property& property) -> napi_property_descriptor
|
|
71
|
-
requires(Property::scope == class_property_scope::prototype) {
|
|
71
|
+
requires(Property::scope == class_property_scope::prototype && Property::disposition == property_disposition::function) {
|
|
72
72
|
constexpr auto u8_name = util::make_consteval_string_view(util::transcode_string<char>(property.name));
|
|
73
|
-
auto [ callback, data ] = make_callback_storage(
|
|
73
|
+
auto [ callback, data ] = make_callback_storage(lock, make_member_function<Environment, Type>(property.function));
|
|
74
74
|
static_assert(!requires { typename decltype(data)::element_type; });
|
|
75
75
|
return {
|
|
76
76
|
.utf8name = u8_name.data(),
|
|
@@ -87,11 +87,31 @@ auto local_for_class_of<Type>::make(Environment& env, const auto& class_template
|
|
|
87
87
|
};
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
+
// Member getter property descriptor
|
|
91
|
+
const auto make_member_getter_descriptor = [ & ]<class Property>(const Property& property) -> napi_property_descriptor
|
|
92
|
+
requires(Property::scope == class_property_scope::prototype && Property::disposition == property_disposition::accessor) {
|
|
93
|
+
constexpr auto u8_name = util::make_consteval_string_view(util::transcode_string<char>(property.name));
|
|
94
|
+
auto [ callback, data ] = make_callback_storage(lock, make_member_function<Environment, Type>(property.function));
|
|
95
|
+
static_assert(!requires { typename decltype(data)::element_type; });
|
|
96
|
+
return {
|
|
97
|
+
.utf8name = u8_name.data(),
|
|
98
|
+
.name{},
|
|
99
|
+
|
|
100
|
+
.method{},
|
|
101
|
+
.getter = callback,
|
|
102
|
+
.setter{},
|
|
103
|
+
.value{},
|
|
104
|
+
|
|
105
|
+
.attributes = napi_configurable,
|
|
106
|
+
.data = data,
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
90
110
|
// Static function property descriptor
|
|
91
111
|
const auto make_static_function_descriptor = [ & ]<class Property>(const Property& property) -> napi_property_descriptor
|
|
92
112
|
requires(Property::scope == class_property_scope::constructor) {
|
|
93
113
|
constexpr auto u8_name = util::make_consteval_string_view(util::transcode_string<char>(property.name));
|
|
94
|
-
auto [ callback, data ] = make_callback_storage(
|
|
114
|
+
auto [ callback, data ] = make_callback_storage(lock, make_free_function<Environment>(property.function));
|
|
95
115
|
static_assert(!requires { typename decltype(data)::element_type; });
|
|
96
116
|
return {
|
|
97
117
|
.utf8name = u8_name.data(),
|
|
@@ -111,6 +131,7 @@ auto local_for_class_of<Type>::make(Environment& env, const auto& class_template
|
|
|
111
131
|
// Make class property descriptors
|
|
112
132
|
const auto make_property_descriptor = util::overloaded{
|
|
113
133
|
make_member_function_descriptor,
|
|
134
|
+
make_member_getter_descriptor,
|
|
114
135
|
make_static_function_descriptor,
|
|
115
136
|
};
|
|
116
137
|
const auto [... properties ] = class_template.properties;
|
|
@@ -123,7 +144,7 @@ auto local_for_class_of<Type>::make(Environment& env, const auto& class_template
|
|
|
123
144
|
constexpr auto u8_name = util::make_consteval_string_view(util::transcode_string<char>(class_template.constructor.name));
|
|
124
145
|
auto result = napi::invoke(
|
|
125
146
|
napi_define_class,
|
|
126
|
-
napi_env{
|
|
147
|
+
napi_env{lock},
|
|
127
148
|
u8_name.data(),
|
|
128
149
|
u8_name.length(),
|
|
129
150
|
construct_ptr,
|
package/value/class.h.cc
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export module napi_js:class_;
|
|
2
|
+
import :lock;
|
|
2
3
|
import :object;
|
|
3
4
|
import std;
|
|
4
5
|
|
|
@@ -9,19 +10,19 @@ class local_for_class_of : public local_next<class_tag_of<Type>> {
|
|
|
9
10
|
public:
|
|
10
11
|
// Construct a new C++ instance & JavaScript value
|
|
11
12
|
template <class... Args>
|
|
12
|
-
auto construct(auto&
|
|
13
|
+
auto construct(const auto& lock, Args&&... args) const -> local_of<object_tag>
|
|
13
14
|
requires std::constructible_from<Type, Args...>;
|
|
14
15
|
|
|
15
16
|
template <class... HostArgs, class... RuntimeArgs>
|
|
16
|
-
auto runtime_construct(auto&
|
|
17
|
+
auto runtime_construct(const auto& lock, std::tuple<HostArgs...> host_args, std::tuple<RuntimeArgs...> runtime_args) const -> local_of<object_tag>
|
|
17
18
|
requires std::constructible_from<Type, HostArgs...>;
|
|
18
19
|
|
|
19
20
|
// Create a JavaScript value from an already-created instance smart pointer
|
|
20
21
|
template <class... Args>
|
|
21
|
-
auto transfer_construct(auto&
|
|
22
|
+
auto transfer_construct(const auto& lock, auto instance, std::tuple<Args...> runtime_args) const -> local_of<object_tag>;
|
|
22
23
|
|
|
23
24
|
template <class Environment>
|
|
24
|
-
static auto make(Environment
|
|
25
|
+
static auto make(const environment_lock_witness_of<Environment>& lock, const auto& class_template) -> local_of<class_tag_of<Type>>;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
} // namespace js::napi
|
package/value/external.cc
CHANGED
|
@@ -7,11 +7,11 @@ namespace js::napi {
|
|
|
7
7
|
class local_for_external : public local_next<external_tag> {
|
|
8
8
|
public:
|
|
9
9
|
// untagged
|
|
10
|
-
static auto make(
|
|
10
|
+
static auto make(environment_lock_witness lock, void* pointer) -> local_of<external_tag>;
|
|
11
11
|
|
|
12
12
|
// tagged
|
|
13
13
|
template <class Type>
|
|
14
|
-
static auto make(
|
|
14
|
+
static auto make(environment_lock_witness lock, Type* pointer) -> local_of<external_tag>;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
class value_for_external : public value_next<external_tag> {
|
|
@@ -24,15 +24,15 @@ class value_for_external : public value_next<external_tag> {
|
|
|
24
24
|
|
|
25
25
|
// ---
|
|
26
26
|
|
|
27
|
-
auto local_for_external::make(
|
|
28
|
-
auto* external = napi::invoke(napi_create_external, napi_env{
|
|
27
|
+
auto local_for_external::make(environment_lock_witness lock, void* pointer) -> local_of<external_tag> {
|
|
28
|
+
auto* external = napi::invoke(napi_create_external, napi_env{lock}, pointer, nullptr, nullptr);
|
|
29
29
|
return local_of<external_tag>::from(external);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
template <class Type>
|
|
33
|
-
auto local_for_external::make(
|
|
34
|
-
auto external = make(
|
|
35
|
-
napi::invoke0(napi_type_tag_object, napi_env{
|
|
33
|
+
auto local_for_external::make(environment_lock_witness lock, Type* pointer) -> local_of<external_tag> {
|
|
34
|
+
auto external = make(lock, static_cast<void*>(pointer));
|
|
35
|
+
napi::invoke0(napi_type_tag_object, napi_env{lock}, external, &type_tag_for<Type>);
|
|
36
36
|
return external;
|
|
37
37
|
};
|
|
38
38
|
|
package/value/function.cc
CHANGED
|
@@ -5,35 +5,35 @@ import std;
|
|
|
5
5
|
namespace js::napi {
|
|
6
6
|
|
|
7
7
|
template <class Result>
|
|
8
|
-
auto local_for_function::apply(
|
|
9
|
-
auto argv = js::transfer_in_strict<std::vector<napi_value>>(std::forward<decltype(args)>(args),
|
|
10
|
-
return invoke<Result>(
|
|
8
|
+
auto local_for_function::apply(const auto& lock, auto&& args) -> Result {
|
|
9
|
+
auto argv = js::transfer_in_strict<std::vector<napi_value>>(std::forward<decltype(args)>(args), lock);
|
|
10
|
+
return invoke<Result>(lock, std::span{argv});
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
template <class Result>
|
|
14
|
-
auto local_for_function::call(
|
|
15
|
-
auto argv = js::transfer_in_strict<std::array<napi_value, sizeof...(args)>>(std::forward_as_tuple(args...),
|
|
16
|
-
return invoke<Result>(
|
|
14
|
+
auto local_for_function::call(const auto& lock, auto&&... args) -> Result {
|
|
15
|
+
auto argv = js::transfer_in_strict<std::array<napi_value, sizeof...(args)>>(std::forward_as_tuple(args...), lock);
|
|
16
|
+
return invoke<Result>(lock, std::span{argv});
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
template <class Result>
|
|
20
|
-
auto local_for_function::invoke(
|
|
21
|
-
auto undefined = js::transfer_in_strict<napi_value>(std::monostate{},
|
|
22
|
-
auto* result = napi::invoke(napi_call_function, napi_env{
|
|
23
|
-
return js::transfer_out<Result>(result,
|
|
20
|
+
auto local_for_function::invoke(const auto& lock, std::span<napi_value> args) -> Result {
|
|
21
|
+
auto undefined = js::transfer_in_strict<napi_value>(std::monostate{}, lock);
|
|
22
|
+
auto* result = napi::invoke(napi_call_function, napi_env{lock}, undefined, napi_value{*this}, args.size(), args.data());
|
|
23
|
+
return js::transfer_out<Result>(result, lock);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
template <
|
|
27
|
-
auto local_for_function::make(Environment
|
|
28
|
-
auto [ callback, data ] = make_callback_storage(
|
|
26
|
+
template <class Environment>
|
|
27
|
+
auto local_for_function::make(const environment_lock_witness_of<Environment>& lock, auto function) -> local_of<function_tag> {
|
|
28
|
+
auto [ callback, data ] = make_callback_storage(lock, make_free_function<Environment>(std::move(function).callback));
|
|
29
29
|
auto make = [ & ](void* data) -> local_of<function_tag> {
|
|
30
|
-
return local_of<function_tag>::from(napi::invoke(napi_create_function, napi_env{
|
|
30
|
+
return local_of<function_tag>::from(napi::invoke(napi_create_function, napi_env{lock}, function.name.data(), function.name.length(), callback, data));
|
|
31
31
|
};
|
|
32
32
|
if constexpr (requires { typename decltype(data)::element_type; }) {
|
|
33
33
|
// Function requires finalizer
|
|
34
34
|
auto function = make(data.get());
|
|
35
35
|
return apply_finalizer(std::move(data), [ & ](auto* data, napi_finalize finalize, void* hint) -> local_of<function_tag> {
|
|
36
|
-
napi::invoke0(napi_add_finalizer, napi_env{
|
|
36
|
+
napi::invoke0(napi_add_finalizer, napi_env{lock}, function, data, finalize, hint, nullptr);
|
|
37
37
|
return function;
|
|
38
38
|
});
|
|
39
39
|
} else {
|
package/value/function.h.cc
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export module napi_js:function;
|
|
2
|
+
import :lock;
|
|
2
3
|
import :primitive;
|
|
3
4
|
import std;
|
|
4
5
|
|
|
@@ -7,17 +8,17 @@ namespace js::napi {
|
|
|
7
8
|
class local_for_function : public local_next<function_tag> {
|
|
8
9
|
public:
|
|
9
10
|
template <class Result = std::monostate>
|
|
10
|
-
auto apply(
|
|
11
|
+
auto apply(const auto& lock, auto&& args) -> Result;
|
|
11
12
|
|
|
12
13
|
template <class Result = std::monostate>
|
|
13
|
-
auto call(
|
|
14
|
+
auto call(const auto& lock, auto&&... args) -> Result;
|
|
14
15
|
|
|
15
|
-
template <
|
|
16
|
-
static auto make(Environment
|
|
16
|
+
template <class Environment>
|
|
17
|
+
static auto make(const environment_lock_witness_of<Environment>& lock, auto function) -> local_of<function_tag>;
|
|
17
18
|
|
|
18
19
|
private:
|
|
19
20
|
template <class Result>
|
|
20
|
-
auto invoke(
|
|
21
|
+
auto invoke(const auto& lock, std::span<napi_value> args) -> Result;
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
} // namespace js::napi
|
package/value/object.cc
CHANGED
|
@@ -3,8 +3,8 @@ module napi_js;
|
|
|
3
3
|
namespace js::napi {
|
|
4
4
|
|
|
5
5
|
// object
|
|
6
|
-
auto value_for_object::get(napi_value key) const -> local_of
|
|
7
|
-
return local_of
|
|
6
|
+
auto value_for_object::get(napi_value key) const -> local_of<> {
|
|
7
|
+
return local_of<>::from(napi::invoke(napi_get_property, env(), napi_value{*this}, key));
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
auto value_for_object::has(napi_value key) const -> bool {
|
package/value/object.h.cc
CHANGED
|
@@ -7,7 +7,7 @@ namespace js::napi {
|
|
|
7
7
|
// object
|
|
8
8
|
class local_for_object : public local_next<object_tag> {
|
|
9
9
|
public:
|
|
10
|
-
auto assign(
|
|
10
|
+
auto assign(const auto& lock, auto source) const -> void;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
class value_for_object : public value_next<object_tag> {
|
|
@@ -17,7 +17,7 @@ class value_for_object : public value_next<object_tag> {
|
|
|
17
17
|
template <class Type>
|
|
18
18
|
[[nodiscard]] auto try_cast(std::type_identity<Type> /*type*/) const -> Type*;
|
|
19
19
|
|
|
20
|
-
[[nodiscard]] auto get(napi_value key) const -> local_of
|
|
20
|
+
[[nodiscard]] auto get(napi_value key) const -> local_of<>;
|
|
21
21
|
[[nodiscard]] auto has(napi_value key) const -> bool;
|
|
22
22
|
|
|
23
23
|
auto set(napi_value key, napi_value value) -> void;
|
package/value/record.cc
CHANGED
|
@@ -3,6 +3,7 @@ import std;
|
|
|
3
3
|
|
|
4
4
|
namespace js::napi {
|
|
5
5
|
|
|
6
|
+
// value_for_record
|
|
6
7
|
auto value_for_record::into_range() const -> range_type {
|
|
7
8
|
return keys() | std::views::transform(iterator_transform{*this});
|
|
8
9
|
}
|
|
@@ -21,7 +22,7 @@ auto value_for_record::keys() const -> const keys_type& {
|
|
|
21
22
|
static_cast<napi_key_filter>(napi_key_enumerable | napi_key_skip_symbols),
|
|
22
23
|
napi_key_keep_numbers
|
|
23
24
|
);
|
|
24
|
-
keys_ = keys_type{
|
|
25
|
+
keys_ = keys_type{lock(), js::napi::local_of<vector_tag>::from(property_names), false};
|
|
25
26
|
}
|
|
26
27
|
return keys_;
|
|
27
28
|
}
|
|
@@ -29,8 +30,13 @@ auto value_for_record::keys() const -> const keys_type& {
|
|
|
29
30
|
value_for_record::iterator_transform::iterator_transform(const value_for_record& subject) :
|
|
30
31
|
subject_{&subject} {}
|
|
31
32
|
|
|
32
|
-
auto value_for_record::iterator_transform::operator()(local_of
|
|
33
|
+
auto value_for_record::iterator_transform::operator()(local_of<> key) const -> value_type {
|
|
33
34
|
return std::pair{key_type::from(key), subject_->get(key)};
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
// value_for_list
|
|
38
|
+
auto value_for_list::values() const -> value_of<vector_tag> {
|
|
39
|
+
return value_of<vector_tag>{lock(), local_of<vector_tag>::from(*this)};
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
} // namespace js::napi
|
package/value/record.h.cc
CHANGED
|
@@ -10,14 +10,14 @@ class value_for_record : public value_next<record_tag> {
|
|
|
10
10
|
using value_next<record_tag>::value_next;
|
|
11
11
|
using keys_type = value_of<vector_tag>;
|
|
12
12
|
using key_type = local_of<primitive_tag>;
|
|
13
|
-
using mapped_type = local_of
|
|
13
|
+
using mapped_type = local_of<>;
|
|
14
14
|
using value_type = std::pair<key_type, mapped_type>;
|
|
15
15
|
|
|
16
16
|
private:
|
|
17
17
|
class iterator_transform {
|
|
18
18
|
public:
|
|
19
19
|
explicit iterator_transform(const value_for_record& subject_);
|
|
20
|
-
auto operator()(local_of
|
|
20
|
+
auto operator()(local_of<> key) const -> value_type;
|
|
21
21
|
|
|
22
22
|
private:
|
|
23
23
|
const value_for_record* subject_;
|
|
@@ -36,4 +36,10 @@ class value_for_record : public value_next<record_tag> {
|
|
|
36
36
|
mutable keys_type keys_;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
+
class value_for_list : public value_next<list_tag> {
|
|
40
|
+
public:
|
|
41
|
+
using value_next<list_tag>::value_next;
|
|
42
|
+
auto values() const -> value_of<vector_tag>;
|
|
43
|
+
};
|
|
44
|
+
|
|
39
45
|
} // namespace js::napi
|