Skip to content

Commit af3c7ef

Browse files
Gabriel Schulhofrvagg
Gabriel Schulhof
authored andcommitted
src: factor out Node.js-agnostic N-APIs
Split the Node.js ECMAScript API (N-EAPI?) into its own header and implementation files. The motivation is that the ECMAScript API stand on its own so it might be embedded separately, implementation and all. Portions of the implementation used by both files are stored in `node_api_impl.h`. The checked boxes below indicate that the given API remains in `node_api.h`, whereas the lack of a checkbox indicates that the API was moved to `node_ecma_api.h`. * [x] NAPI_MODULE * [x] NAPI_MODULE_INIT * [x] napi_acquire_threadsafe_function * [x] napi_add_env_cleanup_hook * [x] napi_async_destroy * [x] napi_async_init * [x] napi_call_threadsafe_function * [x] napi_cancel_async_work * [x] napi_close_callback_scope * [x] napi_create_async_work * [x] napi_create_buffer * [x] napi_create_buffer_copy * [x] napi_create_external_buffer * [x] napi_create_threadsafe_function * [x] napi_delete_async_work * [x] napi_fatal_error * [x] napi_fatal_exception * [x] napi_get_buffer_info * [x] napi_get_node_version * [x] napi_get_threadsafe_function_context * [x] napi_get_uv_event_loop * [x] napi_is_buffer * [x] napi_make_callback * [x] napi_module_register * [x] napi_open_callback_scope * [x] napi_queue_async_work * [x] napi_ref_threadsafe_function * [x] napi_release_threadsafe_function * [x] napi_remove_env_cleanup_hook * [x] napi_unref_threadsafe_function * [ ] napi_add_finalizer * [ ] napi_adjust_external_memory * [ ] napi_call_function * [ ] napi_close_escapable_handle_scope * [ ] napi_close_handle_scope * [ ] napi_coerce_to_bool * [ ] napi_coerce_to_number * [ ] napi_coerce_to_object * [ ] napi_coerce_to_string * [ ] napi_create_array * [ ] napi_create_arraybuffer * [ ] napi_create_array_with_length * [ ] napi_create_bigint_int64 * [ ] napi_create_bigint_uint64 * [ ] napi_create_bigint_words * [ ] napi_create_dataview * [ ] napi_create_double * [ ] napi_create_error * [ ] napi_create_external * [ ] napi_create_external_arraybuffer * [ ] napi_create_function * [ ] napi_create_int32 * [ ] napi_create_int64 * [ ] napi_create_object * [ ] napi_create_promise * [ ] napi_create_range_error * [ ] napi_create_reference * [ ] napi_create_string_latin1 * [ ] napi_create_string_utf16 * [ ] napi_create_string_utf8 * [ ] napi_create_symbol * [ ] napi_create_typedarray * [ ] napi_create_type_error * [ ] napi_create_uint32 * [ ] napi_define_class * [ ] napi_define_properties * [ ] napi_delete_element * [ ] napi_delete_property * [ ] napi_delete_reference * [ ] napi_escape_handle * [ ] napi_get_and_clear_last_exception * [ ] napi_get_arraybuffer_info * [ ] napi_get_array_length * [ ] napi_get_boolean * [ ] napi_get_cb_info * [ ] napi_get_dataview_info * [ ] napi_get_element * [ ] napi_get_global * [ ] napi_get_last_error_info * [ ] napi_get_named_property * [ ] napi_get_new_target * [ ] napi_get_null * [ ] napi_get_property * [ ] napi_get_property_names * [ ] napi_get_prototype * [ ] napi_get_reference_value * [ ] napi_get_typedarray_info * [ ] napi_get_undefined * [ ] napi_get_value_bigint_int64 * [ ] napi_get_value_bigint_uint64 * [ ] napi_get_value_bigint_words * [ ] napi_get_value_bool * [ ] napi_get_value_double * [ ] napi_get_value_external * [ ] napi_get_value_int32 * [ ] napi_get_value_int64 * [ ] napi_get_value_string_latin1 * [ ] napi_get_value_string_utf16 * [ ] napi_get_value_string_utf8 * [ ] napi_get_value_uint32 * [ ] napi_get_version * [ ] napi_has_element * [ ] napi_has_named_property * [ ] napi_has_own_property * [ ] napi_has_property * [ ] napi_instanceof * [ ] napi_is_array * [ ] napi_is_arraybuffer * [ ] napi_is_dataview * [ ] napi_is_error * [ ] napi_is_exception_pending * [ ] napi_is_promise * [ ] napi_is_typedarray * [ ] napi_new_instance * [ ] napi_open_escapable_handle_scope * [ ] napi_open_handle_scope * [ ] napi_reference_ref * [ ] napi_reference_unref * [ ] napi_reject_deferred * [ ] napi_remove_wrap * [ ] napi_resolve_deferred * [ ] napi_run_script * [ ] napi_set_element * [ ] napi_set_named_property * [ ] napi_set_property * [ ] napi_strict_equals * [ ] napi_throw * [ ] napi_throw_error * [ ] napi_throw_range_error * [ ] napi_throw_type_error * [ ] napi_typeof * [ ] napi_unwrap * [ ] napi_wrap PR-URL: #23786 Reviewed-By: Yazhong Liu <yorkiefixer@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
1 parent b44623e commit af3c7ef

