@auto_js/napi 0.0.7 → 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 +13 -2
- package/README.md +8 -8
- package/_module.cc +3 -3
- package/api/finalizer.cc +12 -14
- package/api/napi_scheduler.cc +3 -3
- package/api/napi_scheduler.h.cc +7 -6
- package/api/threadsafe_function.cc +12 -14
- package/api/uv_dlib.cc +4 -3
- package/handle/local.cc +112 -0
- package/handle/reference.cc +5 -5
- package/handle/remote.cc +11 -10
- package/handle/types.cc +9 -132
- 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 +197 -84
- package/support/host.h.cc +30 -14
- package/support/initialize.h.cc +2 -2
- package/support/promise.cc +10 -8
- package/support/win32_delay_load_hook.cc +12 -0
- package/transfer/accept.cc +34 -34
- package/transfer/accept.h.cc +81 -71
- package/transfer/visit.cc +182 -130
- package/value/array.cc +5 -7
- package/value/array.h.cc +7 -7
- package/value/array_buffer.cc +27 -32
- 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 +24 -11
- 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/support/host_shim.cc +0 -42
package/transfer/visit.cc
CHANGED
|
@@ -24,7 +24,7 @@ struct visit_property_name {
|
|
|
24
24
|
auto operator()(napi_value subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
25
25
|
return visit_.get().lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
|
|
26
26
|
auto accept_as = [ & ]<class Tag>(Tag tag) -> auto {
|
|
27
|
-
auto value =
|
|
27
|
+
auto value = value_of{napi_env{visit_.get()}, local_of<Tag>::from(subject)};
|
|
28
28
|
return accept(tag, *this, value);
|
|
29
29
|
};
|
|
30
30
|
switch (napi::invoke(napi_typeof, napi_env{visit_.get()}, subject)) {
|
|
@@ -50,17 +50,17 @@ struct visit_napi_key_literal {
|
|
|
50
50
|
|
|
51
51
|
auto operator()(const auto& /*could_be_literally_anything*/, const auto& accept_or_visit) -> napi_value {
|
|
52
52
|
const auto make = util::overloaded{
|
|
53
|
-
[](auto& env, std::string_view subject) -> napi::
|
|
53
|
+
[](auto& env, std::string_view subject) -> napi::local_of<string_tag_of<char>> {
|
|
54
54
|
auto* value = napi::invoke(node_api_create_property_key_latin1, napi_env{env}, subject.data(), subject.length());
|
|
55
|
-
return napi::
|
|
55
|
+
return napi::local_of<string_tag_of<char>>::from(value);
|
|
56
56
|
},
|
|
57
|
-
[](auto& env, std::u16string_view subject) -> napi::
|
|
57
|
+
[](auto& env, std::u16string_view subject) -> napi::local_of<string_tag_of<char16_t>> {
|
|
58
58
|
auto* value = napi::invoke(node_api_create_property_key_utf16, napi_env{env}, subject.data(), subject.length());
|
|
59
|
-
return napi::
|
|
59
|
+
return napi::local_of<string_tag_of<char16_t>>::from(value);
|
|
60
60
|
},
|
|
61
|
-
[](auto& env, std::u8string_view subject) -> napi::
|
|
61
|
+
[](auto& env, std::u8string_view subject) -> napi::local_of<string_tag_of<char8_t>> {
|
|
62
62
|
auto* value = napi::invoke(node_api_create_property_key_utf8, napi_env{env}, reinterpret_cast<const char*>(subject.data()), subject.length());
|
|
63
|
-
return napi::
|
|
63
|
+
return napi::local_of<string_tag_of<char8_t>>::from(value);
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
66
|
if (local_key_ == napi_value{}) {
|
|
@@ -109,7 +109,7 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
|
|
|
109
109
|
// If the private `immediate` operation is defined: this public operation will first
|
|
110
110
|
// perform a reference map lookup, then delegate to the private operation if not found.
|
|
111
111
|
template <class Tag, class Accept>
|
|
112
|
-
auto operator()(
|
|
112
|
+
auto operator()(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept>
|
|
113
113
|
requires requires { immediate(subject, accept); } {
|
|
114
114
|
return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
|
|
115
115
|
return immediate(subject, accept);
|
|
@@ -118,31 +118,31 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
|
|
|
118
118
|
|
|
119
119
|
// Visit operations for non-refable types.
|
|
120
120
|
template <class Accept>
|
|
121
|
-
auto operator()(
|
|
121
|
+
auto operator()(local_of<null_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
122
122
|
return immediate(subject, accept);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
template <class Accept>
|
|
126
|
-
auto operator()(
|
|
126
|
+
auto operator()(local_of<undefined_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
127
127
|
return immediate(subject, accept);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
template <class Accept>
|
|
131
|
-
auto operator()(
|
|
131
|
+
auto operator()(local_of<boolean_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
132
132
|
return immediate(subject, accept);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
template <class Accept>
|
|
136
|
-
auto operator()(
|
|
137
|
-
if (
|
|
138
|
-
return immediate(
|
|
136
|
+
auto operator()(local_of<number_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
137
|
+
if (maybe_is_number_int32(subject).value_or(false)) {
|
|
138
|
+
return immediate(local_of<number_tag_of<std::int32_t>>::from(subject), accept);
|
|
139
139
|
} else {
|
|
140
|
-
return immediate(
|
|
140
|
+
return immediate(local_of<number_tag_of<double>>::from(subject), accept);
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
template <class Accept, class Type>
|
|
145
|
-
auto operator()(
|
|
145
|
+
auto operator()(local_of<number_tag_of<Type>> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
146
146
|
return immediate(subject, accept);
|
|
147
147
|
}
|
|
148
148
|
|
|
@@ -153,91 +153,100 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
|
|
|
153
153
|
// Check the reference map, and lookup type via napi
|
|
154
154
|
return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
|
|
155
155
|
// This is the pure-napi implementation
|
|
156
|
-
auto slow_path =
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
156
|
+
auto slow_path = util::overloaded{
|
|
157
|
+
[ & ]() -> accept_target_t<Accept> {
|
|
158
|
+
auto type_of = napi::invoke(napi_typeof, napi_env{*this}, subject);
|
|
159
|
+
switch (type_of) {
|
|
160
|
+
case napi_undefined:
|
|
161
|
+
return (*this)(local_of<undefined_tag>::from(subject), accept);
|
|
162
|
+
case napi_null:
|
|
163
|
+
return (*this)(local_of<null_tag>::from(subject), accept);
|
|
164
|
+
case napi_boolean:
|
|
165
|
+
return (*this)(local_of<boolean_tag>::from(subject), accept);
|
|
166
|
+
case napi_number:
|
|
167
|
+
return (*this)(local_of<number_tag>::from(subject), accept);
|
|
168
|
+
case napi_string:
|
|
169
|
+
return immediate(local_of<string_tag>::from(subject), accept);
|
|
170
|
+
case napi_symbol:
|
|
171
|
+
return immediate(local_of<symbol_tag>::from(subject), accept);
|
|
172
|
+
case napi_object:
|
|
173
|
+
return immediate(local_of<object_tag>::from(subject), accept);
|
|
174
|
+
case napi_function:
|
|
175
|
+
return immediate(local_of<function_tag>::from(subject), accept);
|
|
176
|
+
case napi_external:
|
|
177
|
+
return immediate(local_of<external_tag>::from(subject), accept);
|
|
178
|
+
case napi_bigint:
|
|
179
|
+
return immediate(local_of<bigint_tag>::from(subject), accept);
|
|
180
|
+
}
|
|
181
|
+
std::unreachable();
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
[](auto /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
181
185
|
};
|
|
182
186
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return fast_is_number(subject) ? (*this)(value_of<number_tag>::from(subject), accept) : next();
|
|
199
|
-
},
|
|
200
|
-
[ & ](string_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
201
|
-
return fast_is_string(subject) ? immediate(value_of<string_tag>::from(subject), accept) : next();
|
|
202
|
-
},
|
|
203
|
-
[ & ](bigint_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
204
|
-
return fast_is_bigint(subject) ? immediate(value_of<bigint_tag>::from(subject), accept) : next();
|
|
205
|
-
},
|
|
206
|
-
[ & ](date_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
207
|
-
return napi::invoke(napi_is_date, napi_env{*this}, subject) ? immediate(value_of<date_tag>::from(subject), accept) : next();
|
|
208
|
-
},
|
|
209
|
-
[ & ](list_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
210
|
-
return fast_is_array(subject) ? immediate(value_of<list_tag>::from(subject), accept) : next();
|
|
211
|
-
},
|
|
212
|
-
[ & ](object_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
213
|
-
// nb: You can't really skip the subsequent is promise, is date, is arraybuffer, etc
|
|
214
|
-
// checks. We don't really want to accept those types here, I don't think..
|
|
215
|
-
return fast_is_object(subject) ? immediate(value_of<object_tag>::from(subject), accept) : next();
|
|
216
|
-
},
|
|
217
|
-
[ & ](function_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
218
|
-
return fast_is_function(subject) ? immediate(value_of<function_tag>::from(subject), accept) : next();
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
// Skip these, otherwise `number_tag` and `string_tag` are invoked twice, which we don't
|
|
222
|
-
// differentiate between.
|
|
223
|
-
[]<class Type>(number_tag_of<Type> /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
224
|
-
[]<class Type>(string_tag_of<Type> /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
225
|
-
|
|
226
|
-
// Unknown tag
|
|
227
|
-
[](auto /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
228
|
-
|
|
229
|
-
// Slow path
|
|
230
|
-
slow_path,
|
|
187
|
+
// Universal fast checks
|
|
188
|
+
auto fast_path = util::overloaded{
|
|
189
|
+
[ & ](undefined_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
190
|
+
return fast_is_undefined(napi_env{*this}, subject) ? (*this)(local_of<undefined_tag>::from(subject), accept) : next();
|
|
191
|
+
},
|
|
192
|
+
[ & ](null_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
193
|
+
return fast_is_null(napi_env{*this}, subject) ? (*this)(local_of<null_tag>::from(subject), accept) : next();
|
|
194
|
+
},
|
|
195
|
+
[ & ](boolean_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
196
|
+
if (fast_is_false(napi_env{*this}, subject)) {
|
|
197
|
+
return (*this)(local_of<false_tag>::from(subject), accept);
|
|
198
|
+
} else if (fast_is_true(napi_env{*this}, subject)) {
|
|
199
|
+
return (*this)(local_of<true_tag>::from(subject), accept);
|
|
200
|
+
} else {
|
|
201
|
+
return next();
|
|
231
202
|
}
|
|
232
|
-
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Extended fast checks
|
|
207
|
+
auto extended_fast_path = util::overloaded{
|
|
208
|
+
[ & ](number_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
209
|
+
return fast_is_number(subject) ? (*this)(local_of<number_tag>::from(subject), accept) : next();
|
|
210
|
+
},
|
|
211
|
+
[ & ](string_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
212
|
+
return fast_is_string(subject) ? immediate(local_of<string_tag>::from(subject), accept) : next();
|
|
213
|
+
},
|
|
214
|
+
[ & ](bigint_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
215
|
+
return fast_is_bigint(subject) ? immediate(local_of<bigint_tag>::from(subject), accept) : next();
|
|
216
|
+
},
|
|
217
|
+
[ & ](date_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
218
|
+
return napi::invoke(napi_is_date, napi_env{*this}, subject) ? immediate(local_of<date_tag>::from(subject), accept) : next();
|
|
219
|
+
},
|
|
220
|
+
[ & ](list_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
221
|
+
return fast_is_array(subject) ? immediate(local_of<list_tag>::from(subject), accept) : next();
|
|
222
|
+
},
|
|
223
|
+
[ & ](object_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
224
|
+
// nb: You can't really skip the subsequent is promise, is date, is arraybuffer, etc
|
|
225
|
+
// checks. We don't really want to accept those types here, I don't think..
|
|
226
|
+
return fast_is_object(subject) ? immediate(local_of<object_tag>::from(subject), accept) : next();
|
|
227
|
+
},
|
|
228
|
+
[ & ](function_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
229
|
+
return fast_is_function(subject) ? immediate(local_of<function_tag>::from(subject), accept) : next();
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
// Skip these, otherwise `number_tag` and `string_tag` are invoked twice, which we don't
|
|
233
|
+
// differentiate between.
|
|
234
|
+
[]<class Type>(number_tag_of<Type> /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
235
|
+
[]<class Type>(string_tag_of<Type> /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
if (has_extended_fast_is_functions) {
|
|
239
|
+
auto traverse = util::overloaded{fast_path, extended_fast_path, slow_path};
|
|
240
|
+
return util::template_traverse(accept_tags_of_v<Accept>, traverse);
|
|
233
241
|
} else {
|
|
234
|
-
|
|
242
|
+
auto traverse = util::overloaded{fast_path, slow_path};
|
|
243
|
+
return util::template_traverse(accept_tags_of_v<Accept>, traverse);
|
|
235
244
|
}
|
|
236
245
|
});
|
|
237
246
|
}
|
|
238
247
|
|
|
239
248
|
template <class Accept>
|
|
240
|
-
auto operator()(
|
|
249
|
+
auto operator()(local_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
241
250
|
return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
|
|
242
251
|
return util::template_traverse(
|
|
243
252
|
accept_tags_of_v<Accept>,
|
|
@@ -265,79 +274,79 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
|
|
|
265
274
|
// I think this only applies to `symbol_tag`
|
|
266
275
|
template <class Accept, class Tag>
|
|
267
276
|
requires std::is_convertible_v<Tag, primitive_tag>
|
|
268
|
-
auto immediate(
|
|
277
|
+
auto immediate(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
269
278
|
return accept_tagged(subject, accept);
|
|
270
279
|
}
|
|
271
280
|
|
|
272
281
|
// strings
|
|
273
282
|
template <class Accept>
|
|
274
|
-
auto immediate(
|
|
275
|
-
if (
|
|
276
|
-
return accept_tagged(
|
|
283
|
+
auto immediate(local_of<string_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
284
|
+
if (maybe_is_string_latin1(subject).value_or(false)) {
|
|
285
|
+
return accept_tagged(local_of<string_tag_of<char>>::from(subject), accept);
|
|
277
286
|
} else {
|
|
278
|
-
return accept_tagged(
|
|
287
|
+
return accept_tagged(local_of<string_tag_of<char16_t>>::from(subject), accept);
|
|
279
288
|
}
|
|
280
289
|
}
|
|
281
290
|
|
|
282
291
|
// bigint
|
|
283
292
|
template <class Accept>
|
|
284
|
-
auto immediate(
|
|
285
|
-
return accept_tagged(
|
|
293
|
+
auto immediate(local_of<bigint_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
294
|
+
return accept_tagged(local_of<bigint_tag_of<bigint>>::from(subject), accept);
|
|
286
295
|
}
|
|
287
296
|
|
|
288
297
|
// date
|
|
289
298
|
template <class Accept>
|
|
290
|
-
auto immediate(
|
|
299
|
+
auto immediate(local_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
291
300
|
if (napi::invoke(napi_is_array, napi_env{*this}, subject)) {
|
|
292
|
-
return immediate(
|
|
301
|
+
return immediate(local_of<list_tag>::from(subject), accept);
|
|
293
302
|
} else if (napi::invoke(napi_is_date, napi_env{*this}, subject)) {
|
|
294
|
-
return immediate(
|
|
303
|
+
return immediate(local_of<date_tag>::from(subject), accept);
|
|
295
304
|
} else if (napi::invoke(napi_is_typedarray, napi_env{*this}, subject)) {
|
|
296
|
-
return immediate(
|
|
305
|
+
return immediate(local_of<typed_array_tag>::from(subject), accept);
|
|
297
306
|
} else if (napi::invoke(napi_is_dataview, napi_env{*this}, subject)) {
|
|
298
|
-
return immediate(
|
|
307
|
+
return immediate(local_of<data_view_tag>::from(subject), accept);
|
|
299
308
|
} else if (maybe_is_shared_array_buffer(env_.get(), subject).value_or(false)) {
|
|
300
|
-
return immediate(
|
|
301
|
-
} else if (
|
|
302
|
-
return immediate(
|
|
309
|
+
return immediate(local_of<shared_array_buffer_tag>::from(subject), accept);
|
|
310
|
+
} else if (is_object_array_buffer(env_.get(), subject)) {
|
|
311
|
+
return immediate(local_of<array_buffer_tag>::from(subject), accept);
|
|
303
312
|
} else if (napi::invoke(napi_is_promise, napi_env{*this}, subject)) {
|
|
304
|
-
return immediate(
|
|
313
|
+
return immediate(local_of<promise_tag>::from(subject), accept);
|
|
305
314
|
} else {
|
|
306
|
-
return immediate(
|
|
315
|
+
return immediate(local_of<dictionary_tag>::from(subject), accept);
|
|
307
316
|
}
|
|
308
317
|
}
|
|
309
318
|
|
|
310
319
|
// date
|
|
311
320
|
template <class Accept>
|
|
312
|
-
auto immediate(
|
|
321
|
+
auto immediate(local_of<date_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
313
322
|
return accept_tagged(subject, accept);
|
|
314
323
|
}
|
|
315
324
|
|
|
316
325
|
// data blocks
|
|
317
326
|
template <class Accept>
|
|
318
|
-
auto immediate(
|
|
319
|
-
if (
|
|
320
|
-
return immediate(
|
|
327
|
+
auto immediate(local_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
328
|
+
if (is_data_block_array_buffer(env_.get(), subject)) {
|
|
329
|
+
return immediate(local_of<array_buffer_tag>::from(subject), accept);
|
|
321
330
|
} else {
|
|
322
|
-
return immediate(
|
|
331
|
+
return immediate(local_of<shared_array_buffer_tag>::from(subject), accept);
|
|
323
332
|
}
|
|
324
333
|
}
|
|
325
334
|
|
|
326
335
|
template <class Accept, class Tag>
|
|
327
336
|
requires std::is_convertible_v<Tag, data_block_tag>
|
|
328
|
-
auto immediate(
|
|
337
|
+
auto immediate(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
329
338
|
return accept_tagged(subject, accept);
|
|
330
339
|
}
|
|
331
340
|
|
|
332
341
|
// array buffer views
|
|
333
342
|
template <class Accept>
|
|
334
|
-
auto immediate(
|
|
335
|
-
auto bound_subject_variant =
|
|
343
|
+
auto immediate(local_of<typed_array_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
344
|
+
auto bound_subject_variant = value_for_typed_array::make_bound(environment(), subject);
|
|
336
345
|
if (bound_subject_variant.index() == std::variant_npos) {
|
|
337
346
|
std::unreachable();
|
|
338
347
|
} else {
|
|
339
348
|
return std::visit(
|
|
340
|
-
[ & ]<class Tag>(
|
|
349
|
+
[ & ]<class Tag>(value_of<Tag> value) -> accept_target_t<Accept> {
|
|
341
350
|
return accept(Tag{}, *this, value);
|
|
342
351
|
},
|
|
343
352
|
bound_subject_variant
|
|
@@ -346,53 +355,87 @@ struct visit_value : reference_map_t<Reference, reference_map_type> {
|
|
|
346
355
|
}
|
|
347
356
|
|
|
348
357
|
template <class Accept>
|
|
349
|
-
auto immediate(
|
|
358
|
+
auto immediate(local_of<data_view_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
350
359
|
return accept_tagged(subject, accept);
|
|
351
360
|
}
|
|
352
361
|
|
|
353
362
|
// externals
|
|
354
363
|
template <class Accept>
|
|
355
|
-
auto immediate(
|
|
364
|
+
auto immediate(local_of<external_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
356
365
|
return accept_tagged(subject, accept);
|
|
357
366
|
}
|
|
358
367
|
|
|
359
368
|
// promise
|
|
360
369
|
template <class Accept>
|
|
361
|
-
auto immediate(
|
|
370
|
+
auto immediate(local_of<promise_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
362
371
|
return accept_tagged(subject, accept);
|
|
363
372
|
}
|
|
364
373
|
|
|
365
374
|
// function
|
|
366
375
|
template <class Accept>
|
|
367
|
-
auto immediate(
|
|
376
|
+
auto immediate(local_of<function_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
368
377
|
return accept_tagged(subject, accept);
|
|
369
378
|
}
|
|
370
379
|
|
|
371
380
|
// array
|
|
372
381
|
template <class Accept>
|
|
373
|
-
auto immediate(
|
|
374
|
-
auto target = napi::
|
|
382
|
+
auto immediate(local_of<list_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
383
|
+
auto target = napi::value_of{napi_env{*this}, local_of<list_tag>::from(subject)};
|
|
375
384
|
auto visit_entry = visit_entry_pair<visit_property_name<visit_value>, visit_value&>{*this};
|
|
376
385
|
return accept(list_tag{}, visit_entry, target);
|
|
377
386
|
}
|
|
378
387
|
|
|
379
388
|
// object / record
|
|
380
389
|
template <class Accept>
|
|
381
|
-
auto immediate(
|
|
382
|
-
auto target = napi::
|
|
390
|
+
auto immediate(local_of<dictionary_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
391
|
+
auto target = napi::value_of{napi_env{*this}, local_of<dictionary_tag>::from(subject)};
|
|
383
392
|
auto visit_entry = visit_entry_pair<visit_property_name<visit_value>, visit_value&>{*this};
|
|
384
393
|
return accept(dictionary_tag{}, visit_entry, target);
|
|
385
394
|
}
|
|
386
395
|
|
|
387
|
-
// Convenience function which wraps in `napi::
|
|
396
|
+
// Convenience function which wraps in `napi::value_of` and invokes `accept`.
|
|
388
397
|
template <class Tag, class Accept>
|
|
389
|
-
[[nodiscard]] auto accept_tagged(
|
|
390
|
-
return accept(Tag{}, *this, napi::
|
|
398
|
+
[[nodiscard]] auto accept_tagged(local_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
399
|
+
return accept(Tag{}, *this, napi::value_of{environment(), subject});
|
|
391
400
|
}
|
|
392
401
|
|
|
393
402
|
std::reference_wrapper<Environment> env_;
|
|
394
403
|
};
|
|
395
404
|
|
|
405
|
+
// Forward `value_of<T>` back to acceptor
|
|
406
|
+
template <class Meta, class Tag>
|
|
407
|
+
struct visit_napi_value_of {
|
|
408
|
+
private:
|
|
409
|
+
using visit_type = visit_value_with<Meta>;
|
|
410
|
+
|
|
411
|
+
public:
|
|
412
|
+
constexpr explicit visit_napi_value_of(auto* transfer, auto& environment) : visit_{transfer, environment} {}
|
|
413
|
+
|
|
414
|
+
template <class Accept>
|
|
415
|
+
constexpr auto operator()(value_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
416
|
+
return accept(Tag{}, visit_, subject);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
template <class Accept>
|
|
420
|
+
requires std::is_same_v<Tag, object_tag>
|
|
421
|
+
constexpr auto operator()(value_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
422
|
+
auto visit_entry = visit_entry_pair<visit_property_name<visit_type>, visit_type&>{visit_};
|
|
423
|
+
return accept(object_tag{}, visit_entry, subject);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
template <class Accept>
|
|
427
|
+
requires std::is_same_v<Tag, list_tag>
|
|
428
|
+
constexpr auto operator()(value_of<list_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
429
|
+
auto visit_entry = visit_entry_pair<visit_property_name<visit_type>, visit_type&>{visit_};
|
|
430
|
+
return accept(list_tag{}, visit_entry, subject);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
consteval static auto types(auto /*recursive*/) { return util::type_pack{}; }
|
|
434
|
+
|
|
435
|
+
private:
|
|
436
|
+
visit_type visit_;
|
|
437
|
+
};
|
|
438
|
+
|
|
396
439
|
} // namespace js::napi
|
|
397
440
|
|
|
398
441
|
namespace js {
|
|
@@ -404,10 +447,19 @@ struct visit<Meta, napi_value> : napi::visit_value_with<Meta> {
|
|
|
404
447
|
};
|
|
405
448
|
|
|
406
449
|
template <class Meta, class Tag>
|
|
407
|
-
struct visit<Meta, napi::
|
|
450
|
+
struct visit<Meta, napi::local_of<Tag>> : napi::visit_value_with<Meta> {
|
|
408
451
|
using napi::visit_value_with<Meta>::visit_value_with;
|
|
409
452
|
};
|
|
410
453
|
|
|
454
|
+
// Pass through `value_of<Tag>`
|
|
455
|
+
template <class Meta, class Tag>
|
|
456
|
+
struct visit<Meta, napi::value_of<Tag>> : napi::visit_napi_value_of<Meta, Tag> {
|
|
457
|
+
using napi::visit_napi_value_of<Meta, Tag>::visit_napi_value_of;
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
template <class Tag>
|
|
461
|
+
struct visit_subject_for<napi::value_of<Tag>> : std::type_identity<napi_value> {};
|
|
462
|
+
|
|
411
463
|
// Object key maker via napi
|
|
412
464
|
template <auto Key>
|
|
413
465
|
struct visit_key_literal<Key, napi_value> : napi::visit_napi_key_literal<Key> {
|
package/value/array.cc
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
module napi_js;
|
|
2
|
-
import :api;
|
|
3
|
-
import :bound_value;
|
|
4
2
|
|
|
5
3
|
namespace js::napi {
|
|
6
4
|
|
|
7
|
-
auto
|
|
5
|
+
auto value_for_vector::begin() const -> iterator {
|
|
8
6
|
return {*this, 0};
|
|
9
7
|
}
|
|
10
8
|
|
|
11
|
-
auto
|
|
9
|
+
auto value_for_vector::end() const -> iterator {
|
|
12
10
|
return {*this, size()};
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
auto
|
|
13
|
+
auto value_for_vector::size() const -> std::uint32_t {
|
|
16
14
|
if (size_ == 0) {
|
|
17
15
|
size_ = napi::invoke(napi_get_array_length, env(), napi_value{*this}) + 1;
|
|
18
16
|
}
|
|
19
17
|
return size_ - 1;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
value_for_vector::iterator::iterator(value_for_vector subject, size_type index) :
|
|
23
21
|
subject_{subject},
|
|
24
22
|
index_{index} {}
|
|
25
23
|
|
|
26
|
-
auto
|
|
24
|
+
auto value_for_vector::iterator::operator*() const -> value_type {
|
|
27
25
|
return value_type::from(napi::invoke(napi_get_element, subject_.env(), napi_value{subject_}, index_));
|
|
28
26
|
}
|
|
29
27
|
|
package/value/array.h.cc
CHANGED
|
@@ -5,11 +5,11 @@ import util;
|
|
|
5
5
|
|
|
6
6
|
namespace js::napi {
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class value_for_vector : public value_next<vector_tag> {
|
|
9
9
|
public:
|
|
10
10
|
class iterator;
|
|
11
|
-
using
|
|
12
|
-
using value_type =
|
|
11
|
+
using value_next<vector_tag>::value_next;
|
|
12
|
+
using value_type = local_of<value_tag>;
|
|
13
13
|
|
|
14
14
|
[[nodiscard]] auto begin() const -> iterator;
|
|
15
15
|
[[nodiscard]] auto end() const -> iterator;
|
|
@@ -19,15 +19,15 @@ class bound_value_for_vector : public bound_value_next<vector_tag> {
|
|
|
19
19
|
mutable std::uint32_t size_{};
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
class
|
|
22
|
+
class value_for_vector::iterator : public util::random_access_iterator_facade<std::int32_t, std::int64_t> {
|
|
23
23
|
public:
|
|
24
24
|
using arithmetic_facade::operator+;
|
|
25
25
|
using difference_type = arithmetic_facade::difference_type;
|
|
26
26
|
using size_type = std::uint32_t;
|
|
27
|
-
using value_type =
|
|
27
|
+
using value_type = value_for_vector::value_type;
|
|
28
28
|
|
|
29
29
|
iterator() = default;
|
|
30
|
-
iterator(
|
|
30
|
+
iterator(value_for_vector subject, size_type index);
|
|
31
31
|
|
|
32
32
|
auto operator*() const -> value_type;
|
|
33
33
|
|
|
@@ -42,7 +42,7 @@ class bound_value_for_vector::iterator : public util::random_access_iterator_fac
|
|
|
42
42
|
private:
|
|
43
43
|
auto operator+() const -> size_type { return index_; }
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
value_for_vector subject_;
|
|
46
46
|
size_type index_{};
|
|
47
47
|
};
|
|
48
48
|
|