Skip to main content

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