18 files changed

+3927
-3788
lines changed

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,8 @@ ADDONS_NAPI_BINDING_SOURCES := \
393393
# Implicitly depends on $(NODE_EXE), see the build-addons-napi rule for rationale.
394394
test/addons-napi/.buildstamp: $(ADDONS_PREREQS) \
395395
$(ADDONS_NAPI_BINDING_GYPS) $(ADDONS_NAPI_BINDING_SOURCES) \
396-
src/node_api.h src/node_api_types.h
396+
src/node_api.h src/node_api_types.h src/js_native_api.h \
397+
src/js_native_api_types.h src/js_native_api_v8.h src/js_native_api_v8_internals.h
397398
@$(call run_build_addons,"$$PWD/test/addons-napi",$@)
398399

399400
.PHONY: build-addons-napi

doc/api/n-api.md

+59
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,65 @@ available to the module code.
155155

156156
\* Indicates that the N-API version was released as experimental
157157

158+
The N-APIs associated strictly with accessing ECMAScript features from native
159+
code can be found separately in `js_native_api.h` and `js_native_api_types.h`.
160+
The APIs defined in these headers are included in `node_api.h` and
161+
`node_api_types.h`. The headers are structured in this way in order to allow
162+
implementations of N-API outside of Node.js. For those implementations the
163+
Node.js specific APIs may not be applicable.
164+
165+
The Node.js-specific parts of an addon can be separated from the code that
166+
exposes the actual functionality to the JavaScript environment so that the
167+
latter may be used with multiple implementations of N-API. In the example below,
168+
`addon.c` and `addon.h` refer only to `js_native_api.h`. This ensures that
169+
`addon.c` can be reused to compile against either the Node.js implementation of
170+
N-API or any implementation of N-API outside of Node.js.
171+
172+
`addon_node.c` is a separate file that contains the Node.js specific entry point
173+
to the addon and which instantiates the addon by calling into `addon.c` when the
174+
addon is loaded into a Node.js environment.
175+
176+
```C
177+
// addon.h
178+
#ifndef _ADDON_H_
179+
#define _ADDON_H_
180+
#include <js_native_api.h>
181+
napi_value create_addon(napi_env env);
182+
#endif // _ADDON_H_
183+
```
184+
185+
```C
186+
// addon.c
187+
#include "addon.h"
188+
napi_value create_addon(napi_env env) {
189+
napi_value result;
190+
assert(napi_create_object(env, &result) == napi_ok);
191+
napi_value exported_function;
192+
assert(napi_create_function(env,
193+
"doSomethingUseful",
194+
NAPI_AUTO_LENGTH,
195+
DoSomethingUseful,
196+
NULL,
197+
&exported_function) == napi_ok);
198+
assert(napi_set_named_property(env,
199+
result,
200+
"doSomethingUseful",
201+
exported_function) == napi_ok);
202+
return result;
203+
}
204+
```
205+
206+
```C
207+
// addon_node.c
208+
#include <node_api.h>
209+
210+
static napi_value Init(napi_env env, napi_value exports) {
211+
return create_addon(env);
212+
}
213+
214+
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
215+
```
216+
158217
## Basic N-API Data Types
159218

160219
N-API exposes the following fundamental datatypes as abstractions that are

node.gyp

