neon/sys/bindings/
functions.rs

1#![allow(clippy::too_many_arguments)]
2
3mod napi1 {
4    use super::super::types::*;
5    use std::os::raw::{c_char, c_void};
6
7    generate!(
8        #[cfg_attr(docsrs, doc(cfg(feature = "napi-1")))]
9        extern "C" {
10            fn get_undefined(env: Env, result: *mut Value) -> Status;
11
12            fn get_null(env: Env, result: *mut Value) -> Status;
13
14            fn get_global(env: Env, result: *mut Value) -> Status;
15
16            fn get_boolean(env: Env, value: bool, result: *mut Value) -> Status;
17
18            fn create_double(env: Env, value: f64, result: *mut Value) -> Status;
19
20            fn create_object(env: Env, result: *mut Value) -> Status;
21
22            fn get_value_bool(env: Env, value: Value, result: *mut bool) -> Status;
23
24            fn get_value_double(env: Env, value: Value, result: *mut f64) -> Status;
25
26            fn create_array_with_length(env: Env, length: usize, result: *mut Value) -> Status;
27
28            fn get_array_length(env: Env, value: Value, result: *mut u32) -> Status;
29
30            fn get_new_target(env: Env, cbinfo: CallbackInfo, result: *mut Value) -> Status;
31
32            fn coerce_to_string(env: Env, value: Value, result: *mut Value) -> Status;
33
34            fn throw(env: Env, error: Value) -> Status;
35
36            fn create_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
37
38            fn get_and_clear_last_exception(env: Env, result: *mut Value) -> Status;
39
40            fn is_exception_pending(env: Env, result: *mut bool) -> Status;
41
42            fn get_value_external(env: Env, value: Value, result: *mut *mut c_void) -> Status;
43
44            fn typeof_value(env: Env, value: Value, result: *mut ValueType) -> Status;
45
46            fn close_escapable_handle_scope(env: Env, scope: EscapableHandleScope) -> Status;
47
48            fn open_escapable_handle_scope(env: Env, result: *mut EscapableHandleScope) -> Status;
49
50            fn open_handle_scope(env: Env, result: *mut HandleScope) -> Status;
51
52            fn close_handle_scope(env: Env, scope: HandleScope) -> Status;
53
54            fn is_arraybuffer(env: Env, value: Value, result: *mut bool) -> Status;
55            fn is_typedarray(env: Env, value: Value, result: *mut bool) -> Status;
56            fn is_buffer(env: Env, value: Value, result: *mut bool) -> Status;
57            fn is_error(env: Env, value: Value, result: *mut bool) -> Status;
58            fn is_array(env: Env, value: Value, result: *mut bool) -> Status;
59            fn is_promise(env: Env, value: Value, result: *mut bool) -> Status;
60
61            fn get_value_string_utf8(
62                env: Env,
63                value: Value,
64                buf: *mut c_char,
65                bufsize: usize,
66                result: *mut usize,
67            ) -> Status;
68
69            // The `buf` argument is defined as a `char16_t` which _should_ be a `u16` on most
70            // platforms. When generating bindings with `rust-bindgen` it unconditionally defines
71            // it as `u16` as well.
72            fn get_value_string_utf16(
73                env: Env,
74                value: Value,
75                buf: *mut u16,
76                bufsize: usize,
77                result: *mut usize,
78            ) -> Status;
79
80            fn create_type_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
81
82            fn create_range_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
83
84            fn create_string_utf8(
85                env: Env,
86                str: *const c_char,
87                length: usize,
88                result: *mut Value,
89            ) -> Status;
90
91            fn create_arraybuffer(
92                env: Env,
93                byte_length: usize,
94                data: *mut *mut c_void,
95                result: *mut Value,
96            ) -> Status;
97
98            fn get_arraybuffer_info(
99                env: Env,
100                arraybuffer: Value,
101                data: *mut *mut c_void,
102                byte_length: *mut usize,
103            ) -> Status;
104
105            fn create_typedarray(
106                env: Env,
107                type_: TypedArrayType,
108                length: usize,
109                arraybuffer: Value,
110                byte_offset: usize,
111                result: *mut Value,
112            ) -> Status;
113
114            fn get_typedarray_info(
115                env: Env,
116                typedarray: Value,
117                typ: *mut TypedArrayType,
118                length: *mut usize,
119                data: *mut *mut c_void,
120                buf: *mut Value,
121                offset: *mut usize,
122            ) -> Status;
123
124            fn create_buffer(
125                env: Env,
126                length: usize,
127                data: *mut *mut c_void,
128                result: *mut Value,
129            ) -> Status;
130
131            fn get_buffer_info(
132                env: Env,
133                value: Value,
134                data: *mut *mut c_void,
135                length: *mut usize,
136            ) -> Status;
137
138            fn get_cb_info(
139                env: Env,
140                cbinfo: CallbackInfo,
141                argc: *mut usize,
142                argv: *mut Value,
143                this_arg: *mut Value,
144                data: *mut *mut c_void,
145            ) -> Status;
146
147            fn create_external(
148                env: Env,
149                data: *mut c_void,
150                finalize_cb: Finalize,
151                finalize_hint: *mut c_void,
152                result: *mut Value,
153            ) -> Status;
154
155            fn new_instance(
156                env: Env,
157                constructor: Value,
158                argc: usize,
159                argv: *const Value,
160                result: *mut Value,
161            ) -> Status;
162
163            fn call_function(
164                env: Env,
165                recv: Value,
166                func: Value,
167                argc: usize,
168                argv: *const Value,
169                result: *mut Value,
170            ) -> Status;
171
172            fn create_function(
173                env: Env,
174                utf8name: *const c_char,
175                length: usize,
176                cb: Callback,
177                data: *mut c_void,
178                result: *mut Value,
179            ) -> Status;
180
181            fn set_property(env: Env, object: Value, key: Value, value: Value) -> Status;
182
183            fn get_property(env: Env, object: Value, key: Value, result: *mut Value) -> Status;
184
185            fn set_element(env: Env, object: Value, index: u32, value: Value) -> Status;
186
187            fn get_element(env: Env, object: Value, index: u32, result: *mut Value) -> Status;
188
189            fn escape_handle(
190                env: Env,
191                scope: EscapableHandleScope,
192                escapee: Value,
193                result: *mut Value,
194            ) -> Status;
195
196            fn create_reference(
197                env: Env,
198                value: Value,
199                initial_ref_count: u32,
200                result: *mut Ref,
201            ) -> Status;
202
203            fn reference_ref(env: Env, reference: Ref, result: *mut u32) -> Status;
204
205            fn reference_unref(env: Env, reference: Ref, result: *mut u32) -> Status;
206
207            fn delete_reference(env: Env, reference: Ref) -> Status;
208
209            fn get_reference_value(env: Env, reference: Ref, result: *mut Value) -> Status;
210
211            fn strict_equals(env: Env, lhs: Value, rhs: Value, result: *mut bool) -> Status;
212
213            #[cfg(any(feature = "sys", feature = "external-buffers"))]
214            fn create_external_arraybuffer(
215                env: Env,
216                data: *mut c_void,
217                length: usize,
218                finalize_cb: Finalize,
219                finalize_hint: *mut c_void,
220                result: *mut Value,
221            ) -> Status;
222
223            #[cfg(any(feature = "sys", feature = "external-buffers"))]
224            fn create_external_buffer(
225                env: Env,
226                length: usize,
227                data: *mut c_void,
228                finalize_cb: Finalize,
229                finalize_hint: *mut c_void,
230                result: *mut Value,
231            ) -> Status;
232
233            fn run_script(env: Env, script: Value, result: *mut Value) -> Status;
234
235            fn create_async_work(
236                env: Env,
237                async_resource: Value,
238                async_resource_name: Value,
239                execute: AsyncExecuteCallback,
240                complete: AsyncCompleteCallback,
241                data: *mut c_void,
242                result: *mut AsyncWork,
243            ) -> Status;
244
245            fn delete_async_work(env: Env, work: AsyncWork) -> Status;
246            fn queue_async_work(env: Env, work: AsyncWork) -> Status;
247            fn create_promise(env: Env, deferred: *mut Deferred, promise: *mut Value) -> Status;
248            fn resolve_deferred(env: Env, deferred: Deferred, resolution: Value) -> Status;
249            fn reject_deferred(env: Env, deferred: Deferred, rejection: Value) -> Status;
250
251            fn fatal_error(
252                location: *const c_char,
253                location_len: usize,
254                message: *const c_char,
255                message_len: usize,
256            );
257        }
258    );
259}
260
261#[cfg(feature = "napi-4")]
262mod napi4 {
263    use super::super::types::*;
264    use std::os::raw::c_void;
265
266    generate!(
267        #[cfg_attr(docsrs, doc(cfg(feature = "napi-4")))]
268        extern "C" {
269            fn create_threadsafe_function(
270                env: Env,
271                func: Value,
272                async_resource: Value,
273                async_resource_name: Value,
274                max_queue_size: usize,
275                initial_thread_count: usize,
276                thread_finalize_data: *mut c_void,
277                thread_finalize_cb: Finalize,
278                context: *mut c_void,
279                call_js_cb: ThreadsafeFunctionCallJs,
280                result: *mut ThreadsafeFunction,
281            ) -> Status;
282
283            fn call_threadsafe_function(
284                func: ThreadsafeFunction,
285                data: *mut c_void,
286                is_blocking: ThreadsafeFunctionCallMode,
287            ) -> Status;
288
289            fn release_threadsafe_function(
290                func: ThreadsafeFunction,
291                mode: ThreadsafeFunctionReleaseMode,
292            ) -> Status;
293
294            fn ref_threadsafe_function(env: Env, func: ThreadsafeFunction) -> Status;
295
296            fn unref_threadsafe_function(env: Env, func: ThreadsafeFunction) -> Status;
297        }
298    );
299}
300
301#[cfg(feature = "napi-5")]
302mod napi5 {
303    use super::super::types::*;
304    use std::ffi::c_void;
305
306    generate!(
307        #[cfg_attr(docsrs, doc(cfg(feature = "napi-5")))]
308        extern "C" {
309            fn create_date(env: Env, value: f64, result: *mut Value) -> Status;
310
311            fn get_date_value(env: Env, value: Value, result: *mut f64) -> Status;
312
313            fn is_date(env: Env, value: Value, result: *mut bool) -> Status;
314
315            fn add_finalizer(
316                env: Env,
317                js_object: Value,
318                native_object: *mut c_void,
319                finalize_cb: Finalize,
320                finalize_hint: *mut c_void,
321                result: Ref,
322            ) -> Status;
323        }
324    );
325}
326
327#[cfg(feature = "napi-6")]
328mod napi6 {
329    use super::super::types::*;
330    use std::os::raw::c_void;
331
332    generate!(
333        #[cfg_attr(docsrs, doc(cfg(feature = "napi-6")))]
334        extern "C" {
335            fn get_all_property_names(
336                env: Env,
337                object: Value,
338                key_mode: KeyCollectionMode,
339                key_filter: KeyFilter,
340                key_conversion: KeyConversion,
341                result: *mut Value,
342            ) -> Status;
343
344            fn set_instance_data(
345                env: Env,
346                data: *mut c_void,
347                finalize_cb: Finalize,
348                finalize_hint: *mut c_void,
349            ) -> Status;
350
351            fn get_instance_data(env: Env, data: *mut *mut c_void) -> Status;
352
353            fn create_bigint_int64(env: Env, value: i64, result: *mut Value) -> Status;
354
355            fn create_bigint_uint64(env: Env, value: u64, result: *mut Value) -> Status;
356
357            fn create_bigint_words(
358                env: Env,
359                sign_bit: i32,
360                word_count: usize,
361                words: *const u64,
362                result: *mut Value,
363            ) -> Status;
364
365            fn get_value_bigint_int64(
366                env: Env,
367                value: Value,
368                result: *mut i64,
369                lossless: *mut bool,
370            ) -> Status;
371
372            fn get_value_bigint_uint64(
373                env: Env,
374                value: Value,
375                result: *mut u64,
376                lossless: *mut bool,
377            ) -> Status;
378
379            fn get_value_bigint_words(
380                env: Env,
381                value: Value,
382                sign_bit: *mut i64,
383                word_count: *mut usize,
384                words: *mut u64,
385            ) -> Status;
386        }
387    );
388}
389
390#[cfg(feature = "napi-8")]
391mod napi8 {
392    use super::super::types::*;
393
394    generate!(
395        #[cfg_attr(docsrs, doc(cfg(feature = "napi-8")))]
396        extern "C" {
397            fn object_freeze(env: Env, object: Value) -> Status;
398            fn object_seal(env: Env, object: Value) -> Status;
399            fn type_tag_object(env: Env, object: Value, tag: *const TypeTag) -> Status;
400            fn check_object_type_tag(
401                env: Env,
402                object: Value,
403                tag: *const TypeTag,
404                result: *mut bool,
405            ) -> Status;
406        }
407    );
408}
409
410pub use napi1::*;
411#[cfg(feature = "napi-4")]
412pub use napi4::*;
413#[cfg(feature = "napi-5")]
414pub use napi5::*;
415#[cfg(feature = "napi-6")]
416pub use napi6::*;
417#[cfg(feature = "napi-8")]
418pub use napi8::*;
419
420use super::{Env, Status};
421
422// This symbol is loaded separately because it is a prerequisite
423unsafe fn get_version(host: &libloading::Library, env: Env) -> Result<u32, libloading::Error> {
424    let get_version = host.get::<fn(Env, *mut u32) -> Status>(b"napi_get_version")?;
425    let mut version = 0;
426
427    assert_eq!(get_version(env, &mut version as *mut _), Status::Ok,);
428
429    Ok(version)
430}
431
432pub(crate) unsafe fn load(env: Env) -> Result<(), libloading::Error> {
433    #[cfg(not(windows))]
434    let host = libloading::os::unix::Library::this().into();
435    #[cfg(windows)]
436    let host = libloading::os::windows::Library::this()?.into();
437
438    // This never fail since `get_version` is in N-API Version 1 and the module will fail
439    // with `Error: Module did not self-register` if N-API does not exist.
440    let actual_version = get_version(&host, env).expect("Failed to find N-API version");
441
442    let expected_version = match () {
443        _ if cfg!(feature = "napi-8") => 8,
444        _ if cfg!(feature = "napi-7") => 7,
445        _ if cfg!(feature = "napi-6") => 6,
446        _ if cfg!(feature = "napi-5") => 5,
447        _ if cfg!(feature = "napi-4") => 4,
448        _ if cfg!(feature = "napi-3") => 3,
449        _ if cfg!(feature = "napi-2") => 2,
450        _ => 1,
451    };
452
453    if actual_version < expected_version {
454        eprintln!("Minimum required Node-API version {expected_version}, found {actual_version}.\n\nSee the Node-API support matrix for more details: https://nodejs.org/api/n-api.html#node-api-version-matrix");
455    }
456
457    napi1::load(&host);
458
459    #[cfg(feature = "napi-4")]
460    napi4::load(&host);
461
462    #[cfg(feature = "napi-5")]
463    napi5::load(&host);
464
465    #[cfg(feature = "napi-6")]
466    napi6::load(&host);
467
468    #[cfg(feature = "napi-8")]
469    napi8::load(&host);
470
471    Ok(())
472}