xref: /unit/src/nodejs/unit-http/nxt_napi.h (revision 1020)
1*1020Smax.romanov@nginx.com 
2*1020Smax.romanov@nginx.com /*
3*1020Smax.romanov@nginx.com  * Copyright (C) NGINX, Inc.
4*1020Smax.romanov@nginx.com  */
5*1020Smax.romanov@nginx.com 
6*1020Smax.romanov@nginx.com #ifndef _NXT_NODEJS_NAPI_H_INCLUDED_
7*1020Smax.romanov@nginx.com #define _NXT_NODEJS_NAPI_H_INCLUDED_
8*1020Smax.romanov@nginx.com 
9*1020Smax.romanov@nginx.com #include <node_api.h>
10*1020Smax.romanov@nginx.com 
11*1020Smax.romanov@nginx.com 
12*1020Smax.romanov@nginx.com #ifdef __cplusplus
13*1020Smax.romanov@nginx.com extern "C" {
14*1020Smax.romanov@nginx.com #endif
15*1020Smax.romanov@nginx.com 
16*1020Smax.romanov@nginx.com #include "version.h"
17*1020Smax.romanov@nginx.com #include <nxt_unit.h>
18*1020Smax.romanov@nginx.com 
19*1020Smax.romanov@nginx.com #if NXT_VERNUM != NXT_NODE_VERNUM
20*1020Smax.romanov@nginx.com #error "libunit version mismatch."
21*1020Smax.romanov@nginx.com #endif
22*1020Smax.romanov@nginx.com 
23*1020Smax.romanov@nginx.com #include <nxt_unit_response.h>
24*1020Smax.romanov@nginx.com #include <nxt_unit_request.h>
25*1020Smax.romanov@nginx.com 
26*1020Smax.romanov@nginx.com 
27*1020Smax.romanov@nginx.com #ifdef __cplusplus
28*1020Smax.romanov@nginx.com } /* extern "C" */
29*1020Smax.romanov@nginx.com #endif
30*1020Smax.romanov@nginx.com 
31*1020Smax.romanov@nginx.com 
32*1020Smax.romanov@nginx.com struct nxt_napi {
33*1020Smax.romanov@nginx.com 
34*1020Smax.romanov@nginx.com     struct exception {
35*1020Smax.romanov@nginx.com         exception(const char *s) : str(s) { }
36*1020Smax.romanov@nginx.com 
37*1020Smax.romanov@nginx.com         const char *str;
38*1020Smax.romanov@nginx.com     };
39*1020Smax.romanov@nginx.com 
40*1020Smax.romanov@nginx.com 
41*1020Smax.romanov@nginx.com     nxt_napi(napi_env env) : env_(env) { }
42*1020Smax.romanov@nginx.com 
43*1020Smax.romanov@nginx.com 
44*1020Smax.romanov@nginx.com     inline napi_value
45*1020Smax.romanov@nginx.com     coerce_to_string(napi_value val)
46*1020Smax.romanov@nginx.com     {
47*1020Smax.romanov@nginx.com         napi_value   res;
48*1020Smax.romanov@nginx.com         napi_status  status;
49*1020Smax.romanov@nginx.com 
50*1020Smax.romanov@nginx.com         status = napi_coerce_to_string(env_, val, &res);
51*1020Smax.romanov@nginx.com         if (status != napi_ok) {
52*1020Smax.romanov@nginx.com             throw exception("Failed to coerce to string");
53*1020Smax.romanov@nginx.com         }
54*1020Smax.romanov@nginx.com 
55*1020Smax.romanov@nginx.com         return res;
56*1020Smax.romanov@nginx.com     }
57*1020Smax.romanov@nginx.com 
58*1020Smax.romanov@nginx.com 
59*1020Smax.romanov@nginx.com     inline napi_value
60*1020Smax.romanov@nginx.com     create_buffer(size_t size, void **data)
61*1020Smax.romanov@nginx.com     {
62*1020Smax.romanov@nginx.com         napi_value   res;
63*1020Smax.romanov@nginx.com         napi_status  status;
64*1020Smax.romanov@nginx.com 
65*1020Smax.romanov@nginx.com         status = napi_create_buffer(env_, size, data, &res);
66*1020Smax.romanov@nginx.com         if (status != napi_ok) {
67*1020Smax.romanov@nginx.com             throw exception("Failed to create buffer");
68*1020Smax.romanov@nginx.com         }
69*1020Smax.romanov@nginx.com 
70*1020Smax.romanov@nginx.com         return res;
71*1020Smax.romanov@nginx.com     }
72*1020Smax.romanov@nginx.com 
73*1020Smax.romanov@nginx.com 
74*1020Smax.romanov@nginx.com     inline napi_value
75*1020Smax.romanov@nginx.com     create_function(const char *name, size_t len, napi_callback cb, void *data)
76*1020Smax.romanov@nginx.com     {
77*1020Smax.romanov@nginx.com         napi_value   res;
78*1020Smax.romanov@nginx.com         napi_status  status;
79*1020Smax.romanov@nginx.com 
80*1020Smax.romanov@nginx.com         status = napi_create_function(env_, name, len, cb, data, &res);
81*1020Smax.romanov@nginx.com         if (status != napi_ok) {
82*1020Smax.romanov@nginx.com             throw exception("Failed to create function");
83*1020Smax.romanov@nginx.com         }
84*1020Smax.romanov@nginx.com 
85*1020Smax.romanov@nginx.com         return res;
86*1020Smax.romanov@nginx.com     }
87*1020Smax.romanov@nginx.com 
88*1020Smax.romanov@nginx.com 
89*1020Smax.romanov@nginx.com     inline napi_value
90*1020Smax.romanov@nginx.com     create_function(napi_callback cb)
91*1020Smax.romanov@nginx.com     {
92*1020Smax.romanov@nginx.com         return create_function(NULL, 0, cb, NULL);
93*1020Smax.romanov@nginx.com     }
94*1020Smax.romanov@nginx.com 
95*1020Smax.romanov@nginx.com 
96*1020Smax.romanov@nginx.com     inline napi_value
97*1020Smax.romanov@nginx.com     create_object()
98*1020Smax.romanov@nginx.com     {
99*1020Smax.romanov@nginx.com         napi_value   res;
100*1020Smax.romanov@nginx.com         napi_status  status;
101*1020Smax.romanov@nginx.com 
102*1020Smax.romanov@nginx.com         status = napi_create_object(env_, &res);
103*1020Smax.romanov@nginx.com         if (status != napi_ok) {
104*1020Smax.romanov@nginx.com             throw exception("Failed to create object");
105*1020Smax.romanov@nginx.com         }
106*1020Smax.romanov@nginx.com 
107*1020Smax.romanov@nginx.com         return res;
108*1020Smax.romanov@nginx.com     }
109*1020Smax.romanov@nginx.com 
110*1020Smax.romanov@nginx.com 
111*1020Smax.romanov@nginx.com     inline napi_ref
112*1020Smax.romanov@nginx.com     create_reference(napi_value val, int ref_count = 1)
113*1020Smax.romanov@nginx.com     {
114*1020Smax.romanov@nginx.com         napi_ref     res;
115*1020Smax.romanov@nginx.com         napi_status  status;
116*1020Smax.romanov@nginx.com 
117*1020Smax.romanov@nginx.com         status = napi_create_reference(env_, val, ref_count, &res);
118*1020Smax.romanov@nginx.com         if (status != napi_ok) {
119*1020Smax.romanov@nginx.com             throw exception("Failed to create reference");
120*1020Smax.romanov@nginx.com         }
121*1020Smax.romanov@nginx.com 
122*1020Smax.romanov@nginx.com         return res;
123*1020Smax.romanov@nginx.com     }
124*1020Smax.romanov@nginx.com 
125*1020Smax.romanov@nginx.com 
126*1020Smax.romanov@nginx.com     inline napi_value
127*1020Smax.romanov@nginx.com     create_string_latin1(const char *str, size_t len)
128*1020Smax.romanov@nginx.com     {
129*1020Smax.romanov@nginx.com         napi_value   res;
130*1020Smax.romanov@nginx.com         napi_status  status;
131*1020Smax.romanov@nginx.com 
132*1020Smax.romanov@nginx.com         status = napi_create_string_latin1(env_, str, len, &res);
133*1020Smax.romanov@nginx.com         if (status != napi_ok) {
134*1020Smax.romanov@nginx.com             throw exception("Failed to create latin1 string");
135*1020Smax.romanov@nginx.com         }
136*1020Smax.romanov@nginx.com 
137*1020Smax.romanov@nginx.com         return res;
138*1020Smax.romanov@nginx.com     }
139*1020Smax.romanov@nginx.com 
140*1020Smax.romanov@nginx.com 
141*1020Smax.romanov@nginx.com     inline napi_value
142*1020Smax.romanov@nginx.com     create_string_latin1(nxt_unit_sptr_t &str, size_t len)
143*1020Smax.romanov@nginx.com     {
144*1020Smax.romanov@nginx.com         const char  *p;
145*1020Smax.romanov@nginx.com 
146*1020Smax.romanov@nginx.com         p = (const char *) nxt_unit_sptr_get(&str);
147*1020Smax.romanov@nginx.com 
148*1020Smax.romanov@nginx.com         return create_string_latin1(p, len);
149*1020Smax.romanov@nginx.com     }
150*1020Smax.romanov@nginx.com 
151*1020Smax.romanov@nginx.com 
152*1020Smax.romanov@nginx.com     inline napi_value
153*1020Smax.romanov@nginx.com     define_class(const char *name, napi_callback ctor, size_t prop_count,
154*1020Smax.romanov@nginx.com         const napi_property_descriptor* props)
155*1020Smax.romanov@nginx.com     {
156*1020Smax.romanov@nginx.com         napi_value   res;
157*1020Smax.romanov@nginx.com         napi_status  status;
158*1020Smax.romanov@nginx.com 
159*1020Smax.romanov@nginx.com         status = napi_define_class(env_, name, NAPI_AUTO_LENGTH, ctor, nullptr,
160*1020Smax.romanov@nginx.com                                    prop_count, props, &res);
161*1020Smax.romanov@nginx.com         if (status != napi_ok) {
162*1020Smax.romanov@nginx.com             throw exception("Failed to define class");
163*1020Smax.romanov@nginx.com         }
164*1020Smax.romanov@nginx.com 
165*1020Smax.romanov@nginx.com         return res;
166*1020Smax.romanov@nginx.com     }
167*1020Smax.romanov@nginx.com 
168*1020Smax.romanov@nginx.com 
169*1020Smax.romanov@nginx.com     inline void
170*1020Smax.romanov@nginx.com     delete_reference(napi_ref ref)
171*1020Smax.romanov@nginx.com     {
172*1020Smax.romanov@nginx.com         napi_delete_reference(env_, ref);
173*1020Smax.romanov@nginx.com     }
174*1020Smax.romanov@nginx.com 
175*1020Smax.romanov@nginx.com 
176*1020Smax.romanov@nginx.com     inline uint32_t
177*1020Smax.romanov@nginx.com     get_array_length(napi_value val)
178*1020Smax.romanov@nginx.com     {
179*1020Smax.romanov@nginx.com         uint32_t     res;
180*1020Smax.romanov@nginx.com         napi_status  status;
181*1020Smax.romanov@nginx.com 
182*1020Smax.romanov@nginx.com         status = napi_get_array_length(env_, val, &res);
183*1020Smax.romanov@nginx.com         if (status != napi_ok) {
184*1020Smax.romanov@nginx.com             throw exception("Failed to get array length");
185*1020Smax.romanov@nginx.com         }
186*1020Smax.romanov@nginx.com 
187*1020Smax.romanov@nginx.com         return res;
188*1020Smax.romanov@nginx.com     }
189*1020Smax.romanov@nginx.com 
190*1020Smax.romanov@nginx.com 
191*1020Smax.romanov@nginx.com     inline napi_value
192*1020Smax.romanov@nginx.com     get_cb_info(napi_callback_info info, size_t &argc, napi_value *argv)
193*1020Smax.romanov@nginx.com     {
194*1020Smax.romanov@nginx.com         napi_value   res;
195*1020Smax.romanov@nginx.com         napi_status  status;
196*1020Smax.romanov@nginx.com 
197*1020Smax.romanov@nginx.com         status = napi_get_cb_info(env_, info, &argc, argv, &res, nullptr);
198*1020Smax.romanov@nginx.com         if (status != napi_ok) {
199*1020Smax.romanov@nginx.com             throw exception("Failed to get arguments from js");
200*1020Smax.romanov@nginx.com         }
201*1020Smax.romanov@nginx.com 
202*1020Smax.romanov@nginx.com         return res;
203*1020Smax.romanov@nginx.com     }
204*1020Smax.romanov@nginx.com 
205*1020Smax.romanov@nginx.com 
206*1020Smax.romanov@nginx.com     inline napi_value
207*1020Smax.romanov@nginx.com     get_cb_info(napi_callback_info info)
208*1020Smax.romanov@nginx.com     {
209*1020Smax.romanov@nginx.com         napi_value   res;
210*1020Smax.romanov@nginx.com         napi_status  status;
211*1020Smax.romanov@nginx.com 
212*1020Smax.romanov@nginx.com         status = napi_get_cb_info(env_, info, nullptr, nullptr, &res, nullptr);
213*1020Smax.romanov@nginx.com         if (status != napi_ok) {
214*1020Smax.romanov@nginx.com             throw exception("Failed to get arguments from js");
215*1020Smax.romanov@nginx.com         }
216*1020Smax.romanov@nginx.com 
217*1020Smax.romanov@nginx.com         return res;
218*1020Smax.romanov@nginx.com     }
219*1020Smax.romanov@nginx.com 
220*1020Smax.romanov@nginx.com 
221*1020Smax.romanov@nginx.com     inline napi_value
222*1020Smax.romanov@nginx.com     get_element(napi_value obj, uint32_t i)
223*1020Smax.romanov@nginx.com     {
224*1020Smax.romanov@nginx.com         napi_value   res;
225*1020Smax.romanov@nginx.com         napi_status  status;
226*1020Smax.romanov@nginx.com 
227*1020Smax.romanov@nginx.com         status = napi_get_element(env_, obj, i, &res);
228*1020Smax.romanov@nginx.com         if (status != napi_ok) {
229*1020Smax.romanov@nginx.com             throw exception("Failed to get element");
230*1020Smax.romanov@nginx.com         }
231*1020Smax.romanov@nginx.com 
232*1020Smax.romanov@nginx.com         return res;
233*1020Smax.romanov@nginx.com     }
234*1020Smax.romanov@nginx.com 
235*1020Smax.romanov@nginx.com 
236*1020Smax.romanov@nginx.com     inline napi_value
237*1020Smax.romanov@nginx.com     get_named_property(napi_value obj, const char *name)
238*1020Smax.romanov@nginx.com     {
239*1020Smax.romanov@nginx.com         napi_value   res;
240*1020Smax.romanov@nginx.com         napi_status  status;
241*1020Smax.romanov@nginx.com 
242*1020Smax.romanov@nginx.com         status = napi_get_named_property(env_, obj, name, &res);
243*1020Smax.romanov@nginx.com         if (status != napi_ok) {
244*1020Smax.romanov@nginx.com             throw exception("Failed to get named property");
245*1020Smax.romanov@nginx.com         }
246*1020Smax.romanov@nginx.com 
247*1020Smax.romanov@nginx.com         return res;
248*1020Smax.romanov@nginx.com     }
249*1020Smax.romanov@nginx.com 
250*1020Smax.romanov@nginx.com 
251*1020Smax.romanov@nginx.com     inline napi_value
252*1020Smax.romanov@nginx.com     get_new_target(napi_callback_info info)
253*1020Smax.romanov@nginx.com     {
254*1020Smax.romanov@nginx.com         napi_value   res;
255*1020Smax.romanov@nginx.com         napi_status  status;
256*1020Smax.romanov@nginx.com 
257*1020Smax.romanov@nginx.com         status = napi_get_new_target(env_, info, &res);
258*1020Smax.romanov@nginx.com         if (status != napi_ok) {
259*1020Smax.romanov@nginx.com             throw exception("Failed to get new target");
260*1020Smax.romanov@nginx.com         }
261*1020Smax.romanov@nginx.com 
262*1020Smax.romanov@nginx.com         return res;
263*1020Smax.romanov@nginx.com     }
264*1020Smax.romanov@nginx.com 
265*1020Smax.romanov@nginx.com 
266*1020Smax.romanov@nginx.com     inline napi_value
267*1020Smax.romanov@nginx.com     get_property(napi_value val, napi_value key)
268*1020Smax.romanov@nginx.com     {
269*1020Smax.romanov@nginx.com         napi_value   res;
270*1020Smax.romanov@nginx.com         napi_status  status;
271*1020Smax.romanov@nginx.com 
272*1020Smax.romanov@nginx.com         status = napi_get_property(env_, val, key, &res);
273*1020Smax.romanov@nginx.com         if (status != napi_ok) {
274*1020Smax.romanov@nginx.com             throw exception("Failed to get property");
275*1020Smax.romanov@nginx.com         }
276*1020Smax.romanov@nginx.com 
277*1020Smax.romanov@nginx.com         return res;
278*1020Smax.romanov@nginx.com     }
279*1020Smax.romanov@nginx.com 
280*1020Smax.romanov@nginx.com 
281*1020Smax.romanov@nginx.com     inline napi_value
282*1020Smax.romanov@nginx.com     get_property_names(napi_value val)
283*1020Smax.romanov@nginx.com     {
284*1020Smax.romanov@nginx.com         napi_value   res;
285*1020Smax.romanov@nginx.com         napi_status  status;
286*1020Smax.romanov@nginx.com 
287*1020Smax.romanov@nginx.com         status = napi_get_property_names(env_, val, &res);
288*1020Smax.romanov@nginx.com         if (status != napi_ok) {
289*1020Smax.romanov@nginx.com             throw exception("Failed to get property names");
290*1020Smax.romanov@nginx.com         }
291*1020Smax.romanov@nginx.com 
292*1020Smax.romanov@nginx.com         return res;
293*1020Smax.romanov@nginx.com     }
294*1020Smax.romanov@nginx.com 
295*1020Smax.romanov@nginx.com 
296*1020Smax.romanov@nginx.com     inline napi_value
297*1020Smax.romanov@nginx.com     get_reference_value(napi_ref ref)
298*1020Smax.romanov@nginx.com     {
299*1020Smax.romanov@nginx.com         napi_value   res;
300*1020Smax.romanov@nginx.com         napi_status  status;
301*1020Smax.romanov@nginx.com 
302*1020Smax.romanov@nginx.com         status = napi_get_reference_value(env_, ref, &res);
303*1020Smax.romanov@nginx.com         if (status != napi_ok) {
304*1020Smax.romanov@nginx.com             throw exception("Failed to get reference value");
305*1020Smax.romanov@nginx.com         }
306*1020Smax.romanov@nginx.com 
307*1020Smax.romanov@nginx.com         return res;
308*1020Smax.romanov@nginx.com     }
309*1020Smax.romanov@nginx.com 
310*1020Smax.romanov@nginx.com 
311*1020Smax.romanov@nginx.com     inline nxt_unit_request_info_t *
312*1020Smax.romanov@nginx.com     get_request_info(napi_value obj)
313*1020Smax.romanov@nginx.com     {
314*1020Smax.romanov@nginx.com         int64_t      n;
315*1020Smax.romanov@nginx.com         napi_status  status;
316*1020Smax.romanov@nginx.com 
317*1020Smax.romanov@nginx.com         status = napi_get_value_int64(env_, obj, &n);
318*1020Smax.romanov@nginx.com         if (status != napi_ok) {
319*1020Smax.romanov@nginx.com             throw exception("Failed to get request pointer");
320*1020Smax.romanov@nginx.com         }
321*1020Smax.romanov@nginx.com 
322*1020Smax.romanov@nginx.com         return (nxt_unit_request_info_t *) (intptr_t) n;
323*1020Smax.romanov@nginx.com     }
324*1020Smax.romanov@nginx.com 
325*1020Smax.romanov@nginx.com 
326*1020Smax.romanov@nginx.com     inline size_t
327*1020Smax.romanov@nginx.com     get_value_string_latin1(napi_value val, char *buf, size_t bufsize)
328*1020Smax.romanov@nginx.com     {
329*1020Smax.romanov@nginx.com         size_t       res;
330*1020Smax.romanov@nginx.com         napi_status  status;
331*1020Smax.romanov@nginx.com 
332*1020Smax.romanov@nginx.com         status = napi_get_value_string_latin1(env_, val, buf, bufsize, &res);
333*1020Smax.romanov@nginx.com         if (status != napi_ok) {
334*1020Smax.romanov@nginx.com             throw exception("Failed to get string latin1");
335*1020Smax.romanov@nginx.com         }
336*1020Smax.romanov@nginx.com 
337*1020Smax.romanov@nginx.com         return res;
338*1020Smax.romanov@nginx.com     }
339*1020Smax.romanov@nginx.com 
340*1020Smax.romanov@nginx.com 
341*1020Smax.romanov@nginx.com     inline uint32_t
342*1020Smax.romanov@nginx.com     get_value_uint32(napi_value obj)
343*1020Smax.romanov@nginx.com     {
344*1020Smax.romanov@nginx.com         uint32_t     res;
345*1020Smax.romanov@nginx.com         napi_status  status;
346*1020Smax.romanov@nginx.com 
347*1020Smax.romanov@nginx.com         status = napi_get_value_uint32(env_, obj, &res);
348*1020Smax.romanov@nginx.com         if (status != napi_ok) {
349*1020Smax.romanov@nginx.com             throw exception("Failed to get uint32_t");
350*1020Smax.romanov@nginx.com         }
351*1020Smax.romanov@nginx.com 
352*1020Smax.romanov@nginx.com         return res;
353*1020Smax.romanov@nginx.com     }
354*1020Smax.romanov@nginx.com 
355*1020Smax.romanov@nginx.com 
356*1020Smax.romanov@nginx.com     inline bool
357*1020Smax.romanov@nginx.com     is_array(napi_value val)
358*1020Smax.romanov@nginx.com     {
359*1020Smax.romanov@nginx.com         bool         res;
360*1020Smax.romanov@nginx.com         napi_status  status;
361*1020Smax.romanov@nginx.com 
362*1020Smax.romanov@nginx.com         status = napi_is_array(env_, val, &res);
363*1020Smax.romanov@nginx.com         if (status != napi_ok) {
364*1020Smax.romanov@nginx.com             throw exception("Failed to confirm value is array");
365*1020Smax.romanov@nginx.com         }
366*1020Smax.romanov@nginx.com 
367*1020Smax.romanov@nginx.com         return res;
368*1020Smax.romanov@nginx.com     }
369*1020Smax.romanov@nginx.com 
370*1020Smax.romanov@nginx.com 
371*1020Smax.romanov@nginx.com     inline napi_value
372*1020Smax.romanov@nginx.com     make_callback(napi_async_context ctx, napi_value val, napi_value func,
373*1020Smax.romanov@nginx.com         int argc, const napi_value *argv)
374*1020Smax.romanov@nginx.com     {
375*1020Smax.romanov@nginx.com         napi_value   res, ex;
376*1020Smax.romanov@nginx.com         napi_status  status;
377*1020Smax.romanov@nginx.com 
378*1020Smax.romanov@nginx.com         status = napi_make_callback(env_, ctx, val, func, argc, argv, &res);
379*1020Smax.romanov@nginx.com         if (status != napi_ok) {
380*1020Smax.romanov@nginx.com             if (status != napi_pending_exception) {
381*1020Smax.romanov@nginx.com                 throw exception("Failed to make callback");
382*1020Smax.romanov@nginx.com             }
383*1020Smax.romanov@nginx.com 
384*1020Smax.romanov@nginx.com             status = napi_get_and_clear_last_exception(env_, &ex);
385*1020Smax.romanov@nginx.com             if (status != napi_ok) {
386*1020Smax.romanov@nginx.com                 throw exception("Failed to get and clear last exception");
387*1020Smax.romanov@nginx.com             }
388*1020Smax.romanov@nginx.com 
389*1020Smax.romanov@nginx.com             /* Logging a description of the error and call stack. */
390*1020Smax.romanov@nginx.com             status = napi_fatal_exception(env_, ex);
391*1020Smax.romanov@nginx.com             if (status != napi_ok) {
392*1020Smax.romanov@nginx.com                 throw exception("Failed napi_fatal_exception()");
393*1020Smax.romanov@nginx.com             }
394*1020Smax.romanov@nginx.com         }
395*1020Smax.romanov@nginx.com 
396*1020Smax.romanov@nginx.com         return res;
397*1020Smax.romanov@nginx.com     }
398*1020Smax.romanov@nginx.com 
399*1020Smax.romanov@nginx.com 
400*1020Smax.romanov@nginx.com     inline napi_value
401*1020Smax.romanov@nginx.com     new_instance(napi_value ctor)
402*1020Smax.romanov@nginx.com     {
403*1020Smax.romanov@nginx.com         napi_value   res;
404*1020Smax.romanov@nginx.com         napi_status  status;
405*1020Smax.romanov@nginx.com 
406*1020Smax.romanov@nginx.com         status = napi_new_instance(env_, ctor, 0, NULL, &res);
407*1020Smax.romanov@nginx.com         if (status != napi_ok) {
408*1020Smax.romanov@nginx.com             throw exception("Failed to create instance");
409*1020Smax.romanov@nginx.com         }
410*1020Smax.romanov@nginx.com 
411*1020Smax.romanov@nginx.com         return res;
412*1020Smax.romanov@nginx.com     }
413*1020Smax.romanov@nginx.com 
414*1020Smax.romanov@nginx.com 
415*1020Smax.romanov@nginx.com     inline napi_value
416*1020Smax.romanov@nginx.com     new_instance(napi_value ctor, napi_value param)
417*1020Smax.romanov@nginx.com     {
418*1020Smax.romanov@nginx.com         napi_value   res;
419*1020Smax.romanov@nginx.com         napi_status  status;
420*1020Smax.romanov@nginx.com 
421*1020Smax.romanov@nginx.com         status = napi_new_instance(env_, ctor, 1, &param, &res);
422*1020Smax.romanov@nginx.com         if (status != napi_ok) {
423*1020Smax.romanov@nginx.com             throw exception("Failed to create instance");
424*1020Smax.romanov@nginx.com         }
425*1020Smax.romanov@nginx.com 
426*1020Smax.romanov@nginx.com         return res;
427*1020Smax.romanov@nginx.com     }
428*1020Smax.romanov@nginx.com 
429*1020Smax.romanov@nginx.com 
430*1020Smax.romanov@nginx.com     inline void
431*1020Smax.romanov@nginx.com     set_element(napi_value obj, uint32_t i, napi_value val)
432*1020Smax.romanov@nginx.com     {
433*1020Smax.romanov@nginx.com         napi_status  status;
434*1020Smax.romanov@nginx.com 
435*1020Smax.romanov@nginx.com         status = napi_set_element(env_, obj, i, val);
436*1020Smax.romanov@nginx.com         if (status != napi_ok) {
437*1020Smax.romanov@nginx.com             throw exception("Failed to set element");
438*1020Smax.romanov@nginx.com         }
439*1020Smax.romanov@nginx.com     }
440*1020Smax.romanov@nginx.com 
441*1020Smax.romanov@nginx.com 
442*1020Smax.romanov@nginx.com     inline void
443*1020Smax.romanov@nginx.com     set_named_property(napi_value obj, const char *name, napi_value val)
444*1020Smax.romanov@nginx.com     {
445*1020Smax.romanov@nginx.com         napi_status  status;
446*1020Smax.romanov@nginx.com 
447*1020Smax.romanov@nginx.com         status = napi_set_named_property(env_, obj, name, val);
448*1020Smax.romanov@nginx.com         if (status != napi_ok) {
449*1020Smax.romanov@nginx.com             throw exception("Failed to set named property");
450*1020Smax.romanov@nginx.com         }
451*1020Smax.romanov@nginx.com     }
452*1020Smax.romanov@nginx.com 
453*1020Smax.romanov@nginx.com 
454*1020Smax.romanov@nginx.com     inline void
455*1020Smax.romanov@nginx.com     set_named_property(napi_value obj, const char *name, napi_callback cb)
456*1020Smax.romanov@nginx.com     {
457*1020Smax.romanov@nginx.com         set_named_property(obj, name, create_function(cb));
458*1020Smax.romanov@nginx.com     }
459*1020Smax.romanov@nginx.com 
460*1020Smax.romanov@nginx.com 
461*1020Smax.romanov@nginx.com     inline napi_value
462*1020Smax.romanov@nginx.com     set_named_property(napi_value obj, const char *name, nxt_unit_sptr_t &val,
463*1020Smax.romanov@nginx.com         size_t len)
464*1020Smax.romanov@nginx.com     {
465*1020Smax.romanov@nginx.com         napi_value  str;
466*1020Smax.romanov@nginx.com 
467*1020Smax.romanov@nginx.com         str = create_string_latin1(val, len);
468*1020Smax.romanov@nginx.com 
469*1020Smax.romanov@nginx.com         set_named_property(obj, name, str);
470*1020Smax.romanov@nginx.com 
471*1020Smax.romanov@nginx.com         return str;
472*1020Smax.romanov@nginx.com     }
473*1020Smax.romanov@nginx.com 
474*1020Smax.romanov@nginx.com 
475*1020Smax.romanov@nginx.com     inline void
476*1020Smax.romanov@nginx.com     set_named_property(napi_value obj, const char *name, intptr_t val)
477*1020Smax.romanov@nginx.com     {
478*1020Smax.romanov@nginx.com         napi_value   ptr;
479*1020Smax.romanov@nginx.com         napi_status  status;
480*1020Smax.romanov@nginx.com 
481*1020Smax.romanov@nginx.com         status = napi_create_int64(env_, val, &ptr);
482*1020Smax.romanov@nginx.com         if (status != napi_ok) {
483*1020Smax.romanov@nginx.com             throw exception("Failed to create int64");
484*1020Smax.romanov@nginx.com         }
485*1020Smax.romanov@nginx.com 
486*1020Smax.romanov@nginx.com         set_named_property(obj, name, ptr);
487*1020Smax.romanov@nginx.com     }
488*1020Smax.romanov@nginx.com 
489*1020Smax.romanov@nginx.com 
490*1020Smax.romanov@nginx.com     inline void
491*1020Smax.romanov@nginx.com     throw_error(const char *str)
492*1020Smax.romanov@nginx.com     {
493*1020Smax.romanov@nginx.com         napi_throw_error(env_, NULL, str);
494*1020Smax.romanov@nginx.com     }
495*1020Smax.romanov@nginx.com 
496*1020Smax.romanov@nginx.com 
497*1020Smax.romanov@nginx.com     inline void
498*1020Smax.romanov@nginx.com     throw_error(const exception &e)
499*1020Smax.romanov@nginx.com     {
500*1020Smax.romanov@nginx.com         napi_throw_error(env_, NULL, e.str);
501*1020Smax.romanov@nginx.com     }
502*1020Smax.romanov@nginx.com 
503*1020Smax.romanov@nginx.com 
504*1020Smax.romanov@nginx.com     inline napi_valuetype
505*1020Smax.romanov@nginx.com     type_of(napi_value val)
506*1020Smax.romanov@nginx.com     {
507*1020Smax.romanov@nginx.com         napi_status     status;
508*1020Smax.romanov@nginx.com         napi_valuetype  res;
509*1020Smax.romanov@nginx.com 
510*1020Smax.romanov@nginx.com         status = napi_typeof(env_, val, &res);
511*1020Smax.romanov@nginx.com         if (status != napi_ok) {
512*1020Smax.romanov@nginx.com             throw exception("Failed to get typeof");
513*1020Smax.romanov@nginx.com         }
514*1020Smax.romanov@nginx.com 
515*1020Smax.romanov@nginx.com         return res;
516*1020Smax.romanov@nginx.com     }
517*1020Smax.romanov@nginx.com 
518*1020Smax.romanov@nginx.com 
519*1020Smax.romanov@nginx.com     inline void *
520*1020Smax.romanov@nginx.com     unwrap(napi_value val)
521*1020Smax.romanov@nginx.com     {
522*1020Smax.romanov@nginx.com         void         *res;
523*1020Smax.romanov@nginx.com         napi_status  status;
524*1020Smax.romanov@nginx.com 
525*1020Smax.romanov@nginx.com         status = napi_unwrap(env_, val, &res);
526*1020Smax.romanov@nginx.com         if (status != napi_ok) {
527*1020Smax.romanov@nginx.com             throw exception("Failed to unwrap");
528*1020Smax.romanov@nginx.com         }
529*1020Smax.romanov@nginx.com 
530*1020Smax.romanov@nginx.com         return res;
531*1020Smax.romanov@nginx.com     }
532*1020Smax.romanov@nginx.com 
533*1020Smax.romanov@nginx.com 
534*1020Smax.romanov@nginx.com     inline napi_ref
535*1020Smax.romanov@nginx.com     wrap(napi_value val, void *obj, napi_finalize fin_cb, void *hint = nullptr)
536*1020Smax.romanov@nginx.com     {
537*1020Smax.romanov@nginx.com         napi_ref     res;
538*1020Smax.romanov@nginx.com         napi_status  status;
539*1020Smax.romanov@nginx.com 
540*1020Smax.romanov@nginx.com         status = napi_wrap(env_, val, obj, fin_cb, hint, &res);
541*1020Smax.romanov@nginx.com         if (status != napi_ok) {
542*1020Smax.romanov@nginx.com             throw exception("Failed to wrap");
543*1020Smax.romanov@nginx.com         }
544*1020Smax.romanov@nginx.com 
545*1020Smax.romanov@nginx.com         return res;
546*1020Smax.romanov@nginx.com     }
547*1020Smax.romanov@nginx.com 
548*1020Smax.romanov@nginx.com 
549*1020Smax.romanov@nginx.com     inline
550*1020Smax.romanov@nginx.com     operator napi_env()
551*1020Smax.romanov@nginx.com     {
552*1020Smax.romanov@nginx.com         return env_;
553*1020Smax.romanov@nginx.com     }
554*1020Smax.romanov@nginx.com 
555*1020Smax.romanov@nginx.com 
556*1020Smax.romanov@nginx.com     napi_env env()
557*1020Smax.romanov@nginx.com     {
558*1020Smax.romanov@nginx.com         return env_;
559*1020Smax.romanov@nginx.com     }
560*1020Smax.romanov@nginx.com 
561*1020Smax.romanov@nginx.com private:
562*1020Smax.romanov@nginx.com     napi_env  env_;
563*1020Smax.romanov@nginx.com };
564*1020Smax.romanov@nginx.com 
565*1020Smax.romanov@nginx.com 
566*1020Smax.romanov@nginx.com struct nxt_handle_scope : public nxt_napi {
567*1020Smax.romanov@nginx.com     nxt_handle_scope(napi_env env) : nxt_napi(env)
568*1020Smax.romanov@nginx.com     {
569*1020Smax.romanov@nginx.com         napi_status  status;
570*1020Smax.romanov@nginx.com 
571*1020Smax.romanov@nginx.com         status = napi_open_handle_scope(env, &scope_);
572*1020Smax.romanov@nginx.com         if (status != napi_ok) {
573*1020Smax.romanov@nginx.com             throw exception("Failed to open handle scope");
574*1020Smax.romanov@nginx.com         }
575*1020Smax.romanov@nginx.com     }
576*1020Smax.romanov@nginx.com 
577*1020Smax.romanov@nginx.com     ~nxt_handle_scope()
578*1020Smax.romanov@nginx.com     {
579*1020Smax.romanov@nginx.com         napi_status  status;
580*1020Smax.romanov@nginx.com 
581*1020Smax.romanov@nginx.com         status = napi_close_handle_scope(env(), scope_);
582*1020Smax.romanov@nginx.com         if (status != napi_ok) {
583*1020Smax.romanov@nginx.com             throw_error("Failed to close handle scope");
584*1020Smax.romanov@nginx.com         }
585*1020Smax.romanov@nginx.com     }
586*1020Smax.romanov@nginx.com 
587*1020Smax.romanov@nginx.com private:
588*1020Smax.romanov@nginx.com     napi_handle_scope  scope_;
589*1020Smax.romanov@nginx.com };
590*1020Smax.romanov@nginx.com 
591*1020Smax.romanov@nginx.com 
592*1020Smax.romanov@nginx.com struct nxt_async_context : public nxt_napi {
593*1020Smax.romanov@nginx.com     nxt_async_context(napi_env env, const char *name) :
594*1020Smax.romanov@nginx.com         nxt_napi(env)
595*1020Smax.romanov@nginx.com     {
596*1020Smax.romanov@nginx.com         napi_value   name_val;
597*1020Smax.romanov@nginx.com         napi_status  status;
598*1020Smax.romanov@nginx.com 
599*1020Smax.romanov@nginx.com         name_val = create_string_latin1(name, NAPI_AUTO_LENGTH);
600*1020Smax.romanov@nginx.com 
601*1020Smax.romanov@nginx.com         status = napi_async_init(env, NULL, name_val, &context_);
602*1020Smax.romanov@nginx.com         if (status != napi_ok) {
603*1020Smax.romanov@nginx.com             throw exception("Failed to init async object");
604*1020Smax.romanov@nginx.com         }
605*1020Smax.romanov@nginx.com     }
606*1020Smax.romanov@nginx.com 
607*1020Smax.romanov@nginx.com     operator napi_async_context() {
608*1020Smax.romanov@nginx.com         return context_;
609*1020Smax.romanov@nginx.com     }
610*1020Smax.romanov@nginx.com 
611*1020Smax.romanov@nginx.com     ~nxt_async_context()
612*1020Smax.romanov@nginx.com     {
613*1020Smax.romanov@nginx.com         napi_status  status;
614*1020Smax.romanov@nginx.com 
615*1020Smax.romanov@nginx.com         status = napi_async_destroy(env(), context_);
616*1020Smax.romanov@nginx.com         if (status != napi_ok) {
617*1020Smax.romanov@nginx.com             throw_error("Failed to destroy async object");
618*1020Smax.romanov@nginx.com         }
619*1020Smax.romanov@nginx.com     }
620*1020Smax.romanov@nginx.com 
621*1020Smax.romanov@nginx.com private:
622*1020Smax.romanov@nginx.com     napi_async_context  context_;
623*1020Smax.romanov@nginx.com };
624*1020Smax.romanov@nginx.com 
625*1020Smax.romanov@nginx.com 
626*1020Smax.romanov@nginx.com struct nxt_callback_scope : public nxt_napi {
627*1020Smax.romanov@nginx.com     nxt_callback_scope(nxt_async_context& ctx) :
628*1020Smax.romanov@nginx.com         nxt_napi(ctx.env())
629*1020Smax.romanov@nginx.com     {
630*1020Smax.romanov@nginx.com         napi_value   resource;
631*1020Smax.romanov@nginx.com         napi_status  status;
632*1020Smax.romanov@nginx.com 
633*1020Smax.romanov@nginx.com         resource = create_object();
634*1020Smax.romanov@nginx.com 
635*1020Smax.romanov@nginx.com         status = napi_open_callback_scope(env(), resource, ctx, &scope_);
636*1020Smax.romanov@nginx.com         if (status != napi_ok) {
637*1020Smax.romanov@nginx.com             throw exception("Failed to open callback scope");
638*1020Smax.romanov@nginx.com         }
639*1020Smax.romanov@nginx.com     }
640*1020Smax.romanov@nginx.com 
641*1020Smax.romanov@nginx.com     ~nxt_callback_scope()
642*1020Smax.romanov@nginx.com     {
643*1020Smax.romanov@nginx.com         napi_status  status;
644*1020Smax.romanov@nginx.com 
645*1020Smax.romanov@nginx.com         status = napi_close_callback_scope(env(), scope_);
646*1020Smax.romanov@nginx.com         if (status != napi_ok) {
647*1020Smax.romanov@nginx.com             throw_error("Failed to close callback scope");
648*1020Smax.romanov@nginx.com         }
649*1020Smax.romanov@nginx.com     }
650*1020Smax.romanov@nginx.com 
651*1020Smax.romanov@nginx.com private:
652*1020Smax.romanov@nginx.com     napi_callback_scope  scope_;
653*1020Smax.romanov@nginx.com };
654*1020Smax.romanov@nginx.com 
655*1020Smax.romanov@nginx.com 
656*1020Smax.romanov@nginx.com #endif /* _NXT_NODEJS_NAPI_H_INCLUDED_ */
657