@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/support/host.cc
CHANGED
|
@@ -6,31 +6,45 @@ namespace js::napi {
|
|
|
6
6
|
util::lockable_with<bool, {.shared = true}> host_environment_initialized;
|
|
7
7
|
|
|
8
8
|
// Addressof operations
|
|
9
|
-
constexpr auto direct_handle_address =
|
|
10
|
-
|
|
9
|
+
constexpr auto direct_handle_address = [](napi_value value) noexcept -> void* { return value; };
|
|
10
|
+
constexpr auto indirect_handle_address = [](napi_value value) noexcept -> void* { return *reinterpret_cast<void**>(value); };
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
// Fast functions which are supported on all platforms
|
|
13
|
+
// nb: Bun exports these v8 functions, but they crash with the `std::bit_cast<v8::Local<T>>` trick.
|
|
14
|
+
auto v8_is_false(napi_env /*env*/, napi_value value) -> bool {
|
|
15
|
+
return std::bit_cast<v8::Local<v8::Value>>(value)->IsFalse();
|
|
16
|
+
}
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
auto v8_is_null(napi_env /*env*/, napi_value value) -> bool {
|
|
19
|
+
return std::bit_cast<v8::Local<v8::Value>>(value)->IsNull();
|
|
20
|
+
}
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
auto v8_is_true(napi_env /*env*/, napi_value value) -> bool {
|
|
23
|
+
return std::bit_cast<v8::Local<v8::Value>>(value)->IsTrue();
|
|
24
|
+
}
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
auto v8_is_undefined(napi_env /*env*/, napi_value value) -> bool {
|
|
27
|
+
return std::bit_cast<v8::Local<v8::Value>>(value)->IsUndefined();
|
|
28
|
+
}
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
auto napi_fast_is_false(napi_env env, napi_value value) -> bool {
|
|
31
|
+
return value == napi::invoke(napi_get_boolean, env, false);
|
|
32
|
+
}
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
auto napi_fast_is_null(napi_env env, napi_value value) -> bool {
|
|
35
|
+
return value == napi::invoke(napi_get_null, env);
|
|
36
|
+
}
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
auto napi_fast_is_true(napi_env env, napi_value value) -> bool {
|
|
39
|
+
return value == napi::invoke(napi_get_boolean, env, true);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
auto napi_fast_is_undefined(napi_env env, napi_value value) -> bool {
|
|
43
|
+
return value == napi::invoke(napi_get_undefined, env);
|
|
44
|
+
}
|
|
33
45
|
|
|
46
|
+
// Extended fast functions
|
|
47
|
+
// nb: Bun exports these v8 functions, but they crash with the `std::bit_cast<v8::Local<T>>` trick.
|
|
34
48
|
auto fast_is_array(napi_value value) -> bool {
|
|
35
49
|
return std::bit_cast<v8::Local<v8::Value>>(value)->IsArray();
|
|
36
50
|
}
|
|
@@ -39,18 +53,10 @@ auto fast_is_bigint(napi_value value) -> bool {
|
|
|
39
53
|
return std::bit_cast<v8::Local<v8::Value>>(value)->IsBigInt();
|
|
40
54
|
}
|
|
41
55
|
|
|
42
|
-
auto fast_is_boolean(napi_value value) -> bool {
|
|
43
|
-
return std::bit_cast<v8::Local<v8::Value>>(value)->IsBoolean();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
56
|
auto fast_is_function(napi_value value) -> bool {
|
|
47
57
|
return std::bit_cast<v8::Local<v8::Value>>(value)->IsFunction();
|
|
48
58
|
}
|
|
49
59
|
|
|
50
|
-
auto fast_is_null(napi_value value) -> bool {
|
|
51
|
-
return std::bit_cast<v8::Local<v8::Value>>(value)->IsNull();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
60
|
auto fast_is_number(napi_value value) -> bool {
|
|
55
61
|
return std::bit_cast<v8::Local<v8::Value>>(value)->IsNumber();
|
|
56
62
|
}
|
|
@@ -63,13 +69,60 @@ auto fast_is_string(napi_value value) -> bool {
|
|
|
63
69
|
return std::bit_cast<v8::Local<v8::Value>>(value)->IsString();
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
// Bug fixes
|
|
73
|
+
auto napi_is_object_array_buffer(napi_env env, local_of<object_tag> value) -> bool {
|
|
74
|
+
return napi::invoke(napi_is_arraybuffer, env, value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
auto napi_is_data_block_array_buffer(napi_env env, local_of<data_block_tag> value) -> bool {
|
|
78
|
+
return napi_is_object_array_buffer(env, value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
auto bun_is_data_block_array_buffer(napi_env env, local_of<data_block_tag> value) -> bool {
|
|
82
|
+
// https://github.com/oven-sh/bun/issues/32624
|
|
83
|
+
auto* string = napi::invoke(napi_coerce_to_string, env, value);
|
|
84
|
+
auto length = napi::invoke(napi_get_value_string_latin1, env, string, nullptr, 0);
|
|
85
|
+
// '[object ArrayBuffer]'
|
|
86
|
+
return length == 20;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
auto bun_is_object_array_buffer(napi_env env, local_of<object_tag> value) -> bool {
|
|
90
|
+
if (napi::invoke(napi_is_arraybuffer, env, value)) {
|
|
91
|
+
return bun_is_data_block_array_buffer(env, local_of<data_block_tag>::from(value));
|
|
92
|
+
} else {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
68
95
|
}
|
|
69
96
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
97
|
+
// Optional value inspectors.
|
|
98
|
+
auto v8_is_number_int32(local_of<number_tag> value) -> std::optional<bool> {
|
|
99
|
+
return std::bit_cast<v8::Local<v8::Number>>(value)->IsInt32();
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
auto v8_is_string_one_byte(local_of<string_tag> value) -> std::optional<bool> {
|
|
103
|
+
return std::bit_cast<v8::Local<v8::String>>(value)->IsOneByte();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
auto node_api_maybe_is_shared_array_buffer(napi_env env, local_of<object_tag> value) -> std::optional<bool> {
|
|
107
|
+
if constexpr (node_api_has_sharedarraybuffer) {
|
|
108
|
+
return napi::invoke(node_api_is_sharedarraybuffer, env, value);
|
|
109
|
+
} else {
|
|
110
|
+
return std::nullopt;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
auto bun_maybe_is_shared_array_buffer(napi_env env, local_of<object_tag> value) -> std::optional<bool> {
|
|
115
|
+
if (napi::invoke(napi_is_arraybuffer, env, value)) {
|
|
116
|
+
return !bun_is_data_block_array_buffer(env, local_of<data_block_tag>::from(value));
|
|
117
|
+
} else {
|
|
118
|
+
return std::nullopt;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
constexpr auto unknown_maybe_is = [](auto...) -> std::optional<bool> { return std::nullopt; };
|
|
123
|
+
|
|
124
|
+
// 'SharedArrayBuffer' functions
|
|
125
|
+
auto v8_make_shared_array_buffer(js::shared_array_buffer::shared_pointer_type data, std::size_t byte_length) -> local_of<shared_array_buffer_tag> {
|
|
73
126
|
auto backing_store = [ & ]() -> auto {
|
|
74
127
|
// v8 does not call the deleter `byte_length` is zero. So the heap-allocated shared_ptr trick
|
|
75
128
|
// does not work in that case.
|
|
@@ -90,34 +143,31 @@ constexpr auto v8_make_shared_array_buffer =
|
|
|
90
143
|
}
|
|
91
144
|
}();
|
|
92
145
|
auto shared_array_buffer = v8::SharedArrayBuffer::New(v8::Isolate::GetCurrent(), std::move(backing_store));
|
|
93
|
-
return
|
|
146
|
+
return local_of<shared_array_buffer_tag>::from(std::bit_cast<napi_value>(shared_array_buffer));
|
|
94
147
|
};
|
|
95
148
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
149
|
+
auto v8_shared_array_buffer_get_byte_length(local_of<shared_array_buffer_tag> buffer) -> std::size_t {
|
|
150
|
+
return std::bit_cast<v8::Local<v8::SharedArrayBuffer>>(napi_value{buffer})->ByteLength();
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
auto v8_shared_array_buffer_get_backing_store(local_of<shared_array_buffer_tag> buffer) -> std::shared_ptr<std::byte[]> {
|
|
154
|
+
auto backing_store = std::bit_cast<v8::Local<v8::SharedArrayBuffer>>(buffer)->GetBackingStore();
|
|
155
|
+
auto* data = reinterpret_cast<std::byte*>(backing_store->Data());
|
|
156
|
+
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
157
|
+
return std::shared_ptr<std::byte[]>{std::move(backing_store), data};
|
|
100
158
|
};
|
|
101
159
|
|
|
102
160
|
// 'ArrayBufferView' constructors
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
[](value_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<data_view_tag> {
|
|
161
|
+
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
|
|
162
|
+
auto v8_make_sab_data_view(local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> {
|
|
106
163
|
auto buffer_local = std::bit_cast<v8::Local<v8::SharedArrayBuffer>>(napi_value{buffer});
|
|
107
164
|
auto view_local = v8::DataView::New(buffer_local, byte_offset, length);
|
|
108
|
-
return
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
constexpr auto unknown_make_sab_data_view =
|
|
112
|
-
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
|
|
113
|
-
[](value_of<shared_array_buffer_tag> /*buffer*/, std::size_t /*byte_offset*/, std::size_t /*length*/) -> value_of<data_view_tag> {
|
|
114
|
-
throw js::type_error{u"SharedArrayBuffer is not supported in this environment"};
|
|
165
|
+
return local_of<data_view_tag>::from(std::bit_cast<napi_value>(view_local));
|
|
115
166
|
};
|
|
116
167
|
|
|
117
168
|
template <class Type>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
[](value_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> value_of<typed_array_tag_of<Type>> {
|
|
169
|
+
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
|
|
170
|
+
auto v8_make_sab_typed_array_of(local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag_of<Type>> {
|
|
121
171
|
using constructor_type = type_t<util::overloaded{
|
|
122
172
|
[](std::type_identity<double>) -> std::type_identity<v8::Float64Array> { return {}; },
|
|
123
173
|
[](std::type_identity<float>) -> std::type_identity<v8::Float32Array> { return {}; },
|
|
@@ -134,16 +184,30 @@ constexpr auto v8_make_sab_typed_array_of =
|
|
|
134
184
|
}(type<Type>)>;
|
|
135
185
|
auto buffer_local = std::bit_cast<v8::Local<v8::SharedArrayBuffer>>(napi_value{buffer});
|
|
136
186
|
auto view_local = constructor_type::New(buffer_local, byte_offset, length);
|
|
137
|
-
return
|
|
187
|
+
return local_of<typed_array_tag_of<Type>>::from(std::bit_cast<napi_value>(view_local));
|
|
138
188
|
};
|
|
139
189
|
|
|
140
190
|
template <class Type>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
[](value_of<shared_array_buffer_tag> /*buffer*/, std::size_t /*byte_offset*/, std::size_t /*length*/) -> value_of<typed_array_tag_of<Type>> {
|
|
191
|
+
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
|
192
|
+
constexpr auto unknown_sab_throw = [](auto...) -> Type {
|
|
144
193
|
throw js::type_error{u"SharedArrayBuffer is not supported in this environment"};
|
|
145
194
|
};
|
|
146
195
|
|
|
196
|
+
// Dynamic libraries
|
|
197
|
+
constexpr auto node_uv_dlerror =
|
|
198
|
+
[](const uv_lib_t* lib) -> const char* { return uv_dlerror(lib); };
|
|
199
|
+
constexpr auto node_uv_dlopen =
|
|
200
|
+
[](const char* filename, uv_lib_t* lib) -> int { return uv_dlopen(filename, lib); };
|
|
201
|
+
constexpr auto node_uv_dlclose =
|
|
202
|
+
[](uv_lib_t* lib) -> void { uv_dlclose(lib); };
|
|
203
|
+
|
|
204
|
+
constexpr auto unknown_uv_dlerror =
|
|
205
|
+
[](const uv_lib_t* /*lib*/) -> const char* { return "Dynamic libraries are not supported in this environment"; };
|
|
206
|
+
constexpr auto unknown_uv_dlopen =
|
|
207
|
+
[](const char* /*filename*/, uv_lib_t* /*lib*/) -> int { return -1; };
|
|
208
|
+
constexpr auto unknown_uv_dlclose =
|
|
209
|
+
[](uv_lib_t* /*lib*/) -> void { std::unreachable(); };
|
|
210
|
+
|
|
147
211
|
auto initialize_host_environment(napi_env env) -> void {
|
|
148
212
|
if (!*host_environment_initialized.read()) {
|
|
149
213
|
if (auto lock = host_environment_initialized.write(); !*lock) {
|
|
@@ -168,44 +232,53 @@ auto initialize_host_environment(napi_env env) -> void {
|
|
|
168
232
|
handle_addressof = indirect_handle_address;
|
|
169
233
|
}
|
|
170
234
|
|
|
171
|
-
//
|
|
172
|
-
auto
|
|
235
|
+
// Get `globalThis.process`
|
|
236
|
+
auto* process_global = [ & ]() -> napi_value {
|
|
173
237
|
auto* global = napi::invoke(napi_get_global, env);
|
|
174
238
|
constexpr auto process_cw = util::make_consteval_string_view(util::cw<"process">);
|
|
175
239
|
auto* process_str = napi::invoke(node_api_create_property_key_latin1, env, process_cw.data(), process_cw.length());
|
|
176
240
|
auto* process = napi::invoke(napi_get_property, env, global, process_str);
|
|
177
241
|
if (napi::invoke(napi_typeof, env, process) == napi_object) {
|
|
178
|
-
|
|
179
|
-
auto* is_bun_str = napi::invoke(node_api_create_property_key_latin1, env, is_bun_cw.data(), is_bun_cw.length());
|
|
180
|
-
auto* is_bun = napi::invoke(napi_get_property, env, process, is_bun_str);
|
|
181
|
-
auto* is_bun_bool = napi::invoke(napi_coerce_to_bool, env, is_bun);
|
|
182
|
-
return napi::invoke(napi_get_value_bool, env, is_bun_bool);
|
|
242
|
+
return process;
|
|
183
243
|
} else {
|
|
244
|
+
return nullptr;
|
|
245
|
+
}
|
|
246
|
+
}();
|
|
247
|
+
|
|
248
|
+
// Detect bun via `process.isBun`
|
|
249
|
+
auto is_bun = process_global == nullptr ? false : [ & ]() -> bool {
|
|
250
|
+
constexpr auto is_bun_cw = util::make_consteval_string_view(util::cw<"isBun">);
|
|
251
|
+
auto* is_bun_str = napi::invoke(node_api_create_property_key_latin1, env, is_bun_cw.data(), is_bun_cw.length());
|
|
252
|
+
auto* is_bun = napi::invoke(napi_get_property, env, process_global, is_bun_str);
|
|
253
|
+
auto* is_bun_bool = napi::invoke(napi_coerce_to_bool, env, is_bun);
|
|
254
|
+
return napi::invoke(napi_get_value_bool, env, is_bun_bool);
|
|
255
|
+
}();
|
|
256
|
+
|
|
257
|
+
// Detect deno via `process.versions.deno`
|
|
258
|
+
auto is_deno = process_global == nullptr ? false : [ & ]() -> bool {
|
|
259
|
+
constexpr auto versions_cw = util::make_consteval_string_view(util::cw<"versions">);
|
|
260
|
+
auto* versions_str = napi::invoke(node_api_create_property_key_latin1, env, versions_cw.data(), versions_cw.length());
|
|
261
|
+
auto* versions = napi::invoke(napi_get_property, env, process_global, versions_str);
|
|
262
|
+
if (napi::invoke(napi_typeof, env, versions) != napi_object) {
|
|
184
263
|
return false;
|
|
185
264
|
}
|
|
265
|
+
constexpr auto deno_cw = util::make_consteval_string_view(util::cw<"deno">);
|
|
266
|
+
auto* deno_str = napi::invoke(node_api_create_property_key_latin1, env, deno_cw.data(), deno_cw.length());
|
|
267
|
+
auto* deno = napi::invoke(napi_get_property, env, versions, deno_str);
|
|
268
|
+
auto* deno_bool = napi::invoke(napi_coerce_to_bool, env, deno);
|
|
269
|
+
return napi::invoke(napi_get_value_bool, env, deno_bool);
|
|
186
270
|
}();
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
make_sab_typed_array_of<std::uint16_t> = unknown_make_sab_typed_array_of<std::uint16_t>;
|
|
199
|
-
make_sab_typed_array_of<std::uint32_t> = unknown_make_sab_typed_array_of<std::uint32_t>;
|
|
200
|
-
make_sab_typed_array_of<std::uint64_t> = unknown_make_sab_typed_array_of<std::uint64_t>;
|
|
201
|
-
make_sab_typed_array_of<std::uint8_t> = unknown_make_sab_typed_array_of<std::uint8_t>;
|
|
202
|
-
make_shared_array_buffer = unknown_make_shared_array_buffer;
|
|
203
|
-
maybe_fast_is_number_int32 = unknown_maybe_fast_is_number_int32;
|
|
204
|
-
maybe_fast_is_string_one_byte = unknown_maybe_fast_is_string_one_byte;
|
|
205
|
-
maybe_is_shared_array_buffer = unknown_maybe_is_shared_array_buffer;
|
|
206
|
-
} else {
|
|
207
|
-
has_fast_is_functions = true;
|
|
208
|
-
make_sab_data_view = v8_make_sab_data_view;
|
|
271
|
+
|
|
272
|
+
auto is_nodejs = !is_bun && !is_deno;
|
|
273
|
+
if (is_nodejs) {
|
|
274
|
+
has_extended_fast_is_functions = true;
|
|
275
|
+
fast_is_false = v8_is_false;
|
|
276
|
+
fast_is_null = v8_is_null;
|
|
277
|
+
fast_is_true = v8_is_true;
|
|
278
|
+
fast_is_undefined = v8_is_undefined;
|
|
279
|
+
host_uv_dlclose = node_uv_dlclose;
|
|
280
|
+
host_uv_dlerror = node_uv_dlerror;
|
|
281
|
+
host_uv_dlopen = node_uv_dlopen;
|
|
209
282
|
make_sab_typed_array_of<double> = v8_make_sab_typed_array_of<double>;
|
|
210
283
|
make_sab_typed_array_of<float> = v8_make_sab_typed_array_of<float>;
|
|
211
284
|
make_sab_typed_array_of<js::float16_t> = v8_make_sab_typed_array_of<js::float16_t>;
|
|
@@ -219,9 +292,49 @@ auto initialize_host_environment(napi_env env) -> void {
|
|
|
219
292
|
make_sab_typed_array_of<std::uint64_t> = v8_make_sab_typed_array_of<std::uint64_t>;
|
|
220
293
|
make_sab_typed_array_of<std::uint8_t> = v8_make_sab_typed_array_of<std::uint8_t>;
|
|
221
294
|
make_shared_array_buffer = v8_make_shared_array_buffer;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
295
|
+
maybe_is_number_int32 = v8_is_number_int32;
|
|
296
|
+
maybe_is_shared_array_buffer = node_api_maybe_is_shared_array_buffer;
|
|
297
|
+
maybe_is_string_latin1 = v8_is_string_one_byte;
|
|
298
|
+
shared_array_buffer_get_backing_store = v8_shared_array_buffer_get_backing_store;
|
|
299
|
+
shared_array_buffer_get_byte_length = v8_shared_array_buffer_get_byte_length;
|
|
300
|
+
} else {
|
|
301
|
+
has_extended_fast_is_functions = false;
|
|
302
|
+
fast_is_false = napi_fast_is_false;
|
|
303
|
+
fast_is_null = napi_fast_is_null;
|
|
304
|
+
fast_is_true = napi_fast_is_true;
|
|
305
|
+
fast_is_undefined = napi_fast_is_undefined;
|
|
306
|
+
host_uv_dlclose = unknown_uv_dlclose;
|
|
307
|
+
host_uv_dlerror = unknown_uv_dlerror;
|
|
308
|
+
host_uv_dlopen = unknown_uv_dlopen;
|
|
309
|
+
make_sab_data_view = unknown_sab_throw<local_of<data_view_tag>>;
|
|
310
|
+
make_sab_typed_array_of<double> = unknown_sab_throw<local_of<typed_array_tag_of<double>>>;
|
|
311
|
+
make_sab_typed_array_of<float> = unknown_sab_throw<local_of<typed_array_tag_of<float>>>;
|
|
312
|
+
make_sab_typed_array_of<js::float16_t> = unknown_sab_throw<local_of<typed_array_tag_of<js::float16_t>>>;
|
|
313
|
+
make_sab_typed_array_of<js::uint8_clamped_t> = unknown_sab_throw<local_of<typed_array_tag_of<js::uint8_clamped_t>>>;
|
|
314
|
+
make_sab_typed_array_of<std::int16_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::int16_t>>>;
|
|
315
|
+
make_sab_typed_array_of<std::int32_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::int32_t>>>;
|
|
316
|
+
make_sab_typed_array_of<std::int64_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::int64_t>>>;
|
|
317
|
+
make_sab_typed_array_of<std::int8_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::int8_t>>>;
|
|
318
|
+
make_sab_typed_array_of<std::uint16_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::uint16_t>>>;
|
|
319
|
+
make_sab_typed_array_of<std::uint32_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::uint32_t>>>;
|
|
320
|
+
make_sab_typed_array_of<std::uint64_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::uint64_t>>>;
|
|
321
|
+
make_sab_typed_array_of<std::uint8_t> = unknown_sab_throw<local_of<typed_array_tag_of<std::uint8_t>>>;
|
|
322
|
+
make_shared_array_buffer = unknown_sab_throw<local_of<shared_array_buffer_tag>>;
|
|
323
|
+
maybe_is_number_int32 = unknown_maybe_is;
|
|
324
|
+
maybe_is_shared_array_buffer = unknown_maybe_is;
|
|
325
|
+
maybe_is_string_latin1 = unknown_maybe_is;
|
|
326
|
+
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
327
|
+
shared_array_buffer_get_backing_store = unknown_sab_throw<std::shared_ptr<std::byte[]>>;
|
|
328
|
+
shared_array_buffer_get_byte_length = unknown_sab_throw<std::size_t>;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Bug fixes
|
|
332
|
+
is_data_block_array_buffer = napi_is_data_block_array_buffer;
|
|
333
|
+
is_object_array_buffer = napi_is_object_array_buffer;
|
|
334
|
+
if (is_bun) {
|
|
335
|
+
is_data_block_array_buffer = bun_is_data_block_array_buffer;
|
|
336
|
+
is_object_array_buffer = bun_is_object_array_buffer;
|
|
337
|
+
maybe_is_shared_array_buffer = bun_maybe_is_shared_array_buffer;
|
|
225
338
|
}
|
|
226
339
|
}
|
|
227
340
|
}
|
package/support/host.h.cc
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export module napi_js:support.host;
|
|
2
|
-
import :
|
|
2
|
+
import :handle.local_of;
|
|
3
3
|
import std;
|
|
4
4
|
|
|
5
5
|
namespace js::napi {
|
|
@@ -7,32 +7,43 @@ namespace js::napi {
|
|
|
7
7
|
// Addressof operation
|
|
8
8
|
auto (*handle_addressof)(napi_value handle) noexcept -> void* = nullptr;
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
auto (*
|
|
12
|
-
auto (*
|
|
13
|
-
auto (*
|
|
10
|
+
// Fast functions which are supported on all platforms
|
|
11
|
+
auto (*fast_is_false)(napi_env env, napi_value value) -> bool;
|
|
12
|
+
auto (*fast_is_null)(napi_env env, napi_value value) -> bool;
|
|
13
|
+
auto (*fast_is_true)(napi_env env, napi_value value) -> bool;
|
|
14
|
+
auto (*fast_is_undefined)(napi_env env, napi_value value) -> bool;
|
|
14
15
|
|
|
15
|
-
//
|
|
16
|
-
auto
|
|
16
|
+
// Extended fast functions
|
|
17
|
+
auto has_extended_fast_is_functions = false;
|
|
17
18
|
auto fast_is_array(napi_value value) -> bool;
|
|
18
19
|
auto fast_is_bigint(napi_value value) -> bool;
|
|
19
|
-
auto fast_is_boolean(napi_value value) -> bool;
|
|
20
20
|
auto fast_is_function(napi_value value) -> bool;
|
|
21
|
-
auto fast_is_null(napi_value value) -> bool;
|
|
22
21
|
auto fast_is_number(napi_value value) -> bool;
|
|
23
22
|
auto fast_is_object(napi_value value) -> bool;
|
|
24
23
|
auto fast_is_string(napi_value value) -> bool;
|
|
25
|
-
auto fast_is_undefined(napi_value value) -> bool;
|
|
26
24
|
|
|
27
|
-
//
|
|
28
|
-
auto (*
|
|
25
|
+
// Bug fixes
|
|
26
|
+
auto (*is_object_array_buffer)(napi_env env, local_of<object_tag> value) -> bool = nullptr;
|
|
27
|
+
auto (*is_data_block_array_buffer)(napi_env env, local_of<data_block_tag> value) -> bool = nullptr;
|
|
28
|
+
|
|
29
|
+
// Optional value inspectors. int32 & latin1 will select optimized representations, and
|
|
30
|
+
// shared_array_buffer is required for support of that value type.
|
|
31
|
+
auto (*maybe_is_number_int32)(local_of<number_tag> value) -> std::optional<bool> = nullptr;
|
|
32
|
+
auto (*maybe_is_string_latin1)(local_of<string_tag> value) -> std::optional<bool> = nullptr;
|
|
33
|
+
auto (*maybe_is_shared_array_buffer)(napi_env env, local_of<object_tag> value) -> std::optional<bool> = nullptr;
|
|
34
|
+
|
|
35
|
+
// 'SharedArrayBuffer' functions
|
|
36
|
+
auto (*make_shared_array_buffer)(js::shared_array_buffer::shared_pointer_type data, std::size_t byte_length) -> local_of<shared_array_buffer_tag> = nullptr;
|
|
37
|
+
auto (*shared_array_buffer_get_byte_length)(local_of<shared_array_buffer_tag> buffer) -> std::size_t = nullptr;
|
|
38
|
+
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
39
|
+
auto (*shared_array_buffer_get_backing_store)(local_of<shared_array_buffer_tag> buffer) -> std::shared_ptr<std::byte[]> = nullptr;
|
|
29
40
|
|
|
30
41
|
// 'ArrayBufferView' constructors
|
|
31
|
-
auto (*make_sab_data_view)(
|
|
42
|
+
auto (*make_sab_data_view)(local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<data_view_tag> = nullptr;
|
|
32
43
|
|
|
33
44
|
template <class Type>
|
|
34
45
|
using make_sab_typed_array_constructor =
|
|
35
|
-
auto(
|
|
46
|
+
auto(local_of<shared_array_buffer_tag> buffer, std::size_t byte_offset, std::size_t length) -> local_of<typed_array_tag_of<Type>>;
|
|
36
47
|
|
|
37
48
|
template <class Type>
|
|
38
49
|
make_sab_typed_array_constructor<Type>* make_sab_typed_array_of;
|
|
@@ -50,6 +61,11 @@ template make_sab_typed_array_constructor<std::uint32_t>* make_sab_typed_array_o
|
|
|
50
61
|
template make_sab_typed_array_constructor<std::uint64_t>* make_sab_typed_array_of<std::uint64_t>;
|
|
51
62
|
template make_sab_typed_array_constructor<std::uint8_t>* make_sab_typed_array_of<std::uint8_t>;
|
|
52
63
|
|
|
64
|
+
// uv dlfcn wrappers
|
|
65
|
+
auto (*host_uv_dlerror)(const uv_lib_t* lib) -> const char*;
|
|
66
|
+
auto (*host_uv_dlopen)(const char* filename, uv_lib_t* lib) -> int;
|
|
67
|
+
auto (*host_uv_dlclose)(uv_lib_t* lib) -> void;
|
|
68
|
+
|
|
53
69
|
// Once per process, this detects the host environment (nodejs vs bun)
|
|
54
70
|
auto initialize_host_environment(napi_env env) -> void;
|
|
55
71
|
|
package/support/initialize.h.cc
CHANGED
|
@@ -34,8 +34,8 @@ class napi_js_module final : private detail::initialize_require {
|
|
|
34
34
|
const auto [... indices ] = util::sequence<sizeof...(Args)>;
|
|
35
35
|
auto& client_environment = environment::make_and_set_environment<Environment>(env, std::get<indices>(std::move(args_))...);
|
|
36
36
|
// assign export descriptor to napi-constructor namespace object
|
|
37
|
-
auto exports_local =
|
|
38
|
-
exports_local
|
|
37
|
+
auto exports_local = local_of<dictionary_tag>::from(exports);
|
|
38
|
+
exports_local->assign(client_environment, std::move(make_exports_)(client_environment));
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
Make make_exports_;
|
package/support/promise.cc
CHANGED
|
@@ -19,7 +19,7 @@ class resolver {
|
|
|
19
19
|
resolver(resolver&&) = default;
|
|
20
20
|
~resolver() {
|
|
21
21
|
if (scheduler_) {
|
|
22
|
-
resolve(
|
|
22
|
+
resolve(nullptr);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -42,7 +42,8 @@ class resolver {
|
|
|
42
42
|
|
|
43
43
|
// Fulfill using direct resolution value. Note it still needs try/catch (in `fulfill`) because
|
|
44
44
|
// the `transfer` operation could fail.
|
|
45
|
-
|
|
45
|
+
template <class Type>
|
|
46
|
+
auto resolve(Type value) noexcept(std::is_nothrow_move_constructible_v<Type>) -> void {
|
|
46
47
|
using expected_type = std::expected<decltype(value), js::error_value>;
|
|
47
48
|
schedule(
|
|
48
49
|
[](Environment& /*env*/, auto value) -> expected_type {
|
|
@@ -53,7 +54,7 @@ class resolver {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
// Fulfill using thrown error.
|
|
56
|
-
auto reject(js::error_value error) -> void {
|
|
57
|
+
auto reject(js::error_value error) noexcept -> void {
|
|
57
58
|
using expected_type = std::expected<std::monostate, js::error_value>;
|
|
58
59
|
schedule(
|
|
59
60
|
[](Environment& /*env*/, js::error_value error) -> expected_type {
|
|
@@ -64,10 +65,11 @@ class resolver {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
private:
|
|
67
|
-
|
|
68
|
+
template <class Operation, class... Args>
|
|
69
|
+
auto schedule(Operation operation, Args&&... args) noexcept(std::is_nothrow_move_constructible_v<Operation> && (std::is_nothrow_move_constructible_v<Args> && ...)) -> void {
|
|
68
70
|
auto scheduler = std::move(scheduler_);
|
|
69
71
|
scheduler(
|
|
70
|
-
[](napi_env env, napi_value /*nothing*/, napi_deferred deferred, auto operation, auto&&... args) {
|
|
72
|
+
[](napi_env env, napi_value /*nothing*/, napi_deferred deferred, auto operation, auto&&... args) noexcept {
|
|
71
73
|
auto& environment = napi::environment::unsafe_get_environment_as<Environment>(env);
|
|
72
74
|
environment.scheduler().decrement_ref(env);
|
|
73
75
|
try {
|
|
@@ -81,10 +83,10 @@ class resolver {
|
|
|
81
83
|
}
|
|
82
84
|
} catch (const napi::pending_error& /*error*/) {
|
|
83
85
|
auto* exception = napi::invoke(napi_get_and_clear_last_exception, env);
|
|
84
|
-
napi::
|
|
86
|
+
napi::invoke0_noexcept(napi_reject_deferred, env, deferred, exception);
|
|
85
87
|
} catch (const js::error& error) {
|
|
86
88
|
auto exception = js::transfer_in_strict<napi_value>(error, environment);
|
|
87
|
-
napi::
|
|
89
|
+
napi::invoke0_noexcept(napi_reject_deferred, env, deferred, exception);
|
|
88
90
|
}
|
|
89
91
|
},
|
|
90
92
|
deferred_,
|
|
@@ -115,7 +117,7 @@ auto make_promise(Environment& env, auto... dispatch) {
|
|
|
115
117
|
auto resolve = resolver{env, deferred, std::move(dispatch)...};
|
|
116
118
|
|
|
117
119
|
// `[ promise, resolver ]`
|
|
118
|
-
return std::tuple{
|
|
120
|
+
return std::tuple{local_of<promise_tag>::from(promise), std::move(resolve)};
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
} // namespace js::napi
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#define WIN32_LEAN_AND_MEAN
|
|
2
|
+
#include <windows.h>
|
|
3
|
+
#include <delayimp.h>
|
|
4
|
+
import std;
|
|
5
|
+
|
|
6
|
+
const auto __pfnDliNotifyHook2 = PfnDliHook{[](unsigned event, DelayLoadInfo* info) -> FARPROC {
|
|
7
|
+
if (event == dliNotePreLoadLibrary && std::string_view{info->szDll} == "node.exe") {
|
|
8
|
+
return reinterpret_cast<FARPROC>(GetModuleHandle(nullptr));
|
|
9
|
+
} else {
|
|
10
|
+
return nullptr;
|
|
11
|
+
}
|
|
12
|
+
}};
|