+5
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,11 @@
334334
'src/fs_event_wrap.cc',
335335
'src/handle_wrap.cc',
336336
'src/heap_utils.cc',
337+
'src/js_native_api.h',
338+
'src/js_native_api_types.h',
339+
'src/js_native_api_v8.cc',
340+
'src/js_native_api_v8.h',
341+
'src/js_native_api_v8_internals.h',
337342
'src/js_stream.cc',
338343
'src/module_wrap.cc',
339344
'src/node.cc',

src/js_native_api.h

+485
Large diffs are not rendered by default.

src/js_native_api_types.h

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#ifndef SRC_JS_NATIVE_API_TYPES_H_
2+
#define SRC_JS_NATIVE_API_TYPES_H_
3+
4+
#include <stddef.h>
5+
#include <stdint.h>
6+
7+
#if !defined __cplusplus || (defined(_MSC_VER) && _MSC_VER < 1900)
8+
typedef uint16_t char16_t;
9+
#endif
10+
11+
// JSVM API types are all opaque pointers for ABI stability
12+
// typedef undefined structs instead of void* for compile time type safety
13+
typedef struct napi_env__* napi_env;
14+
typedef struct napi_value__* napi_value;
15+
typedef struct napi_ref__* napi_ref;
16+
typedef struct napi_handle_scope__* napi_handle_scope;
17+
typedef struct napi_escapable_handle_scope__* napi_escapable_handle_scope;
18+
typedef struct napi_callback_info__* napi_callback_info;
19+
typedef struct napi_deferred__* napi_deferred;
20+
21+
typedef enum {
22+
napi_default = 0,
23+
napi_writable = 1 << 0,
24+
napi_enumerable = 1 << 1,
25+
napi_configurable = 1 << 2,
26+
27+
// Used with napi_define_class to distinguish static properties
28+
// from instance properties. Ignored by napi_define_properties.
29+
napi_static = 1 << 10,
30+
} napi_property_attributes;
31+
32+
typedef enum {
33+
// ES6 types (corresponds to typeof)
34+
napi_undefined,
35+
napi_null,
36+
napi_boolean,
37+
napi_number,
38+
napi_string,
39+
napi_symbol,
40+
napi_object,
41+
napi_function,
42+
napi_external,
43+
napi_bigint,
44+
} napi_valuetype;
45+
46+
typedef enum {
47+
napi_int8_array,
48+
napi_uint8_array,
49+
napi_uint8_clamped_array,
50+
napi_int16_array,
51+
napi_uint16_array,
52+
napi_int32_array,
53+
napi_uint32_array,
54+
napi_float32_array,
55+
napi_float64_array,
56+
napi_bigint64_array,
57+
napi_biguint64_array,
58+
} napi_typedarray_type;
59+
60+
typedef enum {
61+
napi_ok,
62+
napi_invalid_arg,
63+
napi_object_expected,
64+
napi_string_expected,
65+
napi_name_expected,
66+
napi_function_expected,
67+
napi_number_expected,
68+
napi_boolean_expected,
69+
napi_array_expected,
70+
napi_generic_failure,
71+
napi_pending_exception,
72+
napi_cancelled,
73+
napi_escape_called_twice,
74+
napi_handle_scope_mismatch,
75+
napi_callback_scope_mismatch,
76+
napi_queue_full,
77+
napi_closing,
78+
napi_bigint_expected,
79+
} napi_status;
80+
81+
typedef napi_value (*napi_callback)(napi_env env,
82+
napi_callback_info info);
83+
typedef void (*napi_finalize)(napi_env env,
84+
void* finalize_data,
85+
void* finalize_hint);
86+
87+
typedef struct {
88+
// One of utf8name or name should be NULL.
89+
const char* utf8name;
90+
napi_value name;
91+
92+
napi_callback method;
93+
napi_callback getter;
94+
napi_callback setter;
95+
napi_value value;
96+
97+
napi_property_attributes attributes;
98+
void* data;
99+
} napi_property_descriptor;
100+
101+
typedef struct {
102+
const char* error_message;
103+
void* engine_reserved;
104+
uint32_t engine_error_code;
105+
napi_status error_code;
106+
} napi_extended_error_info;
107+
108+
#endif // SRC_JS_NATIVE_API_TYPES_H_

0 commit comments

Comments
 (0)