1 #ifndef JS_NATIVE_API_COMMON_H_ 2 #define JS_NATIVE_API_COMMON_H_ 3 4 #include <js_native_api.h> 5 #include <stdlib.h> // abort() 6 7 // Empty value so that macros here are able to return NULL or void 8 #define NODE_API_RETVAL_NOTHING // Intentionally blank #define 9 10 #define GET_AND_THROW_LAST_ERROR(env) \ 11 do { \ 12 const napi_extended_error_info *error_info; \ 13 napi_get_last_error_info((env), &error_info); \ 14 bool is_pending; \ 15 const char* err_message = error_info->error_message; \ 16 napi_is_exception_pending((env), &is_pending); \ 17 /* If an exception is already pending, don't rethrow it */ \ 18 if (!is_pending) { \ 19 const char* error_message = err_message != NULL ? \ 20 err_message : \ 21 "empty error message"; \ 22 napi_throw_error((env), NULL, error_message); \ 23 } \ 24 } while (0) 25 26 // The nogc version of GET_AND_THROW_LAST_ERROR. We cannot access any 27 // exceptions and we cannot fail by way of JS exception, so we abort. 28 #define FATALLY_FAIL_WITH_LAST_ERROR(env) \ 29 do { \ 30 const napi_extended_error_info* error_info; \ 31 napi_get_last_error_info((env), &error_info); \ 32 const char* err_message = error_info->error_message; \ 33 const char* error_message = \ 34 err_message != NULL ? err_message : "empty error message"; \ 35 fprintf(stderr, "%s\n", error_message); \ 36 abort(); \ 37 } while (0) 38 39 #define NODE_API_ASSERT_BASE(env, assertion, message, ret_val) \ 40 do { \ 41 if (!(assertion)) { \ 42 napi_throw_error( \ 43 (env), \ 44 NULL, \ 45 "assertion (" #assertion ") failed: " message); \ 46 return ret_val; \ 47 } \ 48 } while (0) 49 50 #define NODE_API_NOGC_ASSERT_BASE(assertion, message, ret_val) \ 51 do { \ 52 if (!(assertion)) { \ 53 fprintf(stderr, "assertion (" #assertion ") failed: " message); \ 54 abort(); \ 55 return ret_val; \ 56 } \ 57 } while (0) 58 59 // Returns NULL on failed assertion. 60 // This is meant to be used inside napi_callback methods. 61 #define NODE_API_ASSERT(env, assertion, message) \ 62 NODE_API_ASSERT_BASE(env, assertion, message, NULL) 63 64 // Returns empty on failed assertion. 65 // This is meant to be used inside functions with void return type. 66 #define NODE_API_ASSERT_RETURN_VOID(env, assertion, message) \ 67 NODE_API_ASSERT_BASE(env, assertion, message, NODE_API_RETVAL_NOTHING) 68 69 #define NODE_API_NOGC_ASSERT_RETURN_VOID(assertion, message) \ 70 NODE_API_NOGC_ASSERT_BASE(assertion, message, NODE_API_RETVAL_NOTHING) 71 72 #define NODE_API_CALL_BASE(env, the_call, ret_val) \ 73 do { \ 74 if ((the_call) != napi_ok) { \ 75 GET_AND_THROW_LAST_ERROR((env)); \ 76 return ret_val; \ 77 } \ 78 } while (0) 79 80 #define NODE_API_NOGC_CALL_BASE(env, the_call, ret_val) \ 81 do { \ 82 if ((the_call) != napi_ok) { \ 83 FATALLY_FAIL_WITH_LAST_ERROR((env)); \ 84 return ret_val; \ 85 } \ 86 } while (0) 87 88 // Returns NULL if the_call doesn't return napi_ok. 89 #define NODE_API_CALL(env, the_call) \ 90 NODE_API_CALL_BASE(env, the_call, NULL) 91 92 // Returns empty if the_call doesn't return napi_ok. 93 #define NODE_API_CALL_RETURN_VOID(env, the_call) \ 94 NODE_API_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING) 95 96 #define NODE_API_NOGC_CALL_RETURN_VOID(env, the_call) \ 97 NODE_API_NOGC_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING) 98 99 #define NODE_API_CHECK_STATUS(the_call) \ 100 do { \ 101 napi_status status = (the_call); \ 102 if (status != napi_ok) { \ 103 return status; \ 104 } \ 105 } while (0) 106 107 #define NODE_API_ASSERT_STATUS(env, assertion, message) \ 108 NODE_API_ASSERT_BASE(env, assertion, message, napi_generic_failure) 109 110 #define DECLARE_NODE_API_PROPERTY(name, func) \ 111 { (name), NULL, (func), NULL, NULL, NULL, napi_default, NULL } 112 113 #define DECLARE_NODE_API_GETTER(name, func) \ 114 { (name), NULL, NULL, (func), NULL, NULL, napi_default, NULL } 115 116 #define DECLARE_NODE_API_PROPERTY_VALUE(name, value) \ 117 { (name), NULL, NULL, NULL, NULL, (value), napi_default, NULL } 118 119 static inline void add_returned_status(napi_env env, 120 const char* key, 121 napi_value object, 122 char* expected_message, 123 napi_status expected_status, 124 napi_status actual_status); 125 126 static inline void add_last_status(napi_env env, 127 const char* key, 128 napi_value return_value); 129 130 #include "common-inl.h" 131 132 #endif // JS_NATIVE_API_COMMON_H_ 133