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, ¶m, &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