@auto_js/napi 0.0.1 → 0.0.2
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 +10 -4
- package/README.md +30 -3
- package/_module.cc +12 -10
- package/api/api.cc +8 -7
- package/api/callback_info.cc +1 -7
- package/api/finalizer.cc +1 -4
- package/api/invoke.cc +4 -9
- package/api/uv_dlib.cc +27 -0
- package/api/uv_dlib.h.cc +21 -0
- package/api/uv_handle.cc +9 -9
- package/api/uv_scheduler.cc +11 -17
- package/api/uv_scheduler.h.cc +3 -6
- package/handle/bound_value.cc +4 -7
- package/handle/reference.cc +9 -5
- package/handle/remote.cc +11 -17
- package/handle/types.cc +61 -46
- package/handle/value.cc +12 -14
- package/package.json +7 -6
- package/support/callback.cc +7 -19
- package/support/callback_storage.cc +4 -9
- package/support/class_template_storage.cc +4 -6
- package/support/container.cc +9 -10
- package/support/environment.cc +32 -20
- package/support/environment.h.cc +8 -18
- package/support/environment_fwd.cc +1 -2
- package/support/error_scope.cc +0 -2
- package/support/initialize.h.cc +2 -5
- package/support/promise.cc +3 -10
- package/support/string_table.cc +3 -5
- package/support/utility.cc +54 -28
- package/transfer/accept.cc +131 -327
- package/transfer/accept.h.cc +390 -0
- package/transfer/visit.cc +201 -132
- package/value/array.cc +1 -3
- package/value/array.h.cc +5 -11
- package/value/array_buffer.cc +109 -0
- package/value/array_buffer.h.cc +150 -0
- package/value/class.cc +12 -21
- package/value/class.h.cc +5 -10
- package/value/external.cc +6 -10
- package/value/function.cc +5 -12
- package/value/function.h.cc +2 -9
- package/value/object.cc +2 -6
- package/value/object.h.cc +7 -15
- package/value/primitive.cc +12 -81
- package/value/primitive.h.cc +6 -64
- package/value/record.cc +38 -0
- package/value/record.h.cc +39 -0
- package/value/value.cc +8 -8
- package/value/dictionary.cc +0 -33
- package/value/dictionary.h.cc +0 -56
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export module napi_js:array_buffer;
|
|
2
|
+
import :bound_value;
|
|
3
|
+
import :environment;
|
|
4
|
+
import :object;
|
|
5
|
+
import std;
|
|
6
|
+
import v8;
|
|
7
|
+
|
|
8
|
+
namespace js::napi {
|
|
9
|
+
|
|
10
|
+
// `ArrayBuffer`
|
|
11
|
+
class bound_value_for_array_buffer : public bound_value_next<array_buffer_tag> {
|
|
12
|
+
public:
|
|
13
|
+
using bound_value_next<array_buffer_tag>::bound_value_next;
|
|
14
|
+
|
|
15
|
+
explicit operator js::array_buffer() const;
|
|
16
|
+
explicit operator std::span<std::byte>() const;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// `SharedArrayBuffer`
|
|
20
|
+
class bound_value_for_shared_array_buffer : public bound_value_next<shared_array_buffer_tag> {
|
|
21
|
+
public:
|
|
22
|
+
using bound_value_next<shared_array_buffer_tag>::bound_value_next;
|
|
23
|
+
|
|
24
|
+
explicit operator js::shared_array_buffer() const;
|
|
25
|
+
explicit operator std::span<std::byte>() const;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// `ArrayBufferView` (hidden superclass of `TypedArray` and `DataView`)
|
|
29
|
+
class bound_value_for_array_buffer_view : public bound_value_next<array_buffer_view_tag> {
|
|
30
|
+
protected:
|
|
31
|
+
bound_value_for_array_buffer_view(
|
|
32
|
+
napi_env env,
|
|
33
|
+
value_of<array_buffer_view_tag> typed_array,
|
|
34
|
+
std::tuple<value_of<data_block_tag>, std::size_t, std::size_t> array_buffer_info
|
|
35
|
+
) :
|
|
36
|
+
bound_value_next<array_buffer_view_tag>{env, typed_array},
|
|
37
|
+
array_buffer_{std::get<0>(array_buffer_info)},
|
|
38
|
+
byte_offset_{std::get<1>(array_buffer_info)},
|
|
39
|
+
length_{std::get<2>(array_buffer_info)} {}
|
|
40
|
+
|
|
41
|
+
public:
|
|
42
|
+
[[nodiscard]] auto buffer() const -> value_of<data_block_tag> { return array_buffer_; }
|
|
43
|
+
[[nodiscard]] auto byte_offset() const -> std::size_t { return byte_offset_; }
|
|
44
|
+
[[nodiscard]] auto size() const -> std::size_t { return length_; }
|
|
45
|
+
|
|
46
|
+
private:
|
|
47
|
+
value_of<data_block_tag> array_buffer_;
|
|
48
|
+
std::size_t byte_offset_;
|
|
49
|
+
std::size_t length_;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// `TypedArray`
|
|
53
|
+
class value_for_typed_array : public value_next<typed_array_tag> {
|
|
54
|
+
protected:
|
|
55
|
+
static auto make(const environment& env, napi_typedarray_type type, value_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<typed_array_tag>;
|
|
56
|
+
static auto make(const environment& env, napi_typedarray_type type, value_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<typed_array_tag>;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
class bound_value_for_typed_array : public bound_value_next<typed_array_tag> {
|
|
60
|
+
public:
|
|
61
|
+
using bound_value_next<typed_array_tag>::bound_value_next;
|
|
62
|
+
using any_bound_typed_array = std::variant<
|
|
63
|
+
bound_value<typed_array_tag_of<double>>,
|
|
64
|
+
bound_value<typed_array_tag_of<float>>,
|
|
65
|
+
bound_value<typed_array_tag_of<std::byte>>,
|
|
66
|
+
bound_value<typed_array_tag_of<std::int16_t>>,
|
|
67
|
+
bound_value<typed_array_tag_of<std::int32_t>>,
|
|
68
|
+
bound_value<typed_array_tag_of<std::int64_t>>,
|
|
69
|
+
bound_value<typed_array_tag_of<std::int8_t>>,
|
|
70
|
+
bound_value<typed_array_tag_of<std::uint16_t>>,
|
|
71
|
+
bound_value<typed_array_tag_of<std::uint32_t>>,
|
|
72
|
+
bound_value<typed_array_tag_of<std::uint64_t>>,
|
|
73
|
+
bound_value<typed_array_tag_of<std::uint8_t>>>;
|
|
74
|
+
|
|
75
|
+
static auto make_bound(const environment& env, value_of<typed_array_tag> typed_array) -> any_bound_typed_array;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
template <class Type>
|
|
79
|
+
class value_for_typed_array_of : public value_next<typed_array_tag_of<Type>> {
|
|
80
|
+
public:
|
|
81
|
+
using value_next<typed_array_tag_of<Type>>::value_next;
|
|
82
|
+
|
|
83
|
+
static auto make(const environment& env, value_of<data_block_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<typed_array_tag_of<Type>> {
|
|
84
|
+
if (napi::invoke(napi_is_arraybuffer, napi_env{env}, buffer)) {
|
|
85
|
+
return make(env, value_of<array_buffer_tag>::from(buffer), byte_offset, length);
|
|
86
|
+
} else {
|
|
87
|
+
return make(env, value_of<shared_array_buffer_tag>::from(buffer), byte_offset, length);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static auto make(const environment& env, value_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<typed_array_tag_of<Type>> {
|
|
92
|
+
constexpr auto type_tag = util::overloaded{
|
|
93
|
+
[](std::type_identity<double>) -> napi_typedarray_type { return napi_float64_array; },
|
|
94
|
+
[](std::type_identity<float>) -> napi_typedarray_type { return napi_float32_array; },
|
|
95
|
+
[](std::type_identity<std::byte>) -> napi_typedarray_type { return napi_uint8_clamped_array; },
|
|
96
|
+
[](std::type_identity<std::int16_t>) -> napi_typedarray_type { return napi_int16_array; },
|
|
97
|
+
[](std::type_identity<std::int32_t>) -> napi_typedarray_type { return napi_int32_array; },
|
|
98
|
+
[](std::type_identity<std::int64_t>) -> napi_typedarray_type { return napi_bigint64_array; },
|
|
99
|
+
[](std::type_identity<std::int8_t>) -> napi_typedarray_type { return napi_int8_array; },
|
|
100
|
+
[](std::type_identity<std::uint16_t>) -> napi_typedarray_type { return napi_uint16_array; },
|
|
101
|
+
[](std::type_identity<std::uint32_t>) -> napi_typedarray_type { return napi_uint32_array; },
|
|
102
|
+
[](std::type_identity<std::uint64_t>) -> napi_typedarray_type { return napi_biguint64_array; },
|
|
103
|
+
[](std::type_identity<std::uint8_t>) -> napi_typedarray_type { return napi_uint8_array; },
|
|
104
|
+
}(type<Type>);
|
|
105
|
+
return value_of<typed_array_tag_of<Type>>::from(value_for_typed_array::make(env, type_tag, buffer, byte_offset, length));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// napi doesn't provide a way to make a typed array view on a shared array buffer
|
|
109
|
+
static auto make(const environment& /*env*/, value_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<typed_array_tag_of<Type>> {
|
|
110
|
+
using constructor_type = type_t<util::overloaded{
|
|
111
|
+
[](std::type_identity<double>) -> std::type_identity<v8::Float64Array> { return {}; },
|
|
112
|
+
[](std::type_identity<float>) -> std::type_identity<v8::Float32Array> { return {}; },
|
|
113
|
+
[](std::type_identity<std::byte>) -> std::type_identity<v8::Uint8ClampedArray> { return {}; },
|
|
114
|
+
[](std::type_identity<std::int16_t>) -> std::type_identity<v8::Int16Array> { return {}; },
|
|
115
|
+
[](std::type_identity<std::int32_t>) -> std::type_identity<v8::Int32Array> { return {}; },
|
|
116
|
+
[](std::type_identity<std::int64_t>) -> std::type_identity<v8::BigInt64Array> { return {}; },
|
|
117
|
+
[](std::type_identity<std::int8_t>) -> std::type_identity<v8::Int8Array> { return {}; },
|
|
118
|
+
[](std::type_identity<std::uint16_t>) -> std::type_identity<v8::Uint16Array> { return {}; },
|
|
119
|
+
[](std::type_identity<std::uint32_t>) -> std::type_identity<v8::Uint32Array> { return {}; },
|
|
120
|
+
[](std::type_identity<std::uint64_t>) -> std::type_identity<v8::BigUint64Array> { return {}; },
|
|
121
|
+
[](std::type_identity<std::uint8_t>) -> std::type_identity<v8::Uint8Array> { return {}; },
|
|
122
|
+
}(type<Type>)>;
|
|
123
|
+
auto buffer_local = std::bit_cast<v8::Local<v8::SharedArrayBuffer>>(napi_value{buffer});
|
|
124
|
+
auto view_local = constructor_type::New(buffer_local, byte_offset, length);
|
|
125
|
+
return value_of<typed_array_tag_of<Type>>::from(std::bit_cast<napi_value>(view_local));
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
template <class Type>
|
|
130
|
+
class bound_value_for_typed_array_of : public bound_value_next<typed_array_tag_of<Type>> {
|
|
131
|
+
public:
|
|
132
|
+
using bound_value_next<typed_array_tag_of<Type>>::bound_value_next;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// `DataView`
|
|
136
|
+
class value_for_data_view : public value_next<data_view_tag> {
|
|
137
|
+
public:
|
|
138
|
+
using value_next<data_view_tag>::value_next;
|
|
139
|
+
|
|
140
|
+
static auto make(const environment& env, value_of<data_block_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<data_view_tag>;
|
|
141
|
+
static auto make(const environment& env, value_of<array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<data_view_tag>;
|
|
142
|
+
static auto make(const environment& env, value_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<data_view_tag>;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
class bound_value_for_data_view : public bound_value_next<data_view_tag> {
|
|
146
|
+
public:
|
|
147
|
+
bound_value_for_data_view(napi_env env, value_of<data_view_tag> data_view);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
} // namespace js::napi
|
package/value/class.cc
CHANGED
|
@@ -1,28 +1,19 @@
|
|
|
1
|
-
module;
|
|
2
|
-
#include <algorithm>
|
|
3
|
-
#include <array>
|
|
4
|
-
#include <concepts>
|
|
5
|
-
#include <memory>
|
|
6
|
-
#include <tuple>
|
|
7
|
-
#include <type_traits>
|
|
8
|
-
#include <utility>
|
|
9
1
|
export module napi_js:class_definitions;
|
|
10
2
|
import :api;
|
|
11
3
|
import :callback;
|
|
12
|
-
import
|
|
13
|
-
import :external;
|
|
4
|
+
import std;
|
|
14
5
|
import util;
|
|
15
6
|
|
|
16
7
|
namespace js::napi {
|
|
17
8
|
|
|
18
9
|
template <class Type>
|
|
19
10
|
template <class... Args>
|
|
20
|
-
auto value_for_class_of<Type>::construct(auto& env, Args&&... args) const ->
|
|
11
|
+
auto value_for_class_of<Type>::construct(auto& env, Args&&... args) const -> value_of<object_tag>
|
|
21
12
|
requires std::constructible_from<Type, Args...> {
|
|
22
13
|
// NOLINTNEXTLINE(readability-simplify-boolean-expr)
|
|
23
14
|
if (false) {
|
|
24
15
|
// nb: Fixes invalid `performance-unnecessary-value-param` lint errors when invoking this function
|
|
25
|
-
|
|
16
|
+
std::ignore = std::tuple<std::remove_cvref_t<Args>...>{std::forward<Args>(args)...};
|
|
26
17
|
}
|
|
27
18
|
// NOLINTNEXTLINE(bugprone-use-after-move)
|
|
28
19
|
return runtime_construct(env, std::forward_as_tuple(std::forward<Args>(args)...), std::tuple{});
|
|
@@ -34,7 +25,7 @@ auto value_for_class_of<Type>::runtime_construct(
|
|
|
34
25
|
auto& env,
|
|
35
26
|
std::tuple<HostArgs...> host_args,
|
|
36
27
|
std::tuple<RuntimeArgs...> runtime_args
|
|
37
|
-
) const ->
|
|
28
|
+
) const -> value_of<object_tag>
|
|
38
29
|
requires std::constructible_from<Type, HostArgs...> {
|
|
39
30
|
const auto [... indices ] = util::sequence<sizeof...(HostArgs)>;
|
|
40
31
|
// NOLINTNEXTLINE(bugprone-use-after-move)
|
|
@@ -44,7 +35,7 @@ auto value_for_class_of<Type>::runtime_construct(
|
|
|
44
35
|
|
|
45
36
|
template <class Type>
|
|
46
37
|
template <class... Args>
|
|
47
|
-
auto value_for_class_of<Type>::transfer_construct(auto& env, auto instance, std::tuple<Args...> runtime_args) const ->
|
|
38
|
+
auto value_for_class_of<Type>::transfer_construct(auto& env, auto instance, std::tuple<Args...> runtime_args) const -> value_of<object_tag> {
|
|
48
39
|
using element_type = decltype(instance)::element_type;
|
|
49
40
|
auto construct = [ & ](napi_value this_arg) mutable -> napi_value {
|
|
50
41
|
// Tag `this_arg`
|
|
@@ -60,16 +51,16 @@ auto value_for_class_of<Type>::transfer_construct(auto& env, auto instance, std:
|
|
|
60
51
|
// Now an external (of `internal_constructor`) gets passed to JavaScript for a moment and
|
|
61
52
|
// hopefully it jumps into `construct`
|
|
62
53
|
auto construct_ref = internal_constructor{construct};
|
|
63
|
-
auto* construct_external = napi_value{
|
|
54
|
+
auto* construct_external = napi_value{value_of<external_tag>::make(env, &construct_ref)};
|
|
64
55
|
auto [... runtime_arg_values ] = js::transfer_in_strict<std::array<napi_value, sizeof...(Args)>>(std::move(runtime_args), env);
|
|
65
56
|
auto arg_vector = std::array{construct_external, runtime_arg_values...};
|
|
66
57
|
auto* this_arg = napi::invoke(napi_new_instance, napi_env{env}, napi_value{*this}, arg_vector.size(), arg_vector.data());
|
|
67
|
-
return
|
|
58
|
+
return value_of<object_tag>::from(this_arg);
|
|
68
59
|
}
|
|
69
60
|
|
|
70
61
|
template <class Type>
|
|
71
62
|
template <class Environment>
|
|
72
|
-
auto value_for_class_of<Type>::make(Environment& env, const auto& class_template) ->
|
|
63
|
+
auto value_for_class_of<Type>::make(Environment& env, const auto& class_template) -> value_of<class_tag_of<Type>> {
|
|
73
64
|
// Make constructor callback
|
|
74
65
|
auto [ construct_ptr, constructor_data ] =
|
|
75
66
|
make_callback_storage(env, make_constructor_function<Environment, Type>(class_template.constructor.function));
|
|
@@ -79,7 +70,7 @@ auto value_for_class_of<Type>::make(Environment& env, const auto& class_template
|
|
|
79
70
|
// Member function property descriptor
|
|
80
71
|
const auto make_member_function_descriptor = [ & ]<class Property>(const Property& property) -> napi_property_descriptor
|
|
81
72
|
requires(Property::scope == class_property_scope::prototype) {
|
|
82
|
-
constexpr auto u8_name = util::
|
|
73
|
+
constexpr auto u8_name = util::make_consteval_string_view(util::transcode_string<char>(property.name));
|
|
83
74
|
auto [ callback, data ] = make_callback_storage(env, make_member_function<Environment, Type>(property.function));
|
|
84
75
|
static_assert(!requires { typename decltype(data)::element_type; });
|
|
85
76
|
return {
|
|
@@ -100,7 +91,7 @@ auto value_for_class_of<Type>::make(Environment& env, const auto& class_template
|
|
|
100
91
|
// Static function property descriptor
|
|
101
92
|
const auto make_static_function_descriptor = [ & ]<class Property>(const Property& property) -> napi_property_descriptor
|
|
102
93
|
requires(Property::scope == class_property_scope::constructor) {
|
|
103
|
-
constexpr auto u8_name = util::
|
|
94
|
+
constexpr auto u8_name = util::make_consteval_string_view(util::transcode_string<char>(property.name));
|
|
104
95
|
auto [ callback, data ] = make_callback_storage(env, make_free_function<Environment>(property.function));
|
|
105
96
|
static_assert(!requires { typename decltype(data)::element_type; });
|
|
106
97
|
return {
|
|
@@ -130,7 +121,7 @@ auto value_for_class_of<Type>::make(Environment& env, const auto& class_template
|
|
|
130
121
|
};
|
|
131
122
|
|
|
132
123
|
// Finally, define the class
|
|
133
|
-
constexpr auto u8_name = util::
|
|
124
|
+
constexpr auto u8_name = util::make_consteval_string_view(util::transcode_string<char>(class_template.constructor.name));
|
|
134
125
|
auto result = napi::invoke(
|
|
135
126
|
napi_define_class,
|
|
136
127
|
napi_env{env},
|
|
@@ -141,7 +132,7 @@ auto value_for_class_of<Type>::make(Environment& env, const auto& class_template
|
|
|
141
132
|
property_descriptors.size(),
|
|
142
133
|
property_descriptors.data()
|
|
143
134
|
);
|
|
144
|
-
return js::napi::
|
|
135
|
+
return js::napi::value_of<class_tag_of<Type>>::from(result);
|
|
145
136
|
}
|
|
146
137
|
|
|
147
138
|
} // namespace js::napi
|
package/value/class.h.cc
CHANGED
|
@@ -1,32 +1,27 @@
|
|
|
1
|
-
module;
|
|
2
|
-
#include <concepts>
|
|
3
|
-
#include <tuple>
|
|
4
1
|
export module napi_js:class_;
|
|
5
|
-
import :value_handle;
|
|
6
2
|
import :object;
|
|
3
|
+
import std;
|
|
7
4
|
|
|
8
5
|
namespace js::napi {
|
|
9
6
|
|
|
10
7
|
template <class Type>
|
|
11
8
|
class value_for_class_of : public value_next<class_tag_of<Type>> {
|
|
12
9
|
public:
|
|
13
|
-
using value_next<class_tag_of<Type>>::value_next;
|
|
14
|
-
|
|
15
10
|
// Construct a new C++ instance & JavaScript value
|
|
16
11
|
template <class... Args>
|
|
17
|
-
auto construct(auto& env, Args&&... args) const ->
|
|
12
|
+
auto construct(auto& env, Args&&... args) const -> value_of<object_tag>
|
|
18
13
|
requires std::constructible_from<Type, Args...>;
|
|
19
14
|
|
|
20
15
|
template <class... HostArgs, class... RuntimeArgs>
|
|
21
|
-
auto runtime_construct(auto& env, std::tuple<HostArgs...> host_args, std::tuple<RuntimeArgs...> runtime_args) const ->
|
|
16
|
+
auto runtime_construct(auto& env, std::tuple<HostArgs...> host_args, std::tuple<RuntimeArgs...> runtime_args) const -> value_of<object_tag>
|
|
22
17
|
requires std::constructible_from<Type, HostArgs...>;
|
|
23
18
|
|
|
24
19
|
// Create a JavaScript value from an already-created instance smart pointer
|
|
25
20
|
template <class... Args>
|
|
26
|
-
auto transfer_construct(auto& env, auto instance, std::tuple<Args...> runtime_args) const ->
|
|
21
|
+
auto transfer_construct(auto& env, auto instance, std::tuple<Args...> runtime_args) const -> value_of<object_tag>;
|
|
27
22
|
|
|
28
23
|
template <class Environment>
|
|
29
|
-
static auto make(Environment& env, const auto& class_template) ->
|
|
24
|
+
static auto make(Environment& env, const auto& class_template) -> value_of<class_tag_of<Type>>;
|
|
30
25
|
};
|
|
31
26
|
|
|
32
27
|
} // namespace js::napi
|
package/value/external.cc
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
module;
|
|
2
|
-
#include <type_traits>
|
|
3
1
|
export module napi_js:external;
|
|
4
2
|
import :api;
|
|
5
3
|
import :bound_value;
|
|
6
4
|
import :object;
|
|
7
|
-
import
|
|
5
|
+
import std;
|
|
8
6
|
|
|
9
7
|
namespace js::napi {
|
|
10
8
|
|
|
11
9
|
class value_for_external : public value_next<external_tag> {
|
|
12
10
|
public:
|
|
13
|
-
using value_next<external_tag>::value_next;
|
|
14
|
-
|
|
15
11
|
// untagged
|
|
16
|
-
static auto make(auto& env, void* pointer) ->
|
|
12
|
+
static auto make(auto& env, void* pointer) -> value_of<external_tag>;
|
|
17
13
|
|
|
18
14
|
// tagged
|
|
19
15
|
template <class Type>
|
|
20
|
-
static auto make(auto& env, Type* pointer) ->
|
|
16
|
+
static auto make(auto& env, Type* pointer) -> value_of<external_tag>;
|
|
21
17
|
};
|
|
22
18
|
|
|
23
19
|
class bound_value_for_external : public bound_value_next<external_tag> {
|
|
@@ -30,13 +26,13 @@ class bound_value_for_external : public bound_value_next<external_tag> {
|
|
|
30
26
|
|
|
31
27
|
// ---
|
|
32
28
|
|
|
33
|
-
auto value_for_external::make(auto& env, void* pointer) ->
|
|
29
|
+
auto value_for_external::make(auto& env, void* pointer) -> value_of<external_tag> {
|
|
34
30
|
auto* external = napi::invoke(napi_create_external, napi_env{env}, pointer, nullptr, nullptr);
|
|
35
|
-
return
|
|
31
|
+
return value_of<external_tag>::from(external);
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
template <class Type>
|
|
39
|
-
auto value_for_external::make(auto& env, Type* pointer) ->
|
|
35
|
+
auto value_for_external::make(auto& env, Type* pointer) -> value_of<external_tag> {
|
|
40
36
|
auto external = make(env, static_cast<void*>(pointer));
|
|
41
37
|
napi::invoke0(napi_type_tag_object, napi_env{env}, external, &type_tag_for<Type>);
|
|
42
38
|
return external;
|
package/value/function.cc
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
module;
|
|
2
|
-
#include <array>
|
|
3
|
-
#include <span>
|
|
4
|
-
#include <tuple>
|
|
5
|
-
#include <variant>
|
|
6
|
-
#include <vector>
|
|
7
1
|
export module napi_js:function_definitions;
|
|
8
|
-
import :api;
|
|
9
2
|
import :callback;
|
|
10
|
-
import
|
|
3
|
+
import std;
|
|
11
4
|
|
|
12
5
|
namespace js::napi {
|
|
13
6
|
|
|
@@ -31,15 +24,15 @@ auto value_for_function::invoke(auto_environment auto& env, std::span<napi_value
|
|
|
31
24
|
}
|
|
32
25
|
|
|
33
26
|
template <auto_environment Environment>
|
|
34
|
-
auto value_for_function::make(Environment& env, auto function) ->
|
|
27
|
+
auto value_for_function::make(Environment& env, auto function) -> value_of<function_tag> {
|
|
35
28
|
auto [ callback, data ] = make_callback_storage(env, make_free_function<Environment>(std::move(function).callback));
|
|
36
|
-
auto make = [ & ](void* data) ->
|
|
37
|
-
return
|
|
29
|
+
auto make = [ & ](void* data) -> value_of<function_tag> {
|
|
30
|
+
return value_of<function_tag>::from(napi::invoke(napi_create_function, napi_env{env}, function.name.data(), function.name.length(), callback, data));
|
|
38
31
|
};
|
|
39
32
|
if constexpr (requires { typename decltype(data)::element_type; }) {
|
|
40
33
|
// Function requires finalizer
|
|
41
34
|
auto function = make(data.get());
|
|
42
|
-
return apply_finalizer(std::move(data), [ & ](auto* data, napi_finalize finalize, void* hint) ->
|
|
35
|
+
return apply_finalizer(std::move(data), [ & ](auto* data, napi_finalize finalize, void* hint) -> value_of<function_tag> {
|
|
43
36
|
napi::invoke0(napi_add_finalizer, napi_env{env}, function, data, finalize, hint, nullptr);
|
|
44
37
|
return function;
|
|
45
38
|
});
|
package/value/function.h.cc
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
module;
|
|
2
|
-
#include <span>
|
|
3
|
-
#include <variant>
|
|
4
1
|
export module napi_js:function;
|
|
5
|
-
import :environment_fwd;
|
|
6
2
|
import :primitive;
|
|
7
|
-
import
|
|
8
|
-
import util;
|
|
3
|
+
import std;
|
|
9
4
|
|
|
10
5
|
namespace js::napi {
|
|
11
6
|
|
|
12
7
|
class value_for_function : public value_next<function_tag> {
|
|
13
8
|
public:
|
|
14
|
-
using value_next<function_tag>::value_next;
|
|
15
|
-
|
|
16
9
|
template <class Result = std::monostate>
|
|
17
10
|
auto apply(auto_environment auto& env, auto&& args) -> Result;
|
|
18
11
|
|
|
@@ -20,7 +13,7 @@ class value_for_function : public value_next<function_tag> {
|
|
|
20
13
|
auto call(auto_environment auto& env, auto&&... args) -> Result;
|
|
21
14
|
|
|
22
15
|
template <auto_environment Environment>
|
|
23
|
-
static auto make(Environment& env, auto function) ->
|
|
16
|
+
static auto make(Environment& env, auto function) -> value_of<function_tag>;
|
|
24
17
|
|
|
25
18
|
private:
|
|
26
19
|
template <class Result>
|
package/value/object.cc
CHANGED
|
@@ -6,8 +6,8 @@ import :value_handle;
|
|
|
6
6
|
namespace js::napi {
|
|
7
7
|
|
|
8
8
|
// object
|
|
9
|
-
auto bound_value_for_object::get(napi_value key) const ->
|
|
10
|
-
return
|
|
9
|
+
auto bound_value_for_object::get(napi_value key) const -> value_of<value_tag> {
|
|
10
|
+
return value_of<value_tag>::from(napi::invoke(napi_get_property, env(), napi_value{*this}, key));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
auto bound_value_for_object::has(napi_value key) const -> bool {
|
|
@@ -19,10 +19,6 @@ auto bound_value_for_object::set(napi_value key, napi_value value) -> void {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// date
|
|
22
|
-
auto value_for_date::make(const environment& env, js_clock::time_point date) -> value<date_tag> {
|
|
23
|
-
return value<date_tag>::from(napi::invoke(napi_create_date, napi_env{env}, date.time_since_epoch().count()));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
22
|
bound_value_for_date::operator js_clock::time_point() const {
|
|
27
23
|
return js_clock::time_point{js_clock::duration{napi::invoke(napi_get_date_value, env(), napi_value{*this})}};
|
|
28
24
|
}
|
package/value/object.h.cc
CHANGED
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
module;
|
|
2
|
-
#include <array>
|
|
3
|
-
#include <tuple>
|
|
4
|
-
#include <utility>
|
|
5
1
|
export module napi_js:object;
|
|
6
2
|
import :api;
|
|
7
3
|
import :bound_value;
|
|
8
4
|
import :environment_fwd;
|
|
9
5
|
import :primitive;
|
|
10
|
-
import
|
|
6
|
+
import std;
|
|
11
7
|
|
|
12
8
|
namespace js::napi {
|
|
13
9
|
|
|
14
10
|
// object
|
|
15
11
|
class value_for_object : public value_next<object_tag> {
|
|
16
12
|
public:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
auto assign(this value<object_tag> self, auto_environment auto& env, auto source) -> void;
|
|
13
|
+
auto assign(this value_of<object_tag> self, auto_environment auto& env, auto source) -> void;
|
|
20
14
|
};
|
|
21
15
|
|
|
22
16
|
class bound_value_for_object : public bound_value_next<object_tag> {
|
|
@@ -26,19 +20,13 @@ class bound_value_for_object : public bound_value_next<object_tag> {
|
|
|
26
20
|
template <class Type>
|
|
27
21
|
[[nodiscard]] auto try_cast(std::type_identity<Type> /*type*/) const -> Type*;
|
|
28
22
|
|
|
29
|
-
[[nodiscard]] auto get(napi_value key) const ->
|
|
23
|
+
[[nodiscard]] auto get(napi_value key) const -> value_of<value_tag>;
|
|
30
24
|
[[nodiscard]] auto has(napi_value key) const -> bool;
|
|
31
25
|
|
|
32
26
|
auto set(napi_value key, napi_value value) -> void;
|
|
33
27
|
};
|
|
34
28
|
|
|
35
29
|
// date
|
|
36
|
-
class value_for_date : public value_next<date_tag> {
|
|
37
|
-
public:
|
|
38
|
-
using value_next<date_tag>::value_next;
|
|
39
|
-
static auto make(const environment& env, js_clock::time_point date) -> value<date_tag>;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
30
|
class bound_value_for_date : public bound_value_next<date_tag> {
|
|
43
31
|
public:
|
|
44
32
|
using bound_value_next<date_tag>::bound_value_next;
|
|
@@ -56,4 +44,8 @@ auto bound_value_for_object::try_cast(std::type_identity<Type> /*type*/) const -
|
|
|
56
44
|
}
|
|
57
45
|
}
|
|
58
46
|
|
|
47
|
+
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125144
|
|
48
|
+
template class bound_value_next<data_block_tag>;
|
|
49
|
+
template class bound_value_next<array_buffer_view_tag>;
|
|
50
|
+
|
|
59
51
|
} // namespace js::napi
|
package/value/primitive.cc
CHANGED
|
@@ -1,83 +1,38 @@
|
|
|
1
|
-
module;
|
|
2
|
-
#include <cstdint>
|
|
3
|
-
#include <string>
|
|
4
|
-
#include <string_view>
|
|
5
1
|
module napi_js;
|
|
6
2
|
import :api;
|
|
7
3
|
import :bound_value;
|
|
8
4
|
import :value_handle;
|
|
5
|
+
import std;
|
|
9
6
|
|
|
10
7
|
namespace js::napi {
|
|
11
8
|
|
|
12
|
-
// undefined
|
|
13
|
-
auto value_for_undefined::make(const environment& env) -> value<undefined_tag> {
|
|
14
|
-
return value<undefined_tag>::from(napi::invoke(napi_get_undefined, napi_env{env}));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// null
|
|
18
|
-
auto value_for_null::make(const environment& env) -> value<null_tag> {
|
|
19
|
-
return value<null_tag>::from(napi::invoke(napi_get_null, napi_env{env}));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
9
|
// boolean
|
|
23
|
-
auto value_for_boolean::make(const environment& env, bool boolean) -> value<boolean_tag> {
|
|
24
|
-
return value<boolean_tag>::from(napi::invoke(napi_get_boolean, napi_env{env}, boolean));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
10
|
bound_value_for_boolean::operator bool() const {
|
|
28
11
|
return napi::invoke(napi_get_value_bool, env(), napi_value{*this});
|
|
29
12
|
}
|
|
30
13
|
|
|
31
14
|
// number
|
|
32
|
-
auto value_for_number::make(const environment& env, double number) -> value<number_tag> {
|
|
33
|
-
return value<number_tag>::from(napi::invoke(napi_create_double, napi_env{env}, number));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
auto value_for_number::make(const environment& env, int32_t number) -> value<number_tag> {
|
|
37
|
-
return value<number_tag>::from(napi::invoke(napi_create_int32, napi_env{env}, number));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
auto value_for_number::make(const environment& env, int64_t number) -> value<number_tag> {
|
|
41
|
-
return value<number_tag>::from(napi::invoke(napi_create_int64, napi_env{env}, number));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
auto value_for_number::make(const environment& env, uint32_t number) -> value<number_tag> {
|
|
45
|
-
return value<number_tag>::from(napi::invoke(napi_create_uint32, napi_env{env}, number));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
15
|
bound_value_for_number::operator double() const {
|
|
49
16
|
return napi::invoke(napi_get_value_double, env(), napi_value{*this});
|
|
50
17
|
}
|
|
51
18
|
|
|
52
|
-
bound_value_for_number::operator int32_t() const {
|
|
19
|
+
bound_value_for_number::operator std::int32_t() const {
|
|
53
20
|
return napi::invoke(napi_get_value_int32, env(), napi_value{*this});
|
|
54
21
|
}
|
|
55
22
|
|
|
56
|
-
bound_value_for_number::operator int64_t() const {
|
|
23
|
+
bound_value_for_number::operator std::int64_t() const {
|
|
57
24
|
return napi::invoke(napi_get_value_int64, env(), napi_value{*this});
|
|
58
25
|
}
|
|
59
26
|
|
|
60
|
-
bound_value_for_number::operator uint32_t() const {
|
|
27
|
+
bound_value_for_number::operator std::uint32_t() const {
|
|
61
28
|
return napi::invoke(napi_get_value_uint32, env(), napi_value{*this});
|
|
62
29
|
}
|
|
63
30
|
|
|
64
31
|
// bigint
|
|
65
|
-
auto value_for_bigint::make(const environment& env, const bigint& number) -> value<bigint_tag> {
|
|
66
|
-
return value<bigint_tag>::from(napi::invoke(napi_create_bigint_words, napi_env{env}, number.sign_bit(), number.size(), number.data()));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
auto value_for_bigint::make(const environment& env, int64_t number) -> value<bigint_tag> {
|
|
70
|
-
return value<bigint_tag>::from(napi::invoke(napi_create_bigint_int64, napi_env{env}, number));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
auto value_for_bigint::make(const environment& env, uint64_t number) -> value<bigint_tag> {
|
|
74
|
-
return value<bigint_tag>::from(napi::invoke(napi_create_bigint_uint64, napi_env{env}, number));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
32
|
bound_value_for_bigint::operator bigint() const {
|
|
78
33
|
js::bigint value;
|
|
79
|
-
auto one_word = uint64_t{};
|
|
80
|
-
auto length = size_t{1};
|
|
34
|
+
auto one_word = std::uint64_t{};
|
|
35
|
+
auto length = std::size_t{1};
|
|
81
36
|
napi::invoke0(napi_get_value_bigint_words, env(), napi_value{*this}, &value.sign_bit(), &length, &one_word);
|
|
82
37
|
if (value.sign_bit() == 0 && length == 1) {
|
|
83
38
|
return js::bigint{one_word};
|
|
@@ -91,52 +46,28 @@ bound_value_for_bigint::operator bigint() const {
|
|
|
91
46
|
return value;
|
|
92
47
|
}
|
|
93
48
|
|
|
94
|
-
bound_value_for_bigint::operator int64_t() const {
|
|
49
|
+
bound_value_for_bigint::operator std::int64_t() const {
|
|
95
50
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
96
|
-
int64_t value;
|
|
51
|
+
std::int64_t value;
|
|
97
52
|
// nb: `lossless` error not checked for consistency with `napi_get_value_int32`,
|
|
98
53
|
// `napi_get_value_string_latin1`, etc which don't return any errors.
|
|
99
54
|
napi::invoke(napi_get_value_bigint_int64, env(), napi_value{*this}, &value);
|
|
100
55
|
return value;
|
|
101
56
|
}
|
|
102
57
|
|
|
103
|
-
bound_value_for_bigint::operator uint64_t() const {
|
|
58
|
+
bound_value_for_bigint::operator std::uint64_t() const {
|
|
104
59
|
// NOLINTNEXTLINE(cppcoreguidelines-init-variables)
|
|
105
|
-
uint64_t value;
|
|
60
|
+
std::uint64_t value;
|
|
106
61
|
napi::invoke(napi_get_value_bigint_uint64, env(), napi_value{*this}, &value);
|
|
107
62
|
return value;
|
|
108
63
|
}
|
|
109
64
|
|
|
110
65
|
// string
|
|
111
|
-
auto value_for_string::make(const environment& env, std::string_view string) -> value<string_tag> {
|
|
112
|
-
return value<string_tag>::from(napi::invoke(napi_create_string_latin1, napi_env{env}, string.data(), string.length()));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
auto value_for_string::make(const environment& env, std::u8string_view string) -> value<string_tag> {
|
|
116
|
-
return value<string_tag>::from(napi::invoke(napi_create_string_utf8, napi_env{env}, reinterpret_cast<const char*>(string.data()), string.length()));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
auto value_for_string::make(const environment& env, std::u16string_view string) -> value<string_tag> {
|
|
120
|
-
return value<string_tag>::from(napi::invoke(napi_create_string_utf16, napi_env{env}, string.data(), string.length()));
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
auto value_for_string::make_property_name(const environment& env, std::string_view string) -> value<string_tag> {
|
|
124
|
-
return value<string_tag>::from(napi::invoke(node_api_create_property_key_latin1, napi_env{env}, reinterpret_cast<const char*>(string.data()), string.length()));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
auto value_for_string::make_property_name(const environment& env, std::u8string_view string) -> value<string_tag> {
|
|
128
|
-
return value<string_tag>::from(napi::invoke(node_api_create_property_key_utf8, napi_env{env}, reinterpret_cast<const char*>(string.data()), string.length()));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
auto value_for_string::make_property_name(const environment& env, std::u16string_view string) -> value<string_tag> {
|
|
132
|
-
return value<string_tag>::from(napi::invoke(node_api_create_property_key_utf16, napi_env{env}, string.data(), string.length()));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
66
|
bound_value_for_string::operator std::string() const {
|
|
136
67
|
std::string string;
|
|
137
68
|
auto length = napi::invoke(napi_get_value_string_latin1, env(), napi_value{*this}, nullptr, 0);
|
|
138
69
|
if (length > 0) {
|
|
139
|
-
string.resize_and_overwrite(length + 1, [ this ](char* data, size_t length) noexcept -> size_t {
|
|
70
|
+
string.resize_and_overwrite(length + 1, [ this ](char* data, std::size_t length) noexcept -> std::size_t {
|
|
140
71
|
napi::invoke_noexcept(napi_get_value_string_latin1, env(), napi_value{*this}, data, length);
|
|
141
72
|
return length - 1;
|
|
142
73
|
});
|
|
@@ -149,7 +80,7 @@ bound_value_for_string::operator std::u16string() const {
|
|
|
149
80
|
std::u16string string;
|
|
150
81
|
auto length = napi::invoke(napi_get_value_string_utf16, env(), napi_value{*this}, nullptr, 0);
|
|
151
82
|
if (length > 0) {
|
|
152
|
-
string.resize_and_overwrite(length + 1, [ this ](char16_t* data, size_t length) noexcept -> size_t {
|
|
83
|
+
string.resize_and_overwrite(length + 1, [ this ](char16_t* data, std::size_t length) noexcept -> std::size_t {
|
|
153
84
|
napi::invoke_noexcept(napi_get_value_string_utf16, env(), napi_value{*this}, data, length);
|
|
154
85
|
return length - 1;
|
|
155
86
|
});
|