@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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export module napi_js:transfer_list;
|
|
2
|
+
import :lock;
|
|
3
|
+
import :support.host;
|
|
4
|
+
import :utility;
|
|
5
|
+
import :value;
|
|
6
|
+
import std;
|
|
7
|
+
import util;
|
|
8
|
+
|
|
9
|
+
namespace js::napi {
|
|
10
|
+
|
|
11
|
+
// Transfer delegate for `ArrayBuffer`
|
|
12
|
+
export class array_buffer_transfer {
|
|
13
|
+
public:
|
|
14
|
+
array_buffer_transfer(environment_lock_witness lock, std::vector<local_of<>>& entries) :
|
|
15
|
+
lock_{lock},
|
|
16
|
+
buffers_{[ & ] -> auto {
|
|
17
|
+
auto maybe_claim_in = [ & ](napi_value value) -> std::optional<local_of<array_buffer_tag>> {
|
|
18
|
+
if (is_object_array_buffer(napi_env{lock}, local_of<object_tag>::from(value))) {
|
|
19
|
+
return local_of<array_buffer_tag>::from(value);
|
|
20
|
+
} else {
|
|
21
|
+
return std::nullopt;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return js::extract_transferees(util::cw<u"ArrayBuffer">, maybe_claim_in, addressof_equal{}, entries);
|
|
25
|
+
}()} {}
|
|
26
|
+
|
|
27
|
+
template <class Visit, class Accept>
|
|
28
|
+
auto operator()(local_of<object_tag> subject, Visit& visit, const Accept& accept) {
|
|
29
|
+
return maybe_claim_out(subject, visit, accept);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
template <class Visit, class Accept>
|
|
33
|
+
auto operator()(local_of<data_block_tag> subject, Visit& visit, const Accept& accept) {
|
|
34
|
+
return maybe_claim_out(subject, visit, accept);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Detaches listed buffers which were never claimed by the visitor
|
|
38
|
+
auto finalize() -> void {
|
|
39
|
+
for (auto entry : std::exchange(buffers_, {})) {
|
|
40
|
+
value_of{lock_, entry}.detach();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private:
|
|
45
|
+
template <class Visit, class Accept>
|
|
46
|
+
auto maybe_claim_out(auto subject, Visit& visit, const Accept& accept) {
|
|
47
|
+
auto claim_out = [ & ](local_of<array_buffer_tag> handle) -> accept_target_t<Accept> {
|
|
48
|
+
auto value = value_of{lock_, handle};
|
|
49
|
+
auto buffer = [ & ] -> js::array_buffer {
|
|
50
|
+
if (array_buffer_get_backing_store == nullptr || value.byte_length() == 0) {
|
|
51
|
+
return js::array_buffer{std::span<std::byte>{value}};
|
|
52
|
+
} else {
|
|
53
|
+
// Steal the backing store, avoiding a copy of the contents
|
|
54
|
+
auto backing_store = std::make_unique<std::shared_ptr<data_block::array_type>>(array_buffer_get_backing_store(local_of{value}));
|
|
55
|
+
return js::array_buffer{
|
|
56
|
+
std::span<std::byte>{value},
|
|
57
|
+
js::array_buffer::deleter{
|
|
58
|
+
[](std::shared_ptr<data_block::array_type>* backing_store, std::byte* /*data*/) -> void {
|
|
59
|
+
delete backing_store;
|
|
60
|
+
},
|
|
61
|
+
backing_store.release()
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}();
|
|
66
|
+
value.detach();
|
|
67
|
+
return accept(array_buffer_tag{}, visit, js::transferred_value{napi_value{handle}, buffer});
|
|
68
|
+
};
|
|
69
|
+
return js::claim_transferee(buffers_, subject, addressof_equal{}, claim_out);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
environment_lock_witness lock_;
|
|
73
|
+
std::vector<local_of<array_buffer_tag>> buffers_;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Napi 'transferList' delegate
|
|
77
|
+
export template <class... Delegates>
|
|
78
|
+
class transfer_list {
|
|
79
|
+
public:
|
|
80
|
+
template <class Type>
|
|
81
|
+
transfer_list(const auto& lock, std::optional<Type> list) :
|
|
82
|
+
transfer_list{lock, list ? std::vector{std::from_range, list->values()} : std::vector<local_of<>>{}} {}
|
|
83
|
+
|
|
84
|
+
transfer_list(const auto& lock, value_of<list_tag> list) :
|
|
85
|
+
transfer_list{lock, std::vector{std::from_range, list.values()}} {}
|
|
86
|
+
|
|
87
|
+
// Constructs a list in place and invokes the given operation with it, finalizing afterwards
|
|
88
|
+
static auto with(const auto& lock, auto list, auto operation) {
|
|
89
|
+
auto self = transfer_list{lock, std::move(list)};
|
|
90
|
+
auto result = operation(self);
|
|
91
|
+
self.finalize();
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Offers the subject to each delegate in order, claiming with the first which engages
|
|
96
|
+
template <class Visit, class Accept>
|
|
97
|
+
auto operator()(auto subject, Visit& visit, const Accept& accept) -> std::optional<accept_target_t<Accept>> {
|
|
98
|
+
return util::template_traverse(
|
|
99
|
+
util::sequence_cw<sizeof...(Delegates)>,
|
|
100
|
+
util::overloaded{
|
|
101
|
+
[ & ](auto ii, auto next) -> std::optional<accept_target_t<Accept>> {
|
|
102
|
+
auto& delegate = std::get<ii>(delegates_);
|
|
103
|
+
if constexpr (std::invocable<decltype(delegate), decltype(subject), Visit&, const Accept&>) {
|
|
104
|
+
if (auto claim = delegate(subject, visit, accept)) {
|
|
105
|
+
return std::optional{(*std::move(claim))()};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return next();
|
|
109
|
+
},
|
|
110
|
+
[] -> std::optional<accept_target_t<Accept>> { return std::nullopt; },
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
auto finalize() -> void {
|
|
116
|
+
constexpr auto [... ii ] = util::sequence<sizeof...(Delegates)>;
|
|
117
|
+
(..., std::get<ii>(delegates_).finalize());
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private:
|
|
121
|
+
// Each delegate claims its entries from the vector. Anything left over is unknown.
|
|
122
|
+
transfer_list(const auto& lock, std::vector<local_of<>> entries) :
|
|
123
|
+
delegates_{Delegates{lock, entries}...} {
|
|
124
|
+
if (!entries.empty()) {
|
|
125
|
+
throw js::type_error{u"Transfer list contains unknown value"};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
std::tuple<Delegates...> delegates_;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
} // namespace js::napi
|