1 /* 2 * Copyright (c) 2012 Joyent, Inc. All rights reserved. 3 */ 4 5 #ifndef _V8PLUS_GLUE_H 6 #define _V8PLUS_GLUE_H 7 8 #include <stdarg.h> 9 #include <libnvpair.h> 10 #include "v8plus_errno.h" 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif /* __cplusplus */ 15 16 #define V8PLUS_ARG_F_NOEXTRA 0x01 17 18 #define V8PLUS_ERRMSG_LEN 512 19 #define V8PLUS_JSF_COOKIE ".__v8plus_jsfunc_cookie" 20 21 typedef enum v8plus_type { 22 V8PLUS_TYPE_NONE = 0, /* N/A */ 23 V8PLUS_TYPE_STRING, /* char * */ 24 V8PLUS_TYPE_NUMBER, /* double */ 25 V8PLUS_TYPE_BOOLEAN, /* boolean_t */ 26 V8PLUS_TYPE_JSFUNC, /* v8plus_jsfunc_t */ 27 V8PLUS_TYPE_OBJECT, /* nvlist_t * */ 28 V8PLUS_TYPE_NULL, /* -- */ 29 V8PLUS_TYPE_UNDEFINED, /* -- */ 30 V8PLUS_TYPE_INVALID, /* data_type_t */ 31 V8PLUS_TYPE_ANY, /* nvpair_t * */ 32 V8PLUS_TYPE_STRNUMBER64, /* uint64_t */ 33 V8PLUS_TYPE_INL_OBJECT /* ... */ 34 } v8plus_type_t; 35 36 typedef uint64_t v8plus_jsfunc_t; 37 38 /* 39 * C constructor, destructor, and method prototypes. See README.md. 40 */ 41 typedef nvlist_t *(*v8plus_c_ctor_f)(const nvlist_t *, void **); 42 typedef nvlist_t *(*v8plus_c_static_f)(const nvlist_t *); 43 typedef nvlist_t *(*v8plus_c_method_f)(void *, const nvlist_t *); 44 typedef void (*v8plus_c_dtor_f)(void *); 45 46 typedef struct v8plus_method_descr { 47 const char *md_name; 48 v8plus_c_method_f md_c_func; 49 } v8plus_method_descr_t; 50 51 typedef struct v8plus_static_descr { 52 const char *sd_name; 53 v8plus_c_static_f sd_c_func; 54 } v8plus_static_descr_t; 55 56 extern __thread v8plus_errno_t _v8plus_errno; 57 extern __thread char _v8plus_errmsg[V8PLUS_ERRMSG_LEN]; 58 59 /* 60 * Set the errno and message, indicating an error. The code and 61 * printf-formatted message, if one is given, will be used in constructing 62 * an exception to be thrown in JavaScript if your method later returns NULL 63 * or an nvlist with an "err" member. 64 */ 65 extern nvlist_t *v8plus_verror(v8plus_errno_t, const char *, va_list); 66 extern nvlist_t *v8plus_error(v8plus_errno_t, const char *, ...); 67 68 /* 69 * Suicide. It's always an option. Try to avoid using this as it's not 70 * very nice to kill the entire node process; if at all possible we need 71 * to throw a JavaScript exception instead. 72 */ 73 extern void v8plus_panic(const char *, ...) __PRINTFLIKE(1) __NORETURN; 74 75 /* 76 * As above, this convenience function sets the error code and message based 77 * on the nvlist-generated error code in its first argument. The second 78 * argument, which may be NULL, should contain the name of the member on 79 * which the error occurred. 80 */ 81 extern nvlist_t *v8plus_nverr(int, const char *); 82 83 /* 84 * Similarly, for system errors. Not all possible errno values are handled. 85 */ 86 extern nvlist_t *v8plus_syserr(int, const char *, ...); 87 88 /* 89 * Clear the errno and message. This is needed only when one wishes to return 90 * NULL from a C method whose return type is effectively void. The idiom is 91 * 92 * return (v8plus_void()); 93 */ 94 extern nvlist_t *v8plus_void(void); 95 96 /* 97 * Find the named V8 function in the nvlist. Analogous to other lookup 98 * routines; see libnvpair(3lib), with an important exception: the 99 * nvlist_lookup_v8plus_jsfunc() and nvpair_value_v8plus_jsfunc() functions 100 * place a hold on the underlying function object, which must be released by C 101 * code when it is no longer needed. See the documentation to understand how 102 * this works. The add routine is of very limited utility because there is no 103 * mechanism for creating a JS function from C. It can however be used to 104 * return a function (or object containing one, etc.) from a deferred 105 * completion routine in which a JS function has been invoked that returned 106 * such a thing to us. 107 */ 108 extern int nvlist_lookup_v8plus_jsfunc(const nvlist_t *, const char *, 109 v8plus_jsfunc_t *); 110 extern int nvpair_value_v8plus_jsfunc(const nvpair_t *, v8plus_jsfunc_t *); 111 extern void v8plus_jsfunc_hold(v8plus_jsfunc_t); 112 extern void v8plus_jsfunc_rele(v8plus_jsfunc_t); 113 114 /* 115 * Place or release a hold on the V8 representation of the specified C object. 116 * This is rarely necessary; v8plus_defer() performs this action for you, but 117 * other asynchronous mechanisms may require it. If you are returning from 118 * a method call but have stashed a reference to the object somewhere and are 119 * not calling v8plus_defer(), you must call this first. Holds and releases 120 * must be balanced. Use of the object within a thread after releasing is a 121 * bug. 122 */ 123 extern void v8plus_obj_hold(const void *); 124 extern void v8plus_obj_rele(const void *); 125 126 /* 127 * Convenience functions for dealing with JS arguments. 128 */ 129 extern v8plus_type_t v8plus_typeof(const nvpair_t *); 130 extern int v8plus_args(const nvlist_t *, uint_t, v8plus_type_t t, ...); 131 extern nvlist_t *v8plus_obj(v8plus_type_t, ...); 132 extern int v8plus_obj_setprops(nvlist_t *, v8plus_type_t, ...); 133 134 /* 135 * Perform a background, possibly blocking and/or expensive, task. First, 136 * the worker function will be enqueued for execution on another thread; its 137 * first argument is a pointer to the C object on which to operate, and the 138 * second is arbitrary per-call context, arguments, etc. defined by the caller. 139 * When that worker function has completed execution, the completion function 140 * will be invoked in the main thread. Its arguments are the C object, the 141 * original context pointer, and the return value from the worker function. 142 * See the documentation for a typical use case. 143 */ 144 typedef void *(*v8plus_worker_f)(void *, void *); 145 typedef void (*v8plus_completion_f)(void *, void *, void *); 146 147 extern void v8plus_defer(void *, void *, v8plus_worker_f, v8plus_completion_f); 148 149 /* 150 * Call an opaque JavaScript function from C. The caller is responsible for 151 * freeing the returned list. The first argument is not const because it is 152 * possible for the JS code to modify the function represented by the cookie. 153 */ 154 extern nvlist_t *v8plus_call(v8plus_jsfunc_t, const nvlist_t *); 155 156 /* 157 * Call the named JavaScript function in the context of the JS object 158 * represented by the native object. Calling and return conventions are the 159 * same as for the C interfaces; i.e., the nvlist will be converted into JS 160 * objects and the return value or exception will be in the "res" or "err" 161 * members of the nvlist that is returned, respectively. If an internal 162 * error occurs, NULL is returned and _v8plus_errno set accordingly. The 163 * results of calling a method implemented in C via this interface are 164 * undefined. 165 * 166 * This can be used in concert with JS code to emit events asynchronously; 167 * see the documentation. 168 */ 169 extern nvlist_t *v8plus_method_call(void *, const char *, const nvlist_t *); 170 171 /* 172 * These methods are analogous to strerror(3c) and similar functions; they 173 * translate among error names, codes, and default messages. There is 174 * normally little need for these functions in C methods, as everything 175 * necessary to construct a JavaScript exception is done by v8+, but these 176 * may be useful in the construction of supplementary exception decorations 177 * for debugging purposes. 178 */ 179 extern const char *v8plus_strerror(v8plus_errno_t); 180 extern const char *v8plus_errname(v8plus_errno_t); 181 extern const char *v8plus_excptype(v8plus_errno_t); 182 183 /* 184 * Provided by C code. See README.md. 185 */ 186 extern const v8plus_c_ctor_f v8plus_ctor; 187 extern const v8plus_c_dtor_f v8plus_dtor; 188 extern const char *v8plus_js_factory_name; 189 extern const char *v8plus_js_class_name; 190 extern const v8plus_method_descr_t v8plus_methods[]; 191 extern const uint_t v8plus_method_count; 192 extern const v8plus_static_descr_t v8plus_static_methods[]; 193 extern const uint_t v8plus_static_method_count; 194 195 #ifdef __cplusplus 196 } 197 #endif /* __cplusplus */ 198 199 #endif /* _V8PLUS_GLUE_H */