@auto_js/napi 0.0.8 → 0.0.9
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 +1 -1
- package/README.md +8 -8
- package/_module.cc +3 -3
- package/api/threadsafe_function.cc +2 -5
- package/handle/local.cc +112 -0
- package/handle/reference.cc +3 -3
- package/handle/remote.cc +10 -10
- package/handle/types.cc +9 -142
- package/handle/value.cc +122 -30
- package/package.json +4 -4
- package/support/callback.cc +3 -3
- package/support/callback_storage.cc +2 -2
- package/support/class_template_storage.cc +2 -2
- package/support/host.cc +37 -33
- package/support/host.h.cc +11 -11
- package/support/initialize.h.cc +2 -2
- package/support/promise.cc +2 -2
- package/transfer/accept.cc +34 -34
- package/transfer/accept.h.cc +81 -71
- package/transfer/visit.cc +115 -72
- package/value/array.cc +5 -7
- package/value/array.h.cc +7 -7
- package/value/array_buffer.cc +26 -29
- package/value/array_buffer.h.cc +50 -52
- package/value/class.cc +8 -9
- package/value/class.h.cc +5 -5
- package/value/external.cc +9 -11
- package/value/function.cc +7 -7
- package/value/function.h.cc +2 -2
- package/value/object.cc +5 -8
- package/value/object.h.cc +8 -15
- package/value/primitive.cc +7 -10
- package/value/primitive.h.cc +15 -15
- package/value/record.cc +6 -8
- package/value/record.h.cc +8 -8
- package/value/value.cc +3 -1
- package/handle/bound_value.cc +0 -47
package/CMakeLists.txt
CHANGED
package/README.md
CHANGED
|
@@ -181,20 +181,20 @@ struct enum_values<enum_test> {
|
|
|
181
181
|
|
|
182
182
|
## Variants
|
|
183
183
|
|
|
184
|
-
`std::variant<std::u16string, double>` could be used to accept *either* a
|
|
185
|
-
You can mix and match types as needed.
|
|
184
|
+
`std::variant<std::u16string, std::string, double, std::int32_t>` could be used to accept *either* a
|
|
185
|
+
string or a number value. You can mix and match types as needed. If you use one of the covariant
|
|
186
|
+
types then you must also use its alternative. `std::u16string, std::string`, `double, std::int32_t`,
|
|
187
|
+
and `std::int64_t, js::bigint`.
|
|
186
188
|
|
|
187
189
|
|
|
188
190
|
## Covariants
|
|
189
191
|
|
|
190
192
|
`std::variant<double, int32_t>` can be used to accept *either* a floating point or a signed integer.
|
|
191
193
|
Note that this uses runtime function calls to resolve the covariance. In v8 it will invoke
|
|
192
|
-
`value->IsInt32()` to discover what to return.
|
|
193
|
-
be returned.
|
|
194
|
+
`value->IsInt32()` to discover what to return.
|
|
194
195
|
|
|
195
|
-
`std::variant<std::
|
|
196
|
+
`std::variant<std::u16string, std::string>` can be used in a similar way to accept either a UTF-16
|
|
196
197
|
string or the optimized ASCII string. This uses `value->IsOneByte()` to resolve the covariance.
|
|
197
|
-
Again, in napi a UTF-16 string will always be returned.
|
|
198
198
|
|
|
199
199
|
|
|
200
200
|
## Structures
|
|
@@ -274,8 +274,8 @@ export class database {
|
|
|
274
274
|
using transfer_type = js::tagged_external<database>;
|
|
275
275
|
|
|
276
276
|
auto query(environment& env, std::string query) -> std::string;
|
|
277
|
-
static auto connect(environment& env, std::string uri) -> js::forward<js::napi::
|
|
278
|
-
static auto class_template(environment& env) -> js::napi::
|
|
277
|
+
static auto connect(environment& env, std::string uri) -> js::forward<js::napi::local_of<>>;
|
|
278
|
+
static auto class_template(environment& env) -> js::napi::local_of<class_tag_of<database>> {
|
|
279
279
|
// incomplete
|
|
280
280
|
}
|
|
281
281
|
};
|
package/_module.cc
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
export module napi_js;
|
|
2
2
|
export import :accept;
|
|
3
3
|
export import :api;
|
|
4
|
-
export import :bound_value;
|
|
5
4
|
export import :callback;
|
|
6
5
|
export import :class_definitions;
|
|
7
6
|
export import :class_template_storage;
|
|
8
7
|
export import :environment;
|
|
9
8
|
export import :error_scope;
|
|
10
9
|
export import :function_definitions;
|
|
11
|
-
export import :handle.types;
|
|
12
10
|
export import :initialize;
|
|
13
11
|
export import :promise;
|
|
14
12
|
export import :reference;
|
|
15
13
|
export import :remote;
|
|
16
14
|
export import :string_table;
|
|
17
15
|
export import :utility;
|
|
18
|
-
export import :
|
|
16
|
+
export import :handle.local_of;
|
|
17
|
+
export import :handle.types;
|
|
18
|
+
export import :handle.value_of;
|
|
19
19
|
export import :value;
|
|
20
20
|
export import :visit;
|
|
@@ -57,9 +57,7 @@ threadsafe_function_of<Context, Message>::threadsafe_function_of(auto& env, napi
|
|
|
57
57
|
auto& context = *static_cast<storage*>(context_ptr);
|
|
58
58
|
if constexpr (trivial_message) {
|
|
59
59
|
if (env != nullptr) {
|
|
60
|
-
|
|
61
|
-
std::memcpy(&message, &data, sizeof(Message));
|
|
62
|
-
context(env, value, message);
|
|
60
|
+
context(env, value, util::bit_truncation_cast<Message>(data));
|
|
63
61
|
}
|
|
64
62
|
} else {
|
|
65
63
|
auto message = std::unique_ptr<Message>{static_cast<Message*>(data)};
|
|
@@ -134,8 +132,7 @@ auto threadsafe_function_of<Context, Message>::operator()(Message message) const
|
|
|
134
132
|
}
|
|
135
133
|
};
|
|
136
134
|
if constexpr (trivial_message) {
|
|
137
|
-
|
|
138
|
-
std::memcpy(&data, &message, sizeof(Message));
|
|
135
|
+
auto* data = util::bit_padding_cast<void*>(message);
|
|
139
136
|
return check(napi_call_threadsafe_function(tsfn_, data, napi_tsfn_nonblocking));
|
|
140
137
|
} else {
|
|
141
138
|
auto message_ptr = std::make_unique<Message>(std::move(message));
|
package/handle/local.cc
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
export module napi_js:handle.local_of;
|
|
2
|
+
import :handle.types;
|
|
3
|
+
import auto_js;
|
|
4
|
+
import nodejs;
|
|
5
|
+
import std;
|
|
6
|
+
import util;
|
|
7
|
+
|
|
8
|
+
namespace js::napi {
|
|
9
|
+
|
|
10
|
+
// Map of `local_of<Tag>` to its concrete implementation class
|
|
11
|
+
template <class Tag>
|
|
12
|
+
struct local_specialization;
|
|
13
|
+
|
|
14
|
+
// Tagged napi_value. Each `local_of<T>` inherits from the tag before it which makes overloading
|
|
15
|
+
// acceptor functions naturally hierarchical.
|
|
16
|
+
export template <class Tag = value_tag>
|
|
17
|
+
class local_of : public local_of<typename Tag::tag_type> {
|
|
18
|
+
protected:
|
|
19
|
+
using local_type = local_specialization<Tag>::type;
|
|
20
|
+
explicit local_of(napi_value value) : local_of<typename Tag::tag_type>{value} {}
|
|
21
|
+
|
|
22
|
+
public:
|
|
23
|
+
local_of() = default;
|
|
24
|
+
using tag_type = Tag;
|
|
25
|
+
|
|
26
|
+
// Constructor from tagged `runtime_handle` flavors
|
|
27
|
+
explicit local_of(local_type value)
|
|
28
|
+
requires(type<local_type> != type<runtime_handle>) :
|
|
29
|
+
local_of{napi_value{value}} {}
|
|
30
|
+
|
|
31
|
+
// "Downcast" to a more specific tag. Potentially unsafe.
|
|
32
|
+
template <std::convertible_to<Tag> To>
|
|
33
|
+
auto cast(To /*tag*/) const -> local_of<To> { return local_of<To>::from(*this); }
|
|
34
|
+
|
|
35
|
+
// Construct from any `napi_value`. Potentially unsafe.
|
|
36
|
+
static auto from(napi_value value_) -> local_of<Tag> { return std::bit_cast<local_of<Tag>>(value_); }
|
|
37
|
+
|
|
38
|
+
// Forward `make` to specialization
|
|
39
|
+
static auto make(auto&&... args) -> local_of<Tag> { return local_type::make(std::forward<decltype(args)>(args)...); }
|
|
40
|
+
|
|
41
|
+
// Dereference operators
|
|
42
|
+
auto operator*() const -> local_type { return std::bit_cast<local_type>(napi_value{*this}); }
|
|
43
|
+
auto operator->() const -> auto { return util::pointer_delegate{**this}; }
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Sentinel instantiation
|
|
47
|
+
template <>
|
|
48
|
+
class local_of<void> : public runtime_handle {
|
|
49
|
+
public:
|
|
50
|
+
using runtime_handle::runtime_handle;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Deduction guide
|
|
54
|
+
template <class Type>
|
|
55
|
+
local_of(Type value) -> local_of<typename Type::tag_type>;
|
|
56
|
+
|
|
57
|
+
// Details applied to each level of the `local_of<T>` hierarchy.
|
|
58
|
+
template <class Tag>
|
|
59
|
+
struct local_next : local_specialization<typename Tag::tag_type>::type {
|
|
60
|
+
using local_specialization<typename Tag::tag_type>::type::type;
|
|
61
|
+
using tag_type = Tag;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// `local_of<Tag>` implementation specializations. The default specialization selects the nearest
|
|
65
|
+
// specialization, or simply `runtime_handle` as the base class.
|
|
66
|
+
template <class Type> class local_for_class_of;
|
|
67
|
+
template <class Type> class local_for_typed_array_of;
|
|
68
|
+
|
|
69
|
+
template <class Tag>
|
|
70
|
+
struct local_specialization
|
|
71
|
+
: local_specialization<typename Tag::tag_type> {};
|
|
72
|
+
|
|
73
|
+
template <>
|
|
74
|
+
struct local_specialization<void>
|
|
75
|
+
: std::type_identity<runtime_handle> {};
|
|
76
|
+
|
|
77
|
+
template <>
|
|
78
|
+
struct local_specialization<object_tag>
|
|
79
|
+
: std::type_identity<class local_for_object> {};
|
|
80
|
+
|
|
81
|
+
template <>
|
|
82
|
+
struct local_specialization<function_tag>
|
|
83
|
+
: std::type_identity<class local_for_function> {};
|
|
84
|
+
|
|
85
|
+
template <>
|
|
86
|
+
struct local_specialization<typed_array_tag>
|
|
87
|
+
: std::type_identity<class local_for_typed_array> {};
|
|
88
|
+
|
|
89
|
+
template <class Type>
|
|
90
|
+
struct local_specialization<typed_array_tag_of<Type>>
|
|
91
|
+
: std::type_identity<class local_for_typed_array_of<Type>> {};
|
|
92
|
+
|
|
93
|
+
template <>
|
|
94
|
+
struct local_specialization<data_view_tag>
|
|
95
|
+
: std::type_identity<class local_for_data_view> {};
|
|
96
|
+
|
|
97
|
+
template <class Type>
|
|
98
|
+
struct local_specialization<class_tag_of<Type>>
|
|
99
|
+
: std::type_identity<class local_for_class_of<Type>> {};
|
|
100
|
+
|
|
101
|
+
template <>
|
|
102
|
+
struct local_specialization<external_tag>
|
|
103
|
+
: std::type_identity<class local_for_external> {};
|
|
104
|
+
|
|
105
|
+
} // namespace js::napi
|
|
106
|
+
|
|
107
|
+
// Specialize for `js::forward`. Makes `js::forward{local_of<Tag>}` infer
|
|
108
|
+
// `js::forward<Tag, ...>`.
|
|
109
|
+
namespace js {
|
|
110
|
+
template <class Tag>
|
|
111
|
+
struct forward_tag_for<napi::local_of<Tag>> : std::type_identity<Tag> {};
|
|
112
|
+
} // namespace js
|
package/handle/reference.cc
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export module napi_js:reference;
|
|
2
2
|
import :api;
|
|
3
|
-
import :
|
|
3
|
+
import :handle.local_of;
|
|
4
4
|
import std;
|
|
5
5
|
import util;
|
|
6
6
|
|
|
@@ -72,7 +72,7 @@ class reference_handle : util::non_copyable {
|
|
|
72
72
|
export template <class Tag>
|
|
73
73
|
class reference : public reference<typename Tag::tag_type> {
|
|
74
74
|
public:
|
|
75
|
-
using value_type =
|
|
75
|
+
using value_type = local_of<Tag>;
|
|
76
76
|
using reference<typename Tag::tag_type>::reference;
|
|
77
77
|
|
|
78
78
|
reference() = default;
|
|
@@ -86,7 +86,7 @@ class reference : public reference<typename Tag::tag_type> {
|
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
template <class Tag>
|
|
89
|
-
reference(auto,
|
|
89
|
+
reference(auto, local_of<Tag>) -> reference<Tag>;
|
|
90
90
|
|
|
91
91
|
// nb: Protected inheritance so that `remote<T> is not comparable to `reference<T>`.
|
|
92
92
|
template <>
|
package/handle/remote.cc
CHANGED
|
@@ -24,14 +24,14 @@ class remote : protected reference_handle {
|
|
|
24
24
|
using unique_remote = std::unique_ptr<remote, util::function_constant<expire>>;
|
|
25
25
|
|
|
26
26
|
remote() = default;
|
|
27
|
-
remote(private_constructor /*private*/, const environment& env,
|
|
27
|
+
remote(private_constructor /*private*/, const environment& env, local_of<Tag> value, napi_scheduler scheduler) :
|
|
28
28
|
reference_handle{napi_env{env}, napi_value{value}},
|
|
29
29
|
scheduler_{std::move(scheduler)} {}
|
|
30
30
|
|
|
31
|
-
auto deref(const environment& env) const ->
|
|
31
|
+
auto deref(const environment& env) const -> local_of<Tag>;
|
|
32
32
|
|
|
33
|
-
static auto make_shared(remote_handle_environment auto& env,
|
|
34
|
-
static auto make_unique(remote_handle_environment auto& env,
|
|
33
|
+
static auto make_shared(remote_handle_environment auto& env, local_of<Tag> value) -> std::shared_ptr<remote>;
|
|
34
|
+
static auto make_unique(remote_handle_environment auto& env, local_of<Tag> value) -> unique_remote;
|
|
35
35
|
|
|
36
36
|
private:
|
|
37
37
|
napi_scheduler scheduler_;
|
|
@@ -45,12 +45,12 @@ export template <class Type>
|
|
|
45
45
|
using unique_remote = remote<Type>::unique_remote;
|
|
46
46
|
|
|
47
47
|
export template <class Tag>
|
|
48
|
-
auto make_shared_remote(remote_handle_environment auto& env,
|
|
48
|
+
auto make_shared_remote(remote_handle_environment auto& env, local_of<Tag> value) -> shared_remote<Tag> {
|
|
49
49
|
return remote<Tag>::make_shared(env, value);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export template <class Tag>
|
|
53
|
-
auto make_unique_remote(remote_handle_environment auto& env,
|
|
53
|
+
auto make_unique_remote(remote_handle_environment auto& env, local_of<Tag> value) -> unique_remote<Tag> {
|
|
54
54
|
return remote<Tag>::make_unique(env, value);
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -68,17 +68,17 @@ auto remote<Tag>::expire(remote* ptr) -> void {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
template <class Tag>
|
|
71
|
-
auto remote<Tag>::deref(const environment& env) const ->
|
|
72
|
-
return
|
|
71
|
+
auto remote<Tag>::deref(const environment& env) const -> local_of<Tag> {
|
|
72
|
+
return local_of<Tag>::from(get_value(napi_env{env}));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
template <class Tag>
|
|
76
|
-
auto remote<Tag>::make_shared(remote_handle_environment auto& env,
|
|
76
|
+
auto remote<Tag>::make_shared(remote_handle_environment auto& env, local_of<Tag> value) -> std::shared_ptr<remote> {
|
|
77
77
|
return std::shared_ptr<remote>{new remote{private_constructor{}, env, value, env.scheduler()}, expire};
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
template <class Tag>
|
|
81
|
-
auto remote<Tag>::make_unique(remote_handle_environment auto& env,
|
|
81
|
+
auto remote<Tag>::make_unique(remote_handle_environment auto& env, local_of<Tag> value) -> unique_remote {
|
|
82
82
|
return unique_remote{new remote{private_constructor{}, env, value, env.scheduler()}};
|
|
83
83
|
}
|
|
84
84
|
|
package/handle/types.cc
CHANGED
|
@@ -4,14 +4,13 @@ import nodejs;
|
|
|
4
4
|
|
|
5
5
|
namespace js::napi {
|
|
6
6
|
|
|
7
|
-
// `
|
|
8
|
-
class
|
|
7
|
+
// `runtime_handle` is the base class of `local_of<T>` and `value_of<T>` member types.
|
|
8
|
+
class runtime_handle {
|
|
9
9
|
protected:
|
|
10
|
-
explicit value_handle(napi_value value) :
|
|
11
|
-
value_{value} {}
|
|
12
|
-
|
|
13
10
|
public:
|
|
14
|
-
|
|
11
|
+
explicit runtime_handle(int, napi_value value) : value_{value} {}
|
|
12
|
+
explicit runtime_handle(napi_value value) : value_{value} {}
|
|
13
|
+
runtime_handle() = default;
|
|
15
14
|
|
|
16
15
|
// Implicit cast back to a `napi_value`
|
|
17
16
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
@@ -24,143 +23,11 @@ class value_handle {
|
|
|
24
23
|
napi_value value_{};
|
|
25
24
|
};
|
|
26
25
|
|
|
27
|
-
//
|
|
26
|
+
// Forward declarations for handle types which declare template deduction guides on each other.
|
|
28
27
|
export template <class Tag = value_tag>
|
|
29
|
-
class
|
|
30
|
-
|
|
31
|
-
template <class Tag>
|
|
32
|
-
class value_next;
|
|
33
|
-
|
|
34
|
-
template <class Type>
|
|
35
|
-
class value_for_class_of;
|
|
36
|
-
|
|
37
|
-
template <class Type>
|
|
38
|
-
class value_for_typed_array_of;
|
|
39
|
-
|
|
40
|
-
// `bound_value` forward declarations
|
|
41
|
-
template <class Tag>
|
|
42
|
-
class bound_value;
|
|
43
|
-
|
|
44
|
-
template <class Tag>
|
|
45
|
-
class bound_value_next;
|
|
46
|
-
|
|
47
|
-
template <class Type>
|
|
48
|
-
class bound_value_for_typed_array_of;
|
|
49
|
-
|
|
50
|
-
// Map of `value_of<Tag>` / `bound_value<Tag>` to concrete implementation classes.
|
|
51
|
-
template <class Tag>
|
|
52
|
-
struct value_defaults {
|
|
53
|
-
using value_type = value_next<Tag>;
|
|
54
|
-
using bound_type = bound_value_next<Tag>;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
template <class Tag>
|
|
58
|
-
struct value_specialization : value_defaults<Tag> {};
|
|
59
|
-
|
|
60
|
-
// Typed specializations
|
|
61
|
-
template <>
|
|
62
|
-
struct value_specialization<boolean_tag> : value_defaults<boolean_tag> {
|
|
63
|
-
using bound_type = class bound_value_for_boolean;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
template <>
|
|
67
|
-
struct value_specialization<false_tag> : value_defaults<false_tag> {
|
|
68
|
-
using bound_type = class bound_value_for_false;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
template <>
|
|
72
|
-
struct value_specialization<true_tag> : value_defaults<true_tag> {
|
|
73
|
-
using bound_type = class bound_value_for_true;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
template <>
|
|
77
|
-
struct value_specialization<number_tag> : value_defaults<number_tag> {
|
|
78
|
-
using bound_type = class bound_value_for_number;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
template <>
|
|
82
|
-
struct value_specialization<bigint_tag> : value_defaults<bigint_tag> {
|
|
83
|
-
using bound_type = class bound_value_for_bigint;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
template <>
|
|
87
|
-
struct value_specialization<string_tag> : value_defaults<string_tag> {
|
|
88
|
-
using bound_type = class bound_value_for_string;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
template <>
|
|
92
|
-
struct value_specialization<date_tag> : value_defaults<date_tag> {
|
|
93
|
-
using bound_type = class bound_value_for_date;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
template <>
|
|
97
|
-
struct value_specialization<object_tag> {
|
|
98
|
-
using value_type = class value_for_object;
|
|
99
|
-
using bound_type = class bound_value_for_object;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
template <>
|
|
103
|
-
struct value_specialization<record_tag> : value_defaults<record_tag> {
|
|
104
|
-
using bound_type = class bound_value_for_record;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
template <>
|
|
108
|
-
struct value_specialization<function_tag> : value_defaults<function_tag> {
|
|
109
|
-
using value_type = class value_for_function;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
template <>
|
|
113
|
-
struct value_specialization<data_block_tag> : value_defaults<data_block_tag> {
|
|
114
|
-
using bound_type = class bound_value_for_data_block;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
template <>
|
|
118
|
-
struct value_specialization<array_buffer_tag> : value_defaults<array_buffer_tag> {
|
|
119
|
-
using bound_type = class bound_value_for_array_buffer;
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
template <>
|
|
123
|
-
struct value_specialization<shared_array_buffer_tag> : value_defaults<shared_array_buffer_tag> {
|
|
124
|
-
using bound_type = class bound_value_for_shared_array_buffer;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
template <>
|
|
128
|
-
struct value_specialization<array_buffer_view_tag> : value_defaults<array_buffer_view_tag> {
|
|
129
|
-
using bound_type = class bound_value_for_array_buffer_view;
|
|
130
|
-
};
|
|
28
|
+
class local_of;
|
|
131
29
|
|
|
132
|
-
template
|
|
133
|
-
|
|
134
|
-
using value_type = class value_for_typed_array;
|
|
135
|
-
using bound_type = class bound_value_for_typed_array;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
template <class Type>
|
|
139
|
-
struct value_specialization<typed_array_tag_of<Type>> {
|
|
140
|
-
using value_type = value_for_typed_array_of<Type>;
|
|
141
|
-
using bound_type = bound_value_for_typed_array_of<Type>;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
template <>
|
|
145
|
-
struct value_specialization<data_view_tag> {
|
|
146
|
-
using value_type = class value_for_data_view;
|
|
147
|
-
using bound_type = class bound_value_for_data_view;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
template <class Type>
|
|
151
|
-
struct value_specialization<class_tag_of<Type>> : value_defaults<class_tag_of<Type>> {
|
|
152
|
-
using value_type = value_for_class_of<Type>;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
template <>
|
|
156
|
-
struct value_specialization<external_tag> {
|
|
157
|
-
using value_type = class value_for_external;
|
|
158
|
-
using bound_type = class bound_value_for_external;
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
template <>
|
|
162
|
-
struct value_specialization<vector_tag> : value_defaults<vector_tag> {
|
|
163
|
-
using bound_type = class bound_value_for_vector;
|
|
164
|
-
};
|
|
30
|
+
export template <class Tag = value_tag>
|
|
31
|
+
class value_of;
|
|
165
32
|
|
|
166
33
|
} // namespace js::napi
|
package/handle/value.cc
CHANGED
|
@@ -1,55 +1,147 @@
|
|
|
1
|
-
export module napi_js:
|
|
1
|
+
export module napi_js:handle.value_of;
|
|
2
2
|
import :handle.types;
|
|
3
|
-
import auto_js;
|
|
4
3
|
import nodejs;
|
|
5
4
|
import std;
|
|
6
5
|
|
|
7
6
|
namespace js::napi {
|
|
8
7
|
|
|
9
|
-
//
|
|
10
|
-
|
|
8
|
+
// Map of `value_of<Tag>` to concrete implementation classes.
|
|
9
|
+
template <class Tag>
|
|
10
|
+
struct value_specialization;
|
|
11
|
+
|
|
12
|
+
// Heirarchy (for example):
|
|
13
|
+
// value_of<record_tag>
|
|
14
|
+
// value_for_record ->
|
|
15
|
+
// value_next<record_tag> ->
|
|
11
16
|
// value_for_object ->
|
|
12
17
|
// value_next<object_tag> ->
|
|
13
|
-
//
|
|
18
|
+
// value_next<value_tag> ->
|
|
19
|
+
// value_next<datum_tag> ->
|
|
20
|
+
// value_of<void>
|
|
14
21
|
|
|
15
22
|
// Details applied to each level of the `value_of<T>` hierarchy.
|
|
16
23
|
template <class Tag>
|
|
17
24
|
class value_next : public value_of<typename Tag::tag_type> {
|
|
18
25
|
public:
|
|
19
|
-
using
|
|
26
|
+
using tag_type = Tag;
|
|
27
|
+
value_next() = default;
|
|
28
|
+
value_next(auto&& env, local_of<Tag> value, auto&&... rest) :
|
|
29
|
+
value_of<typename Tag::tag_type>{std::forward<decltype(env)>(env), value, std::forward<decltype(rest)>(rest)...} {}
|
|
20
30
|
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
auto cast(To /*tag*/) const -> value_of<To> { return value_of<To>::from(*this); }
|
|
24
|
-
|
|
25
|
-
// Construct from any `napi_value`. Potentially unsafe.
|
|
26
|
-
static auto from(napi_value value_) -> value_of<Tag> { return std::bit_cast<value_of<Tag>>(value_); }
|
|
31
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
32
|
+
operator local_of<Tag>() const { return local_of<Tag>::from(napi_value{*this}); }
|
|
27
33
|
};
|
|
28
34
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
value_of
|
|
33
|
-
|
|
34
|
-
// Tagged napi_value
|
|
35
|
-
export template <class Tag>
|
|
36
|
-
class value_of : public value_specialization<Tag>::value_type {
|
|
35
|
+
// Member & method implementation for value semantics objects. It holds the type-erased environment
|
|
36
|
+
// and is used for common operations like casting & iteration.
|
|
37
|
+
template <class Tag>
|
|
38
|
+
class value_of : public value_specialization<Tag>::type {
|
|
37
39
|
public:
|
|
38
|
-
using value_specialization<Tag>::
|
|
40
|
+
using value_type = value_specialization<Tag>::type;
|
|
41
|
+
using value_type::value_type;
|
|
39
42
|
};
|
|
40
43
|
|
|
41
44
|
// Sentinel instantiation
|
|
42
45
|
template <>
|
|
43
|
-
class value_of<void> : public
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
class value_of<void> : public runtime_handle {
|
|
47
|
+
protected:
|
|
48
|
+
value_of() = default;
|
|
49
|
+
value_of(napi_env env, napi_value value) :
|
|
50
|
+
runtime_handle{value},
|
|
51
|
+
env_{env} {}
|
|
52
|
+
|
|
53
|
+
[[nodiscard]] auto env() const -> napi_env { return env_; }
|
|
54
|
+
|
|
55
|
+
private:
|
|
56
|
+
napi_env env_{};
|
|
46
57
|
};
|
|
47
58
|
|
|
48
|
-
|
|
59
|
+
// Deduction guide
|
|
60
|
+
template <class Tag>
|
|
61
|
+
value_of(auto, local_of<Tag>) -> value_of<Tag>;
|
|
62
|
+
|
|
63
|
+
// `value_of<Tag>` specializations. The default specialization selects `value_next` for the
|
|
64
|
+
// immediate parent tag, instantiating it for each tag unconditionally.
|
|
65
|
+
template <class Type> class value_for_typed_array_of;
|
|
49
66
|
|
|
50
|
-
// Specialize for `js::forward`. Makes `js::forward{value_of<Tag>}` infer
|
|
51
|
-
// `js::forward<Tag, ...>`.
|
|
52
|
-
namespace js {
|
|
53
67
|
template <class Tag>
|
|
54
|
-
struct
|
|
55
|
-
|
|
68
|
+
struct value_specialization
|
|
69
|
+
: std::type_identity<value_next<Tag>> {};
|
|
70
|
+
|
|
71
|
+
template <>
|
|
72
|
+
struct value_specialization<void>
|
|
73
|
+
: std::type_identity<value_of<void>> {};
|
|
74
|
+
|
|
75
|
+
template <>
|
|
76
|
+
struct value_specialization<boolean_tag>
|
|
77
|
+
: std::type_identity<class value_for_boolean> {};
|
|
78
|
+
|
|
79
|
+
template <>
|
|
80
|
+
struct value_specialization<false_tag>
|
|
81
|
+
: std::type_identity<class value_for_false> {};
|
|
82
|
+
|
|
83
|
+
template <>
|
|
84
|
+
struct value_specialization<true_tag>
|
|
85
|
+
: std::type_identity<class value_for_true> {};
|
|
86
|
+
|
|
87
|
+
template <>
|
|
88
|
+
struct value_specialization<number_tag>
|
|
89
|
+
: std::type_identity<class value_for_number> {};
|
|
90
|
+
|
|
91
|
+
template <>
|
|
92
|
+
struct value_specialization<bigint_tag>
|
|
93
|
+
: std::type_identity<class value_for_bigint> {};
|
|
94
|
+
|
|
95
|
+
template <>
|
|
96
|
+
struct value_specialization<string_tag>
|
|
97
|
+
: std::type_identity<class value_for_string> {};
|
|
98
|
+
|
|
99
|
+
template <>
|
|
100
|
+
struct value_specialization<object_tag>
|
|
101
|
+
: std::type_identity<class value_for_object> {};
|
|
102
|
+
|
|
103
|
+
template <>
|
|
104
|
+
struct value_specialization<date_tag>
|
|
105
|
+
: std::type_identity<class value_for_date> {};
|
|
106
|
+
|
|
107
|
+
template <>
|
|
108
|
+
struct value_specialization<record_tag>
|
|
109
|
+
: std::type_identity<class value_for_record> {};
|
|
110
|
+
|
|
111
|
+
template <>
|
|
112
|
+
struct value_specialization<data_block_tag>
|
|
113
|
+
: std::type_identity<class value_for_data_block> {};
|
|
114
|
+
|
|
115
|
+
template <>
|
|
116
|
+
struct value_specialization<array_buffer_tag>
|
|
117
|
+
: std::type_identity<class value_for_array_buffer> {};
|
|
118
|
+
|
|
119
|
+
template <>
|
|
120
|
+
struct value_specialization<shared_array_buffer_tag>
|
|
121
|
+
: std::type_identity<class value_for_shared_array_buffer> {};
|
|
122
|
+
|
|
123
|
+
template <>
|
|
124
|
+
struct value_specialization<array_buffer_view_tag>
|
|
125
|
+
: std::type_identity<class value_for_array_buffer_view> {};
|
|
126
|
+
|
|
127
|
+
template <>
|
|
128
|
+
struct value_specialization<typed_array_tag>
|
|
129
|
+
: std::type_identity<class value_for_typed_array> {};
|
|
130
|
+
|
|
131
|
+
template <class Type>
|
|
132
|
+
struct value_specialization<typed_array_tag_of<Type>>
|
|
133
|
+
: std::type_identity<value_for_typed_array_of<Type>> {};
|
|
134
|
+
|
|
135
|
+
template <>
|
|
136
|
+
struct value_specialization<data_view_tag>
|
|
137
|
+
: std::type_identity<class value_for_data_view> {};
|
|
138
|
+
|
|
139
|
+
template <>
|
|
140
|
+
struct value_specialization<external_tag>
|
|
141
|
+
: std::type_identity<class value_for_external> {};
|
|
142
|
+
|
|
143
|
+
template <>
|
|
144
|
+
struct value_specialization<vector_tag>
|
|
145
|
+
: std::type_identity<class value_for_vector> {};
|
|
146
|
+
|
|
147
|
+
} // namespace js::napi
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auto_js/napi",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"author": "https://github.com/laverdet/",
|
|
5
5
|
"description": "Automatic JavaScript to N-API bindings",
|
|
6
6
|
"homepage": "https://github.com/laverdet/isolated-vm/tree/experimental/packages/auto_js/napi",
|
|
7
7
|
"license": "ISC",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@auto_js/
|
|
10
|
-
"@auto_js/
|
|
11
|
-
"@auto_js/
|
|
9
|
+
"@auto_js/v8_exports": "^0.0.7",
|
|
10
|
+
"@auto_js/js": "^0.0.9",
|
|
11
|
+
"@auto_js/napi_exports": "^0.0.9"
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
package/support/callback.cc
CHANGED
|
@@ -13,7 +13,7 @@ template <class Type>
|
|
|
13
13
|
constexpr auto unwrap_member_this = [](auto_environment auto& env, napi_value this_arg) noexcept -> std::optional<tagged_external<Type>> {
|
|
14
14
|
return napi::invoke_maybe(napi_coerce_to_object, napi_env{env}, this_arg)
|
|
15
15
|
.and_then([ &env ](napi_value coerced_this_arg) -> std::optional<tagged_external<Type>> {
|
|
16
|
-
auto as_object =
|
|
16
|
+
auto as_object = value_of{env, local_of<object_tag>::from(coerced_this_arg)};
|
|
17
17
|
// Technically `try_cast` can throw but it should only be in catastrophic cases.
|
|
18
18
|
Type* unwrapped = as_object.try_cast(type<Type>);
|
|
19
19
|
if (unwrapped == nullptr) {
|
|
@@ -116,7 +116,7 @@ constexpr auto make_constructor_function(auto constructor) {
|
|
|
116
116
|
auto instance = std::apply(
|
|
117
117
|
callback,
|
|
118
118
|
std::tuple_cat(
|
|
119
|
-
std::forward_as_tuple(env,
|
|
119
|
+
std::forward_as_tuple(env, local_of<object_tag>::from(info.this_arg())),
|
|
120
120
|
js::transfer_out<std::tuple<js::functional::parameter_transfer_as_t<Args>...>>(info.arguments(), env)
|
|
121
121
|
)
|
|
122
122
|
);
|
|
@@ -136,7 +136,7 @@ constexpr auto make_constructor_function(auto constructor) {
|
|
|
136
136
|
using callback_type = decltype(callback);
|
|
137
137
|
return util::bind{
|
|
138
138
|
[](callback_type& callback, Environment& env, const callback_info& info) noexcept -> napi_value {
|
|
139
|
-
return wrap(callback(env,
|
|
139
|
+
return wrap(callback(env, local_of<object_tag>::from(info.this_arg())));
|
|
140
140
|
},
|
|
141
141
|
std::move(callback),
|
|
142
142
|
};
|