11020Smax.romanov@nginx.com 21020Smax.romanov@nginx.com /* 31020Smax.romanov@nginx.com * Copyright (C) NGINX, Inc. 41020Smax.romanov@nginx.com */ 51020Smax.romanov@nginx.com 61020Smax.romanov@nginx.com #ifndef _NXT_NODEJS_NAPI_H_INCLUDED_ 71020Smax.romanov@nginx.com #define _NXT_NODEJS_NAPI_H_INCLUDED_ 81020Smax.romanov@nginx.com 91020Smax.romanov@nginx.com #include <node_api.h> 101020Smax.romanov@nginx.com 111020Smax.romanov@nginx.com 121020Smax.romanov@nginx.com #ifdef __cplusplus 131020Smax.romanov@nginx.com extern "C" { 141020Smax.romanov@nginx.com #endif 151020Smax.romanov@nginx.com 161020Smax.romanov@nginx.com #include "version.h" 171020Smax.romanov@nginx.com #include <nxt_unit.h> 181020Smax.romanov@nginx.com 191020Smax.romanov@nginx.com #if NXT_VERNUM != NXT_NODE_VERNUM 201020Smax.romanov@nginx.com #error "libunit version mismatch." 211020Smax.romanov@nginx.com #endif 221020Smax.romanov@nginx.com 231020Smax.romanov@nginx.com #include <nxt_unit_response.h> 241020Smax.romanov@nginx.com #include <nxt_unit_request.h> 251020Smax.romanov@nginx.com 261020Smax.romanov@nginx.com 271020Smax.romanov@nginx.com #ifdef __cplusplus 281020Smax.romanov@nginx.com } /* extern "C" */ 291020Smax.romanov@nginx.com #endif 301020Smax.romanov@nginx.com 311020Smax.romanov@nginx.com 321020Smax.romanov@nginx.com struct nxt_napi { 331020Smax.romanov@nginx.com 341020Smax.romanov@nginx.com struct exception { exceptionnxt_napi::exception351020Smax.romanov@nginx.com exception(const char *s) : str(s) { } 361020Smax.romanov@nginx.com 371020Smax.romanov@nginx.com const char *str; 381020Smax.romanov@nginx.com }; 391020Smax.romanov@nginx.com 401020Smax.romanov@nginx.com nxt_napinxt_napi411020Smax.romanov@nginx.com nxt_napi(napi_env env) : env_(env) { } 421020Smax.romanov@nginx.com 431020Smax.romanov@nginx.com 441020Smax.romanov@nginx.com inline napi_value coerce_to_stringnxt_napi451020Smax.romanov@nginx.com coerce_to_string(napi_value val) 461020Smax.romanov@nginx.com { 471020Smax.romanov@nginx.com napi_value res; 481020Smax.romanov@nginx.com napi_status status; 491020Smax.romanov@nginx.com 501020Smax.romanov@nginx.com status = napi_coerce_to_string(env_, val, &res); 511020Smax.romanov@nginx.com if (status != napi_ok) { 521020Smax.romanov@nginx.com throw exception("Failed to coerce to string"); 531020Smax.romanov@nginx.com } 541020Smax.romanov@nginx.com 551020Smax.romanov@nginx.com return res; 561020Smax.romanov@nginx.com } 571020Smax.romanov@nginx.com 581020Smax.romanov@nginx.com 591020Smax.romanov@nginx.com inline napi_value create_buffernxt_napi601020Smax.romanov@nginx.com create_buffer(size_t size, void **data) 611020Smax.romanov@nginx.com { 621020Smax.romanov@nginx.com napi_value res; 631020Smax.romanov@nginx.com napi_status status; 641020Smax.romanov@nginx.com 651020Smax.romanov@nginx.com status = napi_create_buffer(env_, size, data, &res); 661020Smax.romanov@nginx.com if (status != napi_ok) { 671020Smax.romanov@nginx.com throw exception("Failed to create buffer"); 681020Smax.romanov@nginx.com } 691020Smax.romanov@nginx.com 701020Smax.romanov@nginx.com return res; 711020Smax.romanov@nginx.com } 721020Smax.romanov@nginx.com 731020Smax.romanov@nginx.com 741020Smax.romanov@nginx.com inline napi_value create_functionnxt_napi751020Smax.romanov@nginx.com create_function(const char *name, size_t len, napi_callback cb, void *data) 761020Smax.romanov@nginx.com { 771020Smax.romanov@nginx.com napi_value res; 781020Smax.romanov@nginx.com napi_status status; 791020Smax.romanov@nginx.com 801020Smax.romanov@nginx.com status = napi_create_function(env_, name, len, cb, data, &res); 811020Smax.romanov@nginx.com if (status != napi_ok) { 821020Smax.romanov@nginx.com throw exception("Failed to create function"); 831020Smax.romanov@nginx.com } 841020Smax.romanov@nginx.com 851020Smax.romanov@nginx.com return res; 861020Smax.romanov@nginx.com } 871020Smax.romanov@nginx.com 881020Smax.romanov@nginx.com 891020Smax.romanov@nginx.com inline napi_value create_functionnxt_napi901020Smax.romanov@nginx.com create_function(napi_callback cb) 911020Smax.romanov@nginx.com { 921020Smax.romanov@nginx.com return create_function(NULL, 0, cb, NULL); 931020Smax.romanov@nginx.com } 941020Smax.romanov@nginx.com 951020Smax.romanov@nginx.com 961020Smax.romanov@nginx.com inline napi_value create_objectnxt_napi971020Smax.romanov@nginx.com create_object() 981020Smax.romanov@nginx.com { 991020Smax.romanov@nginx.com napi_value res; 1001020Smax.romanov@nginx.com napi_status status; 1011020Smax.romanov@nginx.com 1021020Smax.romanov@nginx.com status = napi_create_object(env_, &res); 1031020Smax.romanov@nginx.com if (status != napi_ok) { 1041020Smax.romanov@nginx.com throw exception("Failed to create object"); 1051020Smax.romanov@nginx.com } 1061020Smax.romanov@nginx.com 1071020Smax.romanov@nginx.com return res; 1081020Smax.romanov@nginx.com } 1091020Smax.romanov@nginx.com 1101020Smax.romanov@nginx.com 1111020Smax.romanov@nginx.com inline napi_ref 1121020Smax.romanov@nginx.com create_reference(napi_value val, int ref_count = 1) 1131020Smax.romanov@nginx.com { 1141020Smax.romanov@nginx.com napi_ref res; 1151020Smax.romanov@nginx.com napi_status status; 1161020Smax.romanov@nginx.com 1171020Smax.romanov@nginx.com status = napi_create_reference(env_, val, ref_count, &res); 1181020Smax.romanov@nginx.com if (status != napi_ok) { 1191020Smax.romanov@nginx.com throw exception("Failed to create reference"); 1201020Smax.romanov@nginx.com } 1211020Smax.romanov@nginx.com 1221020Smax.romanov@nginx.com return res; 1231020Smax.romanov@nginx.com } 1241020Smax.romanov@nginx.com 1251020Smax.romanov@nginx.com 1261020Smax.romanov@nginx.com inline napi_value create_string_latin1nxt_napi1271020Smax.romanov@nginx.com create_string_latin1(const char *str, size_t len) 1281020Smax.romanov@nginx.com { 1291020Smax.romanov@nginx.com napi_value res; 1301020Smax.romanov@nginx.com napi_status status; 1311020Smax.romanov@nginx.com 1321020Smax.romanov@nginx.com status = napi_create_string_latin1(env_, str, len, &res); 1331020Smax.romanov@nginx.com if (status != napi_ok) { 1341020Smax.romanov@nginx.com throw exception("Failed to create latin1 string"); 1351020Smax.romanov@nginx.com } 1361020Smax.romanov@nginx.com 1371020Smax.romanov@nginx.com return res; 1381020Smax.romanov@nginx.com } 1391020Smax.romanov@nginx.com 1401020Smax.romanov@nginx.com 1411020Smax.romanov@nginx.com inline napi_value create_string_latin1nxt_napi1421020Smax.romanov@nginx.com create_string_latin1(nxt_unit_sptr_t &str, size_t len) 1431020Smax.romanov@nginx.com { 1441020Smax.romanov@nginx.com const char *p; 1451020Smax.romanov@nginx.com 1461020Smax.romanov@nginx.com p = (const char *) nxt_unit_sptr_get(&str); 1471020Smax.romanov@nginx.com 1481020Smax.romanov@nginx.com return create_string_latin1(p, len); 1491020Smax.romanov@nginx.com } 1501020Smax.romanov@nginx.com 1511020Smax.romanov@nginx.com 1521020Smax.romanov@nginx.com inline napi_value define_classnxt_napi1531020Smax.romanov@nginx.com define_class(const char *name, napi_callback ctor, size_t prop_count, 1541020Smax.romanov@nginx.com const napi_property_descriptor* props) 1551020Smax.romanov@nginx.com { 1561020Smax.romanov@nginx.com napi_value res; 1571020Smax.romanov@nginx.com napi_status status; 1581020Smax.romanov@nginx.com 1591020Smax.romanov@nginx.com status = napi_define_class(env_, name, NAPI_AUTO_LENGTH, ctor, nullptr, 1601020Smax.romanov@nginx.com prop_count, props, &res); 1611020Smax.romanov@nginx.com if (status != napi_ok) { 1621020Smax.romanov@nginx.com throw exception("Failed to define class"); 1631020Smax.romanov@nginx.com } 1641020Smax.romanov@nginx.com 1651020Smax.romanov@nginx.com return res; 1661020Smax.romanov@nginx.com } 1671020Smax.romanov@nginx.com 1681020Smax.romanov@nginx.com 1691020Smax.romanov@nginx.com inline void delete_referencenxt_napi1701020Smax.romanov@nginx.com delete_reference(napi_ref ref) 1711020Smax.romanov@nginx.com { 1721020Smax.romanov@nginx.com napi_delete_reference(env_, ref); 1731020Smax.romanov@nginx.com } 1741020Smax.romanov@nginx.com 1751020Smax.romanov@nginx.com 1761020Smax.romanov@nginx.com inline uint32_t get_array_lengthnxt_napi1771020Smax.romanov@nginx.com get_array_length(napi_value val) 1781020Smax.romanov@nginx.com { 1791020Smax.romanov@nginx.com uint32_t res; 1801020Smax.romanov@nginx.com napi_status status; 1811020Smax.romanov@nginx.com 1821020Smax.romanov@nginx.com status = napi_get_array_length(env_, val, &res); 1831020Smax.romanov@nginx.com if (status != napi_ok) { 1841020Smax.romanov@nginx.com throw exception("Failed to get array length"); 1851020Smax.romanov@nginx.com } 1861020Smax.romanov@nginx.com 1871020Smax.romanov@nginx.com return res; 1881020Smax.romanov@nginx.com } 1891020Smax.romanov@nginx.com 1901020Smax.romanov@nginx.com 191*1132Smax.romanov@nginx.com inline void * get_buffer_infonxt_napi192*1132Smax.romanov@nginx.com get_buffer_info(napi_value val, size_t &size) 193*1132Smax.romanov@nginx.com { 194*1132Smax.romanov@nginx.com void *res; 195*1132Smax.romanov@nginx.com napi_status status; 196*1132Smax.romanov@nginx.com 197*1132Smax.romanov@nginx.com status = napi_get_buffer_info(env_, val, &res, &size); 198*1132Smax.romanov@nginx.com if (status != napi_ok) { 199*1132Smax.romanov@nginx.com throw exception("Failed to get buffer info"); 200*1132Smax.romanov@nginx.com } 201*1132Smax.romanov@nginx.com 202*1132Smax.romanov@nginx.com return res; 203*1132Smax.romanov@nginx.com } 204*1132Smax.romanov@nginx.com 205*1132Smax.romanov@nginx.com 2061020Smax.romanov@nginx.com inline napi_value get_cb_infonxt_napi2071020Smax.romanov@nginx.com get_cb_info(napi_callback_info info, size_t &argc, napi_value *argv) 2081020Smax.romanov@nginx.com { 2091020Smax.romanov@nginx.com napi_value res; 2101020Smax.romanov@nginx.com napi_status status; 2111020Smax.romanov@nginx.com 2121020Smax.romanov@nginx.com status = napi_get_cb_info(env_, info, &argc, argv, &res, nullptr); 2131020Smax.romanov@nginx.com if (status != napi_ok) { 2141020Smax.romanov@nginx.com throw exception("Failed to get arguments from js"); 2151020Smax.romanov@nginx.com } 2161020Smax.romanov@nginx.com 2171020Smax.romanov@nginx.com return res; 2181020Smax.romanov@nginx.com } 2191020Smax.romanov@nginx.com 2201020Smax.romanov@nginx.com 2211020Smax.romanov@nginx.com inline napi_value get_cb_infonxt_napi2221020Smax.romanov@nginx.com get_cb_info(napi_callback_info info) 2231020Smax.romanov@nginx.com { 2241020Smax.romanov@nginx.com napi_value res; 2251020Smax.romanov@nginx.com napi_status status; 2261020Smax.romanov@nginx.com 2271020Smax.romanov@nginx.com status = napi_get_cb_info(env_, info, nullptr, nullptr, &res, nullptr); 2281020Smax.romanov@nginx.com if (status != napi_ok) { 2291020Smax.romanov@nginx.com throw exception("Failed to get arguments from js"); 2301020Smax.romanov@nginx.com } 2311020Smax.romanov@nginx.com 2321020Smax.romanov@nginx.com return res; 2331020Smax.romanov@nginx.com } 2341020Smax.romanov@nginx.com 2351020Smax.romanov@nginx.com 2361020Smax.romanov@nginx.com inline napi_value get_cb_infonxt_napi237*1132Smax.romanov@nginx.com get_cb_info(napi_callback_info info, napi_value &arg) 238*1132Smax.romanov@nginx.com { 239*1132Smax.romanov@nginx.com size_t argc; 240*1132Smax.romanov@nginx.com napi_value res; 241*1132Smax.romanov@nginx.com 242*1132Smax.romanov@nginx.com argc = 1; 243*1132Smax.romanov@nginx.com res = get_cb_info(info, argc, &arg); 244*1132Smax.romanov@nginx.com 245*1132Smax.romanov@nginx.com if (argc != 1) { 246*1132Smax.romanov@nginx.com throw exception("Wrong args count. Expected 1"); 247*1132Smax.romanov@nginx.com } 248*1132Smax.romanov@nginx.com 249*1132Smax.romanov@nginx.com return res; 250*1132Smax.romanov@nginx.com } 251*1132Smax.romanov@nginx.com 252*1132Smax.romanov@nginx.com 253*1132Smax.romanov@nginx.com inline napi_value get_elementnxt_napi2541020Smax.romanov@nginx.com get_element(napi_value obj, uint32_t i) 2551020Smax.romanov@nginx.com { 2561020Smax.romanov@nginx.com napi_value res; 2571020Smax.romanov@nginx.com napi_status status; 2581020Smax.romanov@nginx.com 2591020Smax.romanov@nginx.com status = napi_get_element(env_, obj, i, &res); 2601020Smax.romanov@nginx.com if (status != napi_ok) { 2611020Smax.romanov@nginx.com throw exception("Failed to get element"); 2621020Smax.romanov@nginx.com } 2631020Smax.romanov@nginx.com 2641020Smax.romanov@nginx.com return res; 2651020Smax.romanov@nginx.com } 2661020Smax.romanov@nginx.com 2671020Smax.romanov@nginx.com 2681020Smax.romanov@nginx.com inline napi_value get_named_propertynxt_napi2691020Smax.romanov@nginx.com get_named_property(napi_value obj, const char *name) 2701020Smax.romanov@nginx.com { 2711020Smax.romanov@nginx.com napi_value res; 2721020Smax.romanov@nginx.com napi_status status; 2731020Smax.romanov@nginx.com 2741020Smax.romanov@nginx.com status = napi_get_named_property(env_, obj, name, &res); 2751020Smax.romanov@nginx.com if (status != napi_ok) { 2761020Smax.romanov@nginx.com throw exception("Failed to get named property"); 2771020Smax.romanov@nginx.com } 2781020Smax.romanov@nginx.com 2791020Smax.romanov@nginx.com return res; 2801020Smax.romanov@nginx.com } 2811020Smax.romanov@nginx.com 2821020Smax.romanov@nginx.com 2831020Smax.romanov@nginx.com inline napi_value get_new_targetnxt_napi2841020Smax.romanov@nginx.com get_new_target(napi_callback_info info) 2851020Smax.romanov@nginx.com { 2861020Smax.romanov@nginx.com napi_value res; 2871020Smax.romanov@nginx.com napi_status status; 2881020Smax.romanov@nginx.com 2891020Smax.romanov@nginx.com status = napi_get_new_target(env_, info, &res); 2901020Smax.romanov@nginx.com if (status != napi_ok) { 2911020Smax.romanov@nginx.com throw exception("Failed to get new target"); 2921020Smax.romanov@nginx.com } 2931020Smax.romanov@nginx.com 2941020Smax.romanov@nginx.com return res; 2951020Smax.romanov@nginx.com } 2961020Smax.romanov@nginx.com 2971020Smax.romanov@nginx.com 2981020Smax.romanov@nginx.com inline napi_value get_propertynxt_napi2991020Smax.romanov@nginx.com get_property(napi_value val, napi_value key) 3001020Smax.romanov@nginx.com { 3011020Smax.romanov@nginx.com napi_value res; 3021020Smax.romanov@nginx.com napi_status status; 3031020Smax.romanov@nginx.com 3041020Smax.romanov@nginx.com status = napi_get_property(env_, val, key, &res); 3051020Smax.romanov@nginx.com if (status != napi_ok) { 3061020Smax.romanov@nginx.com throw exception("Failed to get property"); 3071020Smax.romanov@nginx.com } 3081020Smax.romanov@nginx.com 3091020Smax.romanov@nginx.com return res; 3101020Smax.romanov@nginx.com } 3111020Smax.romanov@nginx.com 3121020Smax.romanov@nginx.com 3131020Smax.romanov@nginx.com inline napi_value get_property_namesnxt_napi3141020Smax.romanov@nginx.com get_property_names(napi_value val) 3151020Smax.romanov@nginx.com { 3161020Smax.romanov@nginx.com napi_value res; 3171020Smax.romanov@nginx.com napi_status status; 3181020Smax.romanov@nginx.com 3191020Smax.romanov@nginx.com status = napi_get_property_names(env_, val, &res); 3201020Smax.romanov@nginx.com if (status != napi_ok) { 3211020Smax.romanov@nginx.com throw exception("Failed to get property names"); 3221020Smax.romanov@nginx.com } 3231020Smax.romanov@nginx.com 3241020Smax.romanov@nginx.com return res; 3251020Smax.romanov@nginx.com } 3261020Smax.romanov@nginx.com 3271020Smax.romanov@nginx.com 3281020Smax.romanov@nginx.com inline napi_value get_reference_valuenxt_napi3291020Smax.romanov@nginx.com get_reference_value(napi_ref ref) 3301020Smax.romanov@nginx.com { 3311020Smax.romanov@nginx.com napi_value res; 3321020Smax.romanov@nginx.com napi_status status; 3331020Smax.romanov@nginx.com 3341020Smax.romanov@nginx.com status = napi_get_reference_value(env_, ref, &res); 3351020Smax.romanov@nginx.com if (status != napi_ok) { 3361020Smax.romanov@nginx.com throw exception("Failed to get reference value"); 3371020Smax.romanov@nginx.com } 3381020Smax.romanov@nginx.com 3391020Smax.romanov@nginx.com return res; 3401020Smax.romanov@nginx.com } 3411020Smax.romanov@nginx.com 3421020Smax.romanov@nginx.com 3431020Smax.romanov@nginx.com inline nxt_unit_request_info_t * get_request_infonxt_napi3441020Smax.romanov@nginx.com get_request_info(napi_value obj) 3451020Smax.romanov@nginx.com { 346*1132Smax.romanov@nginx.com return (nxt_unit_request_info_t *) unwrap(obj); 347*1132Smax.romanov@nginx.com } 348*1132Smax.romanov@nginx.com 349*1132Smax.romanov@nginx.com 350*1132Smax.romanov@nginx.com inline uint32_t get_value_boolnxt_napi351*1132Smax.romanov@nginx.com get_value_bool(napi_value obj) 352*1132Smax.romanov@nginx.com { 353*1132Smax.romanov@nginx.com bool res; 3541020Smax.romanov@nginx.com napi_status status; 3551020Smax.romanov@nginx.com 356*1132Smax.romanov@nginx.com status = napi_get_value_bool(env_, obj, &res); 3571020Smax.romanov@nginx.com if (status != napi_ok) { 358*1132Smax.romanov@nginx.com throw exception("Failed to get bool"); 3591020Smax.romanov@nginx.com } 3601020Smax.romanov@nginx.com 361*1132Smax.romanov@nginx.com return res; 3621020Smax.romanov@nginx.com } 3631020Smax.romanov@nginx.com 3641020Smax.romanov@nginx.com 3651020Smax.romanov@nginx.com inline size_t get_value_string_latin1nxt_napi3661020Smax.romanov@nginx.com get_value_string_latin1(napi_value val, char *buf, size_t bufsize) 3671020Smax.romanov@nginx.com { 3681020Smax.romanov@nginx.com size_t res; 3691020Smax.romanov@nginx.com napi_status status; 3701020Smax.romanov@nginx.com 3711020Smax.romanov@nginx.com status = napi_get_value_string_latin1(env_, val, buf, bufsize, &res); 3721020Smax.romanov@nginx.com if (status != napi_ok) { 3731020Smax.romanov@nginx.com throw exception("Failed to get string latin1"); 3741020Smax.romanov@nginx.com } 3751020Smax.romanov@nginx.com 3761020Smax.romanov@nginx.com return res; 3771020Smax.romanov@nginx.com } 3781020Smax.romanov@nginx.com 3791020Smax.romanov@nginx.com 3801020Smax.romanov@nginx.com inline uint32_t get_value_uint32nxt_napi3811020Smax.romanov@nginx.com get_value_uint32(napi_value obj) 3821020Smax.romanov@nginx.com { 3831020Smax.romanov@nginx.com uint32_t res; 3841020Smax.romanov@nginx.com napi_status status; 3851020Smax.romanov@nginx.com 3861020Smax.romanov@nginx.com status = napi_get_value_uint32(env_, obj, &res); 3871020Smax.romanov@nginx.com if (status != napi_ok) { 3881020Smax.romanov@nginx.com throw exception("Failed to get uint32_t"); 3891020Smax.romanov@nginx.com } 3901020Smax.romanov@nginx.com 3911020Smax.romanov@nginx.com return res; 3921020Smax.romanov@nginx.com } 3931020Smax.romanov@nginx.com 3941020Smax.romanov@nginx.com 395*1132Smax.romanov@nginx.com inline size_t get_value_string_utf8nxt_napi396*1132Smax.romanov@nginx.com get_value_string_utf8(napi_value val, char *buf, size_t bufsize) 397*1132Smax.romanov@nginx.com { 398*1132Smax.romanov@nginx.com size_t res; 399*1132Smax.romanov@nginx.com napi_status status; 400*1132Smax.romanov@nginx.com 401*1132Smax.romanov@nginx.com status = napi_get_value_string_utf8(env_, val, buf, bufsize, &res); 402*1132Smax.romanov@nginx.com if (status != napi_ok) { 403*1132Smax.romanov@nginx.com throw exception("Failed to get string utf8"); 404*1132Smax.romanov@nginx.com } 405*1132Smax.romanov@nginx.com 406*1132Smax.romanov@nginx.com return res; 407*1132Smax.romanov@nginx.com } 408*1132Smax.romanov@nginx.com 409*1132Smax.romanov@nginx.com 4101020Smax.romanov@nginx.com inline bool is_arraynxt_napi4111020Smax.romanov@nginx.com is_array(napi_value val) 4121020Smax.romanov@nginx.com { 4131020Smax.romanov@nginx.com bool res; 4141020Smax.romanov@nginx.com napi_status status; 4151020Smax.romanov@nginx.com 4161020Smax.romanov@nginx.com status = napi_is_array(env_, val, &res); 4171020Smax.romanov@nginx.com if (status != napi_ok) { 4181020Smax.romanov@nginx.com throw exception("Failed to confirm value is array"); 4191020Smax.romanov@nginx.com } 4201020Smax.romanov@nginx.com 4211020Smax.romanov@nginx.com return res; 4221020Smax.romanov@nginx.com } 4231020Smax.romanov@nginx.com 4241020Smax.romanov@nginx.com 425*1132Smax.romanov@nginx.com inline bool is_buffernxt_napi426*1132Smax.romanov@nginx.com is_buffer(napi_value val) 427*1132Smax.romanov@nginx.com { 428*1132Smax.romanov@nginx.com bool res; 429*1132Smax.romanov@nginx.com napi_status status; 430*1132Smax.romanov@nginx.com 431*1132Smax.romanov@nginx.com status = napi_is_buffer(env_, val, &res); 432*1132Smax.romanov@nginx.com if (status != napi_ok) { 433*1132Smax.romanov@nginx.com throw exception("Failed to confirm value is buffer"); 434*1132Smax.romanov@nginx.com } 435*1132Smax.romanov@nginx.com 436*1132Smax.romanov@nginx.com return res; 437*1132Smax.romanov@nginx.com } 438*1132Smax.romanov@nginx.com 439*1132Smax.romanov@nginx.com 4401020Smax.romanov@nginx.com inline napi_value make_callbacknxt_napi4411020Smax.romanov@nginx.com make_callback(napi_async_context ctx, napi_value val, napi_value func, 4421020Smax.romanov@nginx.com int argc, const napi_value *argv) 4431020Smax.romanov@nginx.com { 4441020Smax.romanov@nginx.com napi_value res, ex; 4451020Smax.romanov@nginx.com napi_status status; 4461020Smax.romanov@nginx.com 4471020Smax.romanov@nginx.com status = napi_make_callback(env_, ctx, val, func, argc, argv, &res); 4481020Smax.romanov@nginx.com if (status != napi_ok) { 4491020Smax.romanov@nginx.com if (status != napi_pending_exception) { 4501020Smax.romanov@nginx.com throw exception("Failed to make callback"); 4511020Smax.romanov@nginx.com } 4521020Smax.romanov@nginx.com 4531020Smax.romanov@nginx.com status = napi_get_and_clear_last_exception(env_, &ex); 4541020Smax.romanov@nginx.com if (status != napi_ok) { 4551020Smax.romanov@nginx.com throw exception("Failed to get and clear last exception"); 4561020Smax.romanov@nginx.com } 4571020Smax.romanov@nginx.com 4581020Smax.romanov@nginx.com /* Logging a description of the error and call stack. */ 4591020Smax.romanov@nginx.com status = napi_fatal_exception(env_, ex); 4601020Smax.romanov@nginx.com if (status != napi_ok) { 4611020Smax.romanov@nginx.com throw exception("Failed napi_fatal_exception()"); 4621020Smax.romanov@nginx.com } 4631020Smax.romanov@nginx.com } 4641020Smax.romanov@nginx.com 4651020Smax.romanov@nginx.com return res; 4661020Smax.romanov@nginx.com } 4671020Smax.romanov@nginx.com 4681020Smax.romanov@nginx.com 4691020Smax.romanov@nginx.com inline napi_value make_callbacknxt_napi470*1132Smax.romanov@nginx.com make_callback(napi_async_context ctx, napi_value val, napi_value func) 471*1132Smax.romanov@nginx.com { 472*1132Smax.romanov@nginx.com return make_callback(ctx, val, func, 0, NULL); 473*1132Smax.romanov@nginx.com } 474*1132Smax.romanov@nginx.com 475*1132Smax.romanov@nginx.com 476*1132Smax.romanov@nginx.com inline napi_value make_callbacknxt_napi477*1132Smax.romanov@nginx.com make_callback(napi_async_context ctx, napi_value val, napi_value func, 478*1132Smax.romanov@nginx.com napi_value arg1) 479*1132Smax.romanov@nginx.com { 480*1132Smax.romanov@nginx.com return make_callback(ctx, val, func, 1, &arg1); 481*1132Smax.romanov@nginx.com } 482*1132Smax.romanov@nginx.com 483*1132Smax.romanov@nginx.com 484*1132Smax.romanov@nginx.com inline napi_value make_callbacknxt_napi485*1132Smax.romanov@nginx.com make_callback(napi_async_context ctx, napi_value val, napi_value func, 486*1132Smax.romanov@nginx.com napi_value arg1, napi_value arg2) 487*1132Smax.romanov@nginx.com { 488*1132Smax.romanov@nginx.com napi_value args[2] = { arg1, arg2 }; 489*1132Smax.romanov@nginx.com 490*1132Smax.romanov@nginx.com return make_callback(ctx, val, func, 2, args); 491*1132Smax.romanov@nginx.com } 492*1132Smax.romanov@nginx.com 493*1132Smax.romanov@nginx.com 494*1132Smax.romanov@nginx.com inline napi_value make_callbacknxt_napi495*1132Smax.romanov@nginx.com make_callback(napi_async_context ctx, napi_value val, napi_value func, 496*1132Smax.romanov@nginx.com napi_value arg1, napi_value arg2, napi_value arg3) 497*1132Smax.romanov@nginx.com { 498*1132Smax.romanov@nginx.com napi_value args[3] = { arg1, arg2, arg3 }; 499*1132Smax.romanov@nginx.com 500*1132Smax.romanov@nginx.com return make_callback(ctx, val, func, 3, args); 501*1132Smax.romanov@nginx.com } 502*1132Smax.romanov@nginx.com 503*1132Smax.romanov@nginx.com 504*1132Smax.romanov@nginx.com inline napi_value new_instancenxt_napi5051020Smax.romanov@nginx.com new_instance(napi_value ctor) 5061020Smax.romanov@nginx.com { 5071020Smax.romanov@nginx.com napi_value res; 5081020Smax.romanov@nginx.com napi_status status; 5091020Smax.romanov@nginx.com 5101020Smax.romanov@nginx.com status = napi_new_instance(env_, ctor, 0, NULL, &res); 5111020Smax.romanov@nginx.com if (status != napi_ok) { 5121020Smax.romanov@nginx.com throw exception("Failed to create instance"); 5131020Smax.romanov@nginx.com } 5141020Smax.romanov@nginx.com 5151020Smax.romanov@nginx.com return res; 5161020Smax.romanov@nginx.com } 5171020Smax.romanov@nginx.com 5181020Smax.romanov@nginx.com 5191020Smax.romanov@nginx.com inline napi_value new_instancenxt_napi5201020Smax.romanov@nginx.com new_instance(napi_value ctor, napi_value param) 5211020Smax.romanov@nginx.com { 5221020Smax.romanov@nginx.com napi_value res; 5231020Smax.romanov@nginx.com napi_status status; 5241020Smax.romanov@nginx.com 5251020Smax.romanov@nginx.com status = napi_new_instance(env_, ctor, 1, ¶m, &res); 5261020Smax.romanov@nginx.com if (status != napi_ok) { 5271020Smax.romanov@nginx.com throw exception("Failed to create instance"); 5281020Smax.romanov@nginx.com } 5291020Smax.romanov@nginx.com 5301020Smax.romanov@nginx.com return res; 5311020Smax.romanov@nginx.com } 5321020Smax.romanov@nginx.com 5331020Smax.romanov@nginx.com 534*1132Smax.romanov@nginx.com inline napi_value new_instancenxt_napi535*1132Smax.romanov@nginx.com new_instance(napi_value ctor, napi_value param1, napi_value param2) 536*1132Smax.romanov@nginx.com { 537*1132Smax.romanov@nginx.com napi_value res; 538*1132Smax.romanov@nginx.com napi_status status; 539*1132Smax.romanov@nginx.com napi_value param[2] = { param1, param2 }; 540*1132Smax.romanov@nginx.com 541*1132Smax.romanov@nginx.com status = napi_new_instance(env_, ctor, 2, param, &res); 542*1132Smax.romanov@nginx.com if (status != napi_ok) { 543*1132Smax.romanov@nginx.com throw exception("Failed to create instance"); 544*1132Smax.romanov@nginx.com } 545*1132Smax.romanov@nginx.com 546*1132Smax.romanov@nginx.com return res; 547*1132Smax.romanov@nginx.com } 548*1132Smax.romanov@nginx.com 549*1132Smax.romanov@nginx.com 5501020Smax.romanov@nginx.com inline void set_elementnxt_napi5511020Smax.romanov@nginx.com set_element(napi_value obj, uint32_t i, napi_value val) 5521020Smax.romanov@nginx.com { 5531020Smax.romanov@nginx.com napi_status status; 5541020Smax.romanov@nginx.com 5551020Smax.romanov@nginx.com status = napi_set_element(env_, obj, i, val); 5561020Smax.romanov@nginx.com if (status != napi_ok) { 5571020Smax.romanov@nginx.com throw exception("Failed to set element"); 5581020Smax.romanov@nginx.com } 5591020Smax.romanov@nginx.com } 5601020Smax.romanov@nginx.com 5611020Smax.romanov@nginx.com 5621020Smax.romanov@nginx.com inline void set_named_propertynxt_napi5631020Smax.romanov@nginx.com set_named_property(napi_value obj, const char *name, napi_value val) 5641020Smax.romanov@nginx.com { 5651020Smax.romanov@nginx.com napi_status status; 5661020Smax.romanov@nginx.com 5671020Smax.romanov@nginx.com status = napi_set_named_property(env_, obj, name, val); 5681020Smax.romanov@nginx.com if (status != napi_ok) { 5691020Smax.romanov@nginx.com throw exception("Failed to set named property"); 5701020Smax.romanov@nginx.com } 5711020Smax.romanov@nginx.com } 5721020Smax.romanov@nginx.com 5731020Smax.romanov@nginx.com 5741020Smax.romanov@nginx.com inline void set_named_propertynxt_napi5751020Smax.romanov@nginx.com set_named_property(napi_value obj, const char *name, napi_callback cb) 5761020Smax.romanov@nginx.com { 5771020Smax.romanov@nginx.com set_named_property(obj, name, create_function(cb)); 5781020Smax.romanov@nginx.com } 5791020Smax.romanov@nginx.com 5801020Smax.romanov@nginx.com 5811020Smax.romanov@nginx.com inline napi_value set_named_propertynxt_napi5821020Smax.romanov@nginx.com set_named_property(napi_value obj, const char *name, nxt_unit_sptr_t &val, 5831020Smax.romanov@nginx.com size_t len) 5841020Smax.romanov@nginx.com { 5851020Smax.romanov@nginx.com napi_value str; 5861020Smax.romanov@nginx.com 5871020Smax.romanov@nginx.com str = create_string_latin1(val, len); 5881020Smax.romanov@nginx.com 5891020Smax.romanov@nginx.com set_named_property(obj, name, str); 5901020Smax.romanov@nginx.com 5911020Smax.romanov@nginx.com return str; 5921020Smax.romanov@nginx.com } 5931020Smax.romanov@nginx.com 5941020Smax.romanov@nginx.com 595*1132Smax.romanov@nginx.com template<typename T> 5961020Smax.romanov@nginx.com inline void set_named_propertynxt_napi597*1132Smax.romanov@nginx.com set_named_property(napi_value obj, const char *name, T val) 598*1132Smax.romanov@nginx.com { 599*1132Smax.romanov@nginx.com set_named_property(obj, name, create(val)); 600*1132Smax.romanov@nginx.com } 601*1132Smax.romanov@nginx.com 602*1132Smax.romanov@nginx.com 603*1132Smax.romanov@nginx.com inline napi_value createnxt_napi604*1132Smax.romanov@nginx.com create(int32_t val) 605*1132Smax.romanov@nginx.com { 606*1132Smax.romanov@nginx.com napi_value ptr; 607*1132Smax.romanov@nginx.com napi_status status; 608*1132Smax.romanov@nginx.com 609*1132Smax.romanov@nginx.com status = napi_create_int32(env_, val, &ptr); 610*1132Smax.romanov@nginx.com if (status != napi_ok) { 611*1132Smax.romanov@nginx.com throw exception("Failed to create int32"); 612*1132Smax.romanov@nginx.com } 613*1132Smax.romanov@nginx.com 614*1132Smax.romanov@nginx.com return ptr; 615*1132Smax.romanov@nginx.com } 616*1132Smax.romanov@nginx.com 617*1132Smax.romanov@nginx.com 618*1132Smax.romanov@nginx.com inline napi_value createnxt_napi619*1132Smax.romanov@nginx.com create(uint32_t val) 620*1132Smax.romanov@nginx.com { 621*1132Smax.romanov@nginx.com napi_value ptr; 622*1132Smax.romanov@nginx.com napi_status status; 623*1132Smax.romanov@nginx.com 624*1132Smax.romanov@nginx.com status = napi_create_uint32(env_, val, &ptr); 625*1132Smax.romanov@nginx.com if (status != napi_ok) { 626*1132Smax.romanov@nginx.com throw exception("Failed to create uint32"); 627*1132Smax.romanov@nginx.com } 628*1132Smax.romanov@nginx.com 629*1132Smax.romanov@nginx.com return ptr; 630*1132Smax.romanov@nginx.com } 631*1132Smax.romanov@nginx.com 632*1132Smax.romanov@nginx.com 633*1132Smax.romanov@nginx.com inline napi_value createnxt_napi634*1132Smax.romanov@nginx.com create(int64_t val) 6351020Smax.romanov@nginx.com { 6361020Smax.romanov@nginx.com napi_value ptr; 6371020Smax.romanov@nginx.com napi_status status; 6381020Smax.romanov@nginx.com 6391020Smax.romanov@nginx.com status = napi_create_int64(env_, val, &ptr); 6401020Smax.romanov@nginx.com if (status != napi_ok) { 6411020Smax.romanov@nginx.com throw exception("Failed to create int64"); 6421020Smax.romanov@nginx.com } 6431020Smax.romanov@nginx.com 644*1132Smax.romanov@nginx.com return ptr; 645*1132Smax.romanov@nginx.com } 646*1132Smax.romanov@nginx.com 647*1132Smax.romanov@nginx.com 648*1132Smax.romanov@nginx.com inline void remove_wrapnxt_napi649*1132Smax.romanov@nginx.com remove_wrap(napi_ref& ref) 650*1132Smax.romanov@nginx.com { 651*1132Smax.romanov@nginx.com if (ref != nullptr) { 652*1132Smax.romanov@nginx.com remove_wrap(get_reference_value(ref)); 653*1132Smax.romanov@nginx.com ref = nullptr; 654*1132Smax.romanov@nginx.com } 655*1132Smax.romanov@nginx.com } 656*1132Smax.romanov@nginx.com 657*1132Smax.romanov@nginx.com 658*1132Smax.romanov@nginx.com inline void * remove_wrapnxt_napi659*1132Smax.romanov@nginx.com remove_wrap(napi_value val) 660*1132Smax.romanov@nginx.com { 661*1132Smax.romanov@nginx.com void *res; 662*1132Smax.romanov@nginx.com napi_status status; 663*1132Smax.romanov@nginx.com 664*1132Smax.romanov@nginx.com status = napi_remove_wrap(env_, val, &res); 665*1132Smax.romanov@nginx.com if (status != napi_ok) { 666*1132Smax.romanov@nginx.com throw exception("Failed to remove_wrap"); 667*1132Smax.romanov@nginx.com } 668*1132Smax.romanov@nginx.com 669*1132Smax.romanov@nginx.com return res; 6701020Smax.romanov@nginx.com } 6711020Smax.romanov@nginx.com 6721020Smax.romanov@nginx.com 6731020Smax.romanov@nginx.com inline void throw_errornxt_napi6741020Smax.romanov@nginx.com throw_error(const char *str) 6751020Smax.romanov@nginx.com { 6761020Smax.romanov@nginx.com napi_throw_error(env_, NULL, str); 6771020Smax.romanov@nginx.com } 6781020Smax.romanov@nginx.com 6791020Smax.romanov@nginx.com 6801020Smax.romanov@nginx.com inline void throw_errornxt_napi6811020Smax.romanov@nginx.com throw_error(const exception &e) 6821020Smax.romanov@nginx.com { 6831020Smax.romanov@nginx.com napi_throw_error(env_, NULL, e.str); 6841020Smax.romanov@nginx.com } 6851020Smax.romanov@nginx.com 6861020Smax.romanov@nginx.com 6871020Smax.romanov@nginx.com inline napi_valuetype type_ofnxt_napi6881020Smax.romanov@nginx.com type_of(napi_value val) 6891020Smax.romanov@nginx.com { 6901020Smax.romanov@nginx.com napi_status status; 6911020Smax.romanov@nginx.com napi_valuetype res; 6921020Smax.romanov@nginx.com 6931020Smax.romanov@nginx.com status = napi_typeof(env_, val, &res); 6941020Smax.romanov@nginx.com if (status != napi_ok) { 6951020Smax.romanov@nginx.com throw exception("Failed to get typeof"); 6961020Smax.romanov@nginx.com } 6971020Smax.romanov@nginx.com 6981020Smax.romanov@nginx.com return res; 6991020Smax.romanov@nginx.com } 7001020Smax.romanov@nginx.com 7011020Smax.romanov@nginx.com 7021020Smax.romanov@nginx.com inline void * unwrapnxt_napi7031020Smax.romanov@nginx.com unwrap(napi_value val) 7041020Smax.romanov@nginx.com { 7051020Smax.romanov@nginx.com void *res; 7061020Smax.romanov@nginx.com napi_status status; 7071020Smax.romanov@nginx.com 7081020Smax.romanov@nginx.com status = napi_unwrap(env_, val, &res); 7091020Smax.romanov@nginx.com if (status != napi_ok) { 7101020Smax.romanov@nginx.com throw exception("Failed to unwrap"); 7111020Smax.romanov@nginx.com } 7121020Smax.romanov@nginx.com 7131020Smax.romanov@nginx.com return res; 7141020Smax.romanov@nginx.com } 7151020Smax.romanov@nginx.com 7161020Smax.romanov@nginx.com 7171020Smax.romanov@nginx.com inline napi_ref 7181020Smax.romanov@nginx.com wrap(napi_value val, void *obj, napi_finalize fin_cb, void *hint = nullptr) 7191020Smax.romanov@nginx.com { 7201020Smax.romanov@nginx.com napi_ref res; 7211020Smax.romanov@nginx.com napi_status status; 7221020Smax.romanov@nginx.com 7231020Smax.romanov@nginx.com status = napi_wrap(env_, val, obj, fin_cb, hint, &res); 7241020Smax.romanov@nginx.com if (status != napi_ok) { 7251020Smax.romanov@nginx.com throw exception("Failed to wrap"); 7261020Smax.romanov@nginx.com } 7271020Smax.romanov@nginx.com 7281020Smax.romanov@nginx.com return res; 7291020Smax.romanov@nginx.com } 7301020Smax.romanov@nginx.com 7311020Smax.romanov@nginx.com 7321020Smax.romanov@nginx.com inline napi_envnxt_napi7331020Smax.romanov@nginx.com operator napi_env() 7341020Smax.romanov@nginx.com { 7351020Smax.romanov@nginx.com return env_; 7361020Smax.romanov@nginx.com } 7371020Smax.romanov@nginx.com 7381020Smax.romanov@nginx.com envnxt_napi7391020Smax.romanov@nginx.com napi_env env() 7401020Smax.romanov@nginx.com { 7411020Smax.romanov@nginx.com return env_; 7421020Smax.romanov@nginx.com } 7431020Smax.romanov@nginx.com 7441020Smax.romanov@nginx.com private: 7451020Smax.romanov@nginx.com napi_env env_; 7461020Smax.romanov@nginx.com }; 7471020Smax.romanov@nginx.com 7481020Smax.romanov@nginx.com 7491020Smax.romanov@nginx.com struct nxt_handle_scope : public nxt_napi { nxt_handle_scopenxt_handle_scope7501020Smax.romanov@nginx.com nxt_handle_scope(napi_env env) : nxt_napi(env) 7511020Smax.romanov@nginx.com { 7521020Smax.romanov@nginx.com napi_status status; 7531020Smax.romanov@nginx.com 7541020Smax.romanov@nginx.com status = napi_open_handle_scope(env, &scope_); 7551020Smax.romanov@nginx.com if (status != napi_ok) { 7561020Smax.romanov@nginx.com throw exception("Failed to open handle scope"); 7571020Smax.romanov@nginx.com } 7581020Smax.romanov@nginx.com } 7591020Smax.romanov@nginx.com ~nxt_handle_scopenxt_handle_scope7601020Smax.romanov@nginx.com ~nxt_handle_scope() 7611020Smax.romanov@nginx.com { 7621020Smax.romanov@nginx.com napi_status status; 7631020Smax.romanov@nginx.com 7641020Smax.romanov@nginx.com status = napi_close_handle_scope(env(), scope_); 7651020Smax.romanov@nginx.com if (status != napi_ok) { 7661020Smax.romanov@nginx.com throw_error("Failed to close handle scope"); 7671020Smax.romanov@nginx.com } 7681020Smax.romanov@nginx.com } 7691020Smax.romanov@nginx.com 7701020Smax.romanov@nginx.com private: 7711020Smax.romanov@nginx.com napi_handle_scope scope_; 7721020Smax.romanov@nginx.com }; 7731020Smax.romanov@nginx.com 7741020Smax.romanov@nginx.com 7751020Smax.romanov@nginx.com struct nxt_async_context : public nxt_napi { nxt_async_contextnxt_async_context7761020Smax.romanov@nginx.com nxt_async_context(napi_env env, const char *name) : 7771020Smax.romanov@nginx.com nxt_napi(env) 7781020Smax.romanov@nginx.com { 7791020Smax.romanov@nginx.com napi_value name_val; 7801020Smax.romanov@nginx.com napi_status status; 7811020Smax.romanov@nginx.com 7821020Smax.romanov@nginx.com name_val = create_string_latin1(name, NAPI_AUTO_LENGTH); 7831020Smax.romanov@nginx.com 7841020Smax.romanov@nginx.com status = napi_async_init(env, NULL, name_val, &context_); 7851020Smax.romanov@nginx.com if (status != napi_ok) { 7861020Smax.romanov@nginx.com throw exception("Failed to init async object"); 7871020Smax.romanov@nginx.com } 7881020Smax.romanov@nginx.com } 7891020Smax.romanov@nginx.com napi_async_contextnxt_async_context7901020Smax.romanov@nginx.com operator napi_async_context() { 7911020Smax.romanov@nginx.com return context_; 7921020Smax.romanov@nginx.com } 7931020Smax.romanov@nginx.com ~nxt_async_contextnxt_async_context7941020Smax.romanov@nginx.com ~nxt_async_context() 7951020Smax.romanov@nginx.com { 7961020Smax.romanov@nginx.com napi_status status; 7971020Smax.romanov@nginx.com 7981020Smax.romanov@nginx.com status = napi_async_destroy(env(), context_); 7991020Smax.romanov@nginx.com if (status != napi_ok) { 8001020Smax.romanov@nginx.com throw_error("Failed to destroy async object"); 8011020Smax.romanov@nginx.com } 8021020Smax.romanov@nginx.com } 8031020Smax.romanov@nginx.com 8041020Smax.romanov@nginx.com private: 8051020Smax.romanov@nginx.com napi_async_context context_; 8061020Smax.romanov@nginx.com }; 8071020Smax.romanov@nginx.com 8081020Smax.romanov@nginx.com 8091020Smax.romanov@nginx.com struct nxt_callback_scope : public nxt_napi { nxt_callback_scopenxt_callback_scope8101020Smax.romanov@nginx.com nxt_callback_scope(nxt_async_context& ctx) : 8111020Smax.romanov@nginx.com nxt_napi(ctx.env()) 8121020Smax.romanov@nginx.com { 8131020Smax.romanov@nginx.com napi_value resource; 8141020Smax.romanov@nginx.com napi_status status; 8151020Smax.romanov@nginx.com 8161020Smax.romanov@nginx.com resource = create_object(); 8171020Smax.romanov@nginx.com 8181020Smax.romanov@nginx.com status = napi_open_callback_scope(env(), resource, ctx, &scope_); 8191020Smax.romanov@nginx.com if (status != napi_ok) { 8201020Smax.romanov@nginx.com throw exception("Failed to open callback scope"); 8211020Smax.romanov@nginx.com } 8221020Smax.romanov@nginx.com } 8231020Smax.romanov@nginx.com ~nxt_callback_scopenxt_callback_scope8241020Smax.romanov@nginx.com ~nxt_callback_scope() 8251020Smax.romanov@nginx.com { 8261020Smax.romanov@nginx.com napi_status status; 8271020Smax.romanov@nginx.com 8281020Smax.romanov@nginx.com status = napi_close_callback_scope(env(), scope_); 8291020Smax.romanov@nginx.com if (status != napi_ok) { 8301020Smax.romanov@nginx.com throw_error("Failed to close callback scope"); 8311020Smax.romanov@nginx.com } 8321020Smax.romanov@nginx.com } 8331020Smax.romanov@nginx.com 8341020Smax.romanov@nginx.com private: 8351020Smax.romanov@nginx.com napi_callback_scope scope_; 8361020Smax.romanov@nginx.com }; 8371020Smax.romanov@nginx.com 8381020Smax.romanov@nginx.com 8391020Smax.romanov@nginx.com #endif /* _NXT_NODEJS_NAPI_H_INCLUDED_ */ 840