Skip to content

Commit c224486

Browse files
author
Mariusz Pasinski
committed
Merge branch 'mario/twisted-addon-example' into mario/wip-refactor-cpp
2 parents 437ba9b + a9f3be0 commit c224486

File tree

6 files changed

+401
-0
lines changed

6 files changed

+401
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
project(examples-1-getting-started-2_function_arguments_twisted-napi)
3+
4+
add_compile_definitions(-DNAPI_VERSION=4)
5+
6+
add_library(addon_twisted SHARED addon.c ${CMAKE_JS_SRC})
7+
set_target_properties(addon_twisted PROPERTIES PREFIX "" SUFFIX ".node")
8+
target_include_directories(addon_twisted PRIVATE ${CMAKE_JS_INC})
9+
target_link_libraries(addon_twisted PRIVATE ${CMAKE_JS_LIB})
10+
target_compile_features(addon_twisted PRIVATE cxx_std_17)
11+
12+
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
13+
# Generate node.lib
14+
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
15+
endif()
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <assert.h>
2+
#include "node_api_deprecated.h"
3+
#include <stdio.h>
4+
5+
static napi_value Add(napi_env env, napi_callback_info info) {
6+
napi_status status;
7+
8+
size_t argc = 2;
9+
napi_value args[2];
10+
status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
11+
assert(status == napi_ok);
12+
13+
if (argc < 2) {
14+
napi_throw_type_error(env, NULL, "Wrong number of arguments");
15+
return NULL;
16+
}
17+
18+
napi_valuetype valuetype0;
19+
status = napi_typeof(env, args[0], &valuetype0);
20+
assert(status == napi_ok);
21+
22+
napi_valuetype valuetype1;
23+
status = napi_typeof(env, args[1], &valuetype1);
24+
assert(status == napi_ok);
25+
26+
if (valuetype0 != napi_number || valuetype1 != napi_number) {
27+
napi_throw_type_error(env, NULL, "Wrong arguments");
28+
return NULL;
29+
}
30+
31+
double value0;
32+
status = napi_get_value_double(env, args[0], &value0);
33+
assert(status == napi_ok);
34+
35+
double value1;
36+
status = napi_get_value_double(env, args[1], &value1);
37+
assert(status == napi_ok);
38+
39+
napi_value sum;
40+
status = napi_create_double(env, value0 + value1, &sum);
41+
assert(status == napi_ok);
42+
43+
return sum;
44+
}
45+
46+
#define DECLARE_NAPI_METHOD(name, func) \
47+
{ name, 0, func, 0, 0, 0, napi_default, 0 }
48+
49+
napi_value Init(napi_env env, napi_value exports) {
50+
napi_status status;
51+
napi_property_descriptor addDescriptor = DECLARE_NAPI_METHOD("add", Add);
52+
status = napi_define_properties(env, exports, 1, &addDescriptor);
53+
assert(status == napi_ok);
54+
return exports;
55+
}
56+
57+
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"targets": [
3+
{
4+
"target_name": "addon_twisted",
5+
"sources": [ "addon.c" ],
6+
"defines": [
7+
"NAPI_VERSION=4"
8+
],
9+
}
10+
]
11+
}
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
// Taken from https://github.com/nodejs/node-api-headers/blob/2a5355a65e06b081154e584ca5b0574c9c07b61d/include/node_api.h
2+
#ifndef SRC_NODE_API_H_
3+
#define SRC_NODE_API_H_
4+
5+
#ifdef BUILDING_NODE_EXTENSION
6+
#ifdef _WIN32
7+
// Building native module against node
8+
#define NAPI_EXTERN __declspec(dllimport)
9+
#elif defined(__wasm32__)
10+
#define NAPI_EXTERN __attribute__((__import_module__("napi")))
11+
#endif
12+
#endif
13+
#include <js_native_api.h>
14+
#include <node_api_types.h>
15+
16+
struct uv_loop_s; // Forward declaration.
17+
18+
#ifdef _WIN32
19+
# define NAPI_MODULE_EXPORT __declspec(dllexport)
20+
#else
21+
# define NAPI_MODULE_EXPORT __attribute__((visibility("default")))
22+
#endif
23+
24+
#if defined(__GNUC__)
25+
# define NAPI_NO_RETURN __attribute__((noreturn))
26+
#elif defined(_WIN32)
27+
# define NAPI_NO_RETURN __declspec(noreturn)
28+
#else
29+
# define NAPI_NO_RETURN
30+
#endif
31+
32+
typedef napi_value (*napi_addon_register_func)(napi_env env,
33+
napi_value exports);
34+
35+
typedef struct napi_module {
36+
int nm_version;
37+
unsigned int nm_flags;
38+
const char* nm_filename;
39+
napi_addon_register_func nm_register_func;
40+
const char* nm_modname;
41+
void* nm_priv;
42+
void* reserved[4];
43+
} napi_module;
44+
45+
#define NAPI_MODULE_VERSION 1
46+
47+
#if defined(_MSC_VER)
48+
#pragma section(".CRT$XCU", read)
49+
#define NAPI_C_CTOR(fn) \
50+
static void __cdecl fn(void); \
51+
__declspec(dllexport, allocate(".CRT$XCU")) void(__cdecl * fn##_)(void) = \
52+
fn; \
53+
static void __cdecl fn(void)
54+
#else
55+
#define NAPI_C_CTOR(fn) \
56+
static void fn(void) __attribute__((constructor)); \
57+
static void fn(void)
58+
#endif
59+
60+
#define NAPI_MODULE_X(modname, regfunc, priv, flags) \
61+
EXTERN_C_START \
62+
static napi_module _module = \
63+
{ \
64+
NAPI_MODULE_VERSION, \
65+
flags, \
66+
__FILE__, \
67+
regfunc, \
68+
#modname, \
69+
priv, \
70+
{0}, \
71+
}; \
72+
NAPI_C_CTOR(_register_ ## modname) { \
73+
napi_module_register(&_module); \
74+
} \
75+
EXTERN_C_END
76+
77+
#define NAPI_MODULE_INITIALIZER_X(base, version) \
78+
NAPI_MODULE_INITIALIZER_X_HELPER(base, version)
79+
#define NAPI_MODULE_INITIALIZER_X_HELPER(base, version) base##version
80+
81+
#ifdef __wasm32__
82+
#define NAPI_WASM_INITIALIZER \
83+
NAPI_MODULE_INITIALIZER_X(napi_register_wasm_v, NAPI_MODULE_VERSION)
84+
#define NAPI_MODULE(modname, regfunc) \
85+
EXTERN_C_START \
86+
NAPI_MODULE_EXPORT napi_value NAPI_WASM_INITIALIZER(napi_env env, \
87+
napi_value exports) { \
88+
return regfunc(env, exports); \
89+
} \
90+
EXTERN_C_END
91+
#else
92+
#define NAPI_MODULE(modname, regfunc) \
93+
NAPI_MODULE_X(modname, regfunc, NULL, 0) // NOLINT (readability/null_usage)
94+
#endif
95+
96+
#define NAPI_MODULE_INITIALIZER_BASE napi_register_module_v
97+
98+
#define NAPI_MODULE_INITIALIZER \
99+
NAPI_MODULE_INITIALIZER_X(NAPI_MODULE_INITIALIZER_BASE, \
100+
NAPI_MODULE_VERSION)
101+
102+
#define NAPI_MODULE_INIT() \
103+
EXTERN_C_START \
104+
NAPI_MODULE_EXPORT napi_value \
105+
NAPI_MODULE_INITIALIZER(napi_env env, napi_value exports); \
106+
EXTERN_C_END \
107+
NAPI_MODULE(NODE_GYP_MODULE_NAME, NAPI_MODULE_INITIALIZER) \
108+
napi_value NAPI_MODULE_INITIALIZER(napi_env env, \
109+
napi_value exports)
110+
111+
EXTERN_C_START
112+
113+
NAPI_EXTERN void napi_module_register(napi_module* mod);
114+
115+
NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location,
116+
size_t location_len,
117+
const char* message,
118+
size_t message_len);
119+
120+
// Methods for custom handling of async operations
121+
NAPI_EXTERN napi_status napi_async_init(napi_env env,
122+
napi_value async_resource,
123+
napi_value async_resource_name,
124+
napi_async_context* result);
125+
126+
NAPI_EXTERN napi_status napi_async_destroy(napi_env env,
127+
napi_async_context async_context);
128+
129+
NAPI_EXTERN napi_status napi_make_callback(napi_env env,
130+
napi_async_context async_context,
131+
napi_value recv,
132+
napi_value func,
133+
size_t argc,
134+
const napi_value* argv,
135+
napi_value* result);
136+
137+
// Methods to provide node::Buffer functionality with napi types
138+
NAPI_EXTERN napi_status napi_create_buffer(napi_env env,
139+
size_t length,
140+
void** data,
141+
napi_value* result);
142+
NAPI_EXTERN napi_status napi_create_external_buffer(napi_env env,
143+
size_t length,
144+
void* data,
145+
napi_finalize finalize_cb,
146+
void* finalize_hint,
147+
napi_value* result);
148+
NAPI_EXTERN napi_status napi_create_buffer_copy(napi_env env,
149+
size_t length,
150+
const void* data,
151+
void** result_data,
152+
napi_value* result);
153+
NAPI_EXTERN napi_status napi_is_buffer(napi_env env,
154+
napi_value value,
155+
bool* result);
156+
NAPI_EXTERN napi_status napi_get_buffer_info(napi_env env,
157+
napi_value value,
158+
void** data,
159+
size_t* length);
160+
161+
// Methods to manage simple async operations
162+
NAPI_EXTERN
163+
napi_status napi_create_async_work(napi_env env,
164+
napi_value async_resource,
165+
napi_value async_resource_name,
166+
napi_async_execute_callback execute,
167+
napi_async_complete_callback complete,
168+
void* data,
169+
napi_async_work* result);
170+
NAPI_EXTERN napi_status napi_delete_async_work(napi_env env,
171+
napi_async_work work);
172+
NAPI_EXTERN napi_status napi_queue_async_work(napi_env env,
173+
napi_async_work work);
174+
NAPI_EXTERN napi_status napi_cancel_async_work(napi_env env,
175+
napi_async_work work);
176+
177+
// version management
178+
NAPI_EXTERN
179+
napi_status napi_get_node_version(napi_env env,
180+
const napi_node_version** version);
181+
182+
#if NAPI_VERSION >= 2
183+
184+
// Return the current libuv event loop for a given environment
185+
NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env,
186+
struct uv_loop_s** loop);
187+
188+
#endif // NAPI_VERSION >= 2
189+
190+
#if NAPI_VERSION >= 3
191+
192+
NAPI_EXTERN napi_status napi_fatal_exception(napi_env env, napi_value err);
193+
194+
NAPI_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
195+
void (*fun)(void* arg),
196+
void* arg);
197+
198+
NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
199+
void (*fun)(void* arg),
200+
void* arg);
201+
202+
NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,
203+
napi_value resource_object,
204+
napi_async_context context,
205+
napi_callback_scope* result);
206+
207+
NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env,
208+
napi_callback_scope scope);
209+
210+
#endif // NAPI_VERSION >= 3
211+
212+
#if NAPI_VERSION >= 4
213+
214+
#ifndef __wasm32__
215+
// Calling into JS from other threads
216+
NAPI_EXTERN napi_status
217+
napi_create_threadsafe_function(napi_env env,
218+
napi_value func,
219+
napi_value async_resource,
220+
napi_value async_resource_name,
221+
size_t max_queue_size,
222+
size_t initial_thread_count,
223+
void* thread_finalize_data,
224+
napi_finalize thread_finalize_cb,
225+
void* context,
226+
napi_threadsafe_function_call_js call_js_cb,
227+
napi_threadsafe_function* result);
228+
229+
NAPI_EXTERN napi_status
230+
napi_get_threadsafe_function_context(napi_threadsafe_function func,
231+
void** result);
232+
233+
NAPI_EXTERN napi_status
234+
napi_call_threadsafe_function(napi_threadsafe_function func,
235+
void* data,
236+
napi_threadsafe_function_call_mode is_blocking);
237+
238+
NAPI_EXTERN napi_status
239+
napi_acquire_threadsafe_function(napi_threadsafe_function func);
240+
241+
NAPI_EXTERN napi_status
242+
napi_release_threadsafe_function(napi_threadsafe_function func,
243+
napi_threadsafe_function_release_mode mode);
244+
245+
NAPI_EXTERN napi_status
246+
napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
247+
248+
NAPI_EXTERN napi_status
249+
napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
250+
#endif // __wasm32__
251+
252+
#endif // NAPI_VERSION >= 4
253+
254+
#ifdef NAPI_EXPERIMENTAL
255+
256+
NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
257+
napi_env env,
258+
napi_async_cleanup_hook hook,
259+
void* arg,
260+
napi_async_cleanup_hook_handle* remove_handle);
261+
262+
NAPI_EXTERN napi_status napi_remove_async_cleanup_hook(
263+
napi_async_cleanup_hook_handle remove_handle);
264+
265+
#endif // NAPI_EXPERIMENTAL
266+
267+
EXTERN_C_END
268+
269+
#endif // SRC_NODE_API_H_

packages/node-addon-examples/examples/1-getting-started/2_function_arguments_twisted/napi/package-lock.json

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)