```c
typedef union JSCFunctionType {
JSCFunction *generic;
JSValue (*generic_magic)(JSContext *ctx, JSValueConst
this_val, int argc, JSValueConst *argv, int magic);
JSCFunction *constructor;
JSValue (*constructor_magic)(JSContext *ctx, JSValueConst
new_target, int argc, JSValueConst *argv, int magic);
JSCFunction *constructor_or_func;
double (*f_f)(double);
double (*f_f_f)(double, double);
JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
JSValue (*setter)(JSContext *ctx, JSValueConst this_val,
JSValueConst val);
JSValue (*getter_magic)(JSContext *ctx, JSValueConst
this_val, int magic);
JSValue (*setter_magic)(JSContext *ctx, JSValueConst
this_val, JSValueConst val, int magic);
JSValue (*iterator_next)(JSContext *ctx, JSValueConst
this_val,
int argc, JSValueConst *argv, int
*pdone, int magic);
} JSCFunctionType;
typedef struct JSCFunctionListEntry {
const char *name;
uint8_t prop_flags;
uint8_t def_type;
int16_t magic;
union {
struct {
uint8_t length; /* XXX: should move outside union */
uint8_t cproto; /* XXX: should move outside union */
JSCFunctionType cfunc;
} func;
struct {
JSCFunctionType get;
JSCFunctionType set;
} getset;
struct {
const char *name;
int base;
} alias;
struct {
const struct JSCFunctionListEntry *tab;
int len;
} prop_list;
const char *str;
int32_t i32;
int64_t i64;
double f64;
} u;
} JSCFunctionListEntry;
#define JS_CFUNC_DEF(name, length, func1) { name,
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u =
{ .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name,
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic,
.u = { .func = { length, JS_CFUNC_generic_magic, {
.generic_magic = func1 } } } }
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) {
name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0,
.u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1
} } } }
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) {
name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC,
magic, .u = { .func = { length, JS_CFUNC_iterator_next, {
.iterator_next = func1 } } } }
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name,
JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = {
.get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) {
name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, .u = {
.getset = { .get = { .getter_magic = fgetter }, .set = {
.setter_magic = fsetter } } } }
static const JSCFunctionListEntry js_std_funcs[] = {
JS_CFUNC_DEF("exit", 1, js_std_exit ),
JS_CFUNC_DEF("gc", 0, js_std_gc ),
JS_CFUNC_DEF("evalScript", 1, js_evalScript ),
JS_CFUNC_DEF("loadScript", 1, js_loadScript ),
JS_CFUNC_DEF("getenv", 1, js_std_getenv ),
JS_CFUNC_DEF("setenv", 1, js_std_setenv ),
JS_CFUNC_DEF("unsetenv", 1, js_std_unsetenv ),
JS_CFUNC_DEF("getenviron", 1, js_std_getenviron ),
JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ),
JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ),
JS_CFUNC_DEF("strerror", 1, js_std_strerror ),
JS_CFUNC_DEF("parseExtJSON", 1, js_std_parseExtJSON ),
/* FILE I/O */
JS_CFUNC_DEF("open", 2, js_std_open ),
JS_CFUNC_DEF("popen", 2, js_std_popen ),
JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ),
JS_CFUNC_DEF("tmpfile", 0, js_std_tmpfile ),
JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 0 ),
JS_CFUNC_DEF("printf", 1, js_std_printf ),
JS_CFUNC_DEF("sprintf", 1, js_std_sprintf ),
};
```
the js_std_funcs better to be defined as const, so in runtime
the memory address is non-writable for some platform.
I am not sure how to translate JS_CFUNC_DEF, JS_CFUNC_MAGIC_DEF
into D, so I can use it like c here to create a nice const
array of JSCFunctionListEntry