From 2b90a160baa61298383a7ede95fed6ead353e2e3 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sun, 30 Nov 2025 17:28:05 -0600 Subject: [PATCH] remove qjs_macros.h --- meson.build | 1 - scripts/debug.c | 1 - scripts/wildstar.c | 1 - source/cell.h | 208 +++++++++++++++++++++++++++++++++++++++++++- source/jsffi.c | 2 - source/qjs_actor.c | 1 - source/qjs_macros.h | 203 ------------------------------------------ 7 files changed, 207 insertions(+), 210 deletions(-) delete mode 100644 source/qjs_macros.h diff --git a/meson.build b/meson.build index acfbf871..536cfed8 100644 --- a/meson.build +++ b/meson.build @@ -328,7 +328,6 @@ cell = custom_target('cell', # Install headers for building dynamic libraries using Cell install_headers('source/cell.h', 'source/jsffi.h') install_headers('source/quickjs.h') -install_headers('source/qjs_macros.h') install_headers('source/wota.h') install_headers('source/qjs_wota.h') diff --git a/scripts/debug.c b/scripts/debug.c index 8b01edb8..8dff33d9 100644 --- a/scripts/debug.c +++ b/scripts/debug.c @@ -1,5 +1,4 @@ #include "cell.h" -#include "qjs_macros.h" // Return the current stack depth. JSC_CCALL(debug_stack_depth, return number2js(js,js_debugger_stack_depth(js))) diff --git a/scripts/wildstar.c b/scripts/wildstar.c index 23ea7cc0..616c6319 100644 --- a/scripts/wildstar.c +++ b/scripts/wildstar.c @@ -1,6 +1,5 @@ #include "cell.h" #include "wildmatch.h" -#include "qjs_macros.h" JSC_CCALL(wildstar_match, const char *pattern = JS_ToCString(js, argv[0]); diff --git a/source/cell.h b/source/cell.h index 8adea926..1def3d1b 100644 --- a/source/cell.h +++ b/source/cell.h @@ -3,7 +3,6 @@ #include #include "quickjs.h" -#include "qjs_macros.h" #include "blob.h" #ifdef __cplusplus @@ -114,6 +113,213 @@ JSValue number2js(JSContext *js, double g); void *js2wota(JSContext *js, JSValue v); JSValue wota2js(JSContext *js, void *v); + +// Macros to help with creating scripts +#define MIST_CFUNC_DEF(name, length, func1, props) { name, props, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } } + +#define MIST_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN, JS_PROP_C_W_E) +#define PROTO_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN, 0) + +#define JS_SETSIG JSContext *js, JSValue self, JSValue val +#define JSC_CCALL(NAME, ...) static JSValue js_##NAME (JSContext *js, JSValue self, int argc, JSValue *argv) { \ + JSValue ret = JS_NULL; \ + __VA_ARGS__ ;\ + return ret; \ +} + +#define JSC_CCALL_EXTERN(NAME, ...) JSValue js_##NAME (JSContext *js, JSValue self, int argc, JSValue *argv) { \ + JSValue ret = JS_NULL; \ + __VA_ARGS__ ;\ + return ret; \ +} + +#define JSC_SCALL(NAME, ...) JSC_CCALL(NAME, \ + const char *str = JS_ToCString(js,argv[0]); \ + __VA_ARGS__ ;\ + JS_FreeCString(js,str); \ +) + +#define JSC_SSCALL(NAME, ...) JSC_CCALL(NAME, \ + const char *str = NULL; \ + const char *str2 = NULL; \ + if (!JS_IsNull(argv[0])) str = JS_ToCString(js,argv[0]); \ + if (!JS_IsNull(argv[1])) str2 = JS_ToCString(js,argv[1]); \ + __VA_ARGS__ ; \ + JS_FreeCString(js,str2); \ + JS_FreeCString(js,str); \ +) \ + +#define MIST_CGETSET_BASE(name, fgetter, fsetter, props) { name, props, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } } +#define MIST_CGETSET_DEF(name, fgetter, fsetter) MIST_CGETSET_BASE(name, fgetter, fsetter, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE) +#define MIST_CGETET_HID(name, fgetter, fsetter) MIST_CGETSET_BASE(name, fgetter, fsetter, JS_PROP_CONFIGURABLE) +#define MIST_GET(name, fgetter) { #fgetter , JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = js_##name##_get_##fgetter } } } } + +#define CGETSET_ADD_NAME(ID, ENTRY, NAME) MIST_CGETSET_DEF(#NAME, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY) +#define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY) +#define CGETSET_ADD_HID(ID, ENTRY) MIST_CGETSET_BASE(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY, JS_PROP_CONFIGURABLE) + +#define JSC_DCALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(); return JS_NULL; } + +#define JSC_1CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0])); return JS_NULL; } +#define JSC_2CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1])); return JS_NULL; } +#define JSC_3CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2])); return JS_NULL; } +#define JSC_4CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3])); return JS_NULL; } +#define JSC_5CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4])); return JS_NULL; } +#define JSC_6CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4]), js2number(js,argv[5])); return JS_NULL; } +#define JSC_7CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4]), js2number(js,argv[5]), js2number(js,argv[6])); return JS_NULL; } + +#define GETSETPAIR(ID, ENTRY, TYPE, FN) \ +JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \ + js2##ID (js, self)->ENTRY = js2##TYPE (js,val); \ + {FN;} \ + return JS_NULL; \ +} \ +\ +JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \ + return TYPE##2js(js,js2##ID (js, self)->ENTRY); \ +} \ + +#define JSC_GETSET(ID, ENTRY, TYPE) GETSETPAIR( ID , ENTRY , TYPE , ; ) +#define JSC_GETSET_APPLY(ID, ENTRY, TYPE) GETSETPAIR(ID, ENTRY, TYPE, ID##_apply(js2##ID (js, self));) +#define JSC_GETSET_CALLBACK(ID, ENTRY) \ +JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \ + JSValue fn = js2##ID (js, self)->ENTRY; \ + if (!JS_IsNull(fn)) JS_FreeValue(js, fn); \ + js2##ID (js, self)->ENTRY = JS_DupValue(js, val); \ + return JS_NULL; \ +}\ +JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { return JS_DupValue(js, js2##ID (js, self)->ENTRY); } \ + +#define JSC_GET(ID, ENTRY, TYPE) \ +JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \ + return TYPE##2js(js,js2##ID (js, self)->ENTRY); } \ + +#define QJSCLASS(TYPE, ...)\ +JSClassID js_##TYPE##_id;\ +static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\ +TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\ +TYPE##_free(rt,n);}\ +static JSClassDef js_##TYPE##_class = {\ + .class_name = #TYPE,\ + .finalizer = js_##TYPE##_finalizer,\ +};\ +TYPE *js2##TYPE (JSContext *js, JSValue val) { \ + if (JS_GetClassID(val) != js_##TYPE##_id) return NULL; \ + return JS_GetOpaque(val,js_##TYPE##_id); \ +}\ +JSValue TYPE##2js(JSContext *js, TYPE *n) { \ + JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\ + JS_SetOpaque(j,n);\ + __VA_ARGS__ \ + return j; }\ +\ + +#define QJSCLASSMARK(TYPE, ...)\ +static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\ +TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\ +TYPE##_free(rt,n);}\ +static JSClassDef js_##TYPE##_class = {\ + .class_name = #TYPE,\ + .finalizer = js_##TYPE##_finalizer,\ + .gc_mark = js_##TYPE##_mark,\ +};\ +TYPE *js2##TYPE (JSContext *js, JSValue val) { \ + if (JS_GetClassID(val) != js_##TYPE##_id) return NULL; \ + return JS_GetOpaque(val,js_##TYPE##_id); \ +}\ +JSValue TYPE##2js(JSContext *js, TYPE *n) { \ + JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\ + JS_SetOpaque(j,n);\ + __VA_ARGS__ \ + return j; }\ +\ + +#define QJSCLASSMARK_EXTERN(TYPE, ...)\ +static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\ +TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\ +TYPE##_free(rt,n);}\ +static JSClassDef js_##TYPE##_class = {\ + .class_name = #TYPE,\ + .finalizer = js_##TYPE##_finalizer,\ + .gc_mark = js_##TYPE##_mark,\ +};\ +extern JSClassID js_##TYPE##_id;\ +TYPE *js2##TYPE (JSContext *js, JSValue val) { \ + if (JS_GetClassID(val) != js_##TYPE##_id) return NULL; \ + return JS_GetOpaque(val,js_##TYPE##_id); \ +}\ +JSValue TYPE##2js(JSContext *js, TYPE *n) { \ + JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\ + JS_SetOpaque(j,n);\ + __VA_ARGS__ \ + return j; }\ +\ + +#define QJSGLOBALCLASS(NAME) \ +JSValue NAME = JS_NewObject(js); \ +JS_SetPropertyFunctionList(js, NAME, js_##NAME##_funcs, countof(js_##NAME##_funcs)); \ +JS_SetPropertyStr(js, globalThis, #NAME, NAME); \ + +/* Defines a class and uses its function list as its prototype */ +#define QJSCLASSPREP_FUNCS(TYPE) \ +QJSCLASSPREP_NO_FUNCS(TYPE) \ +JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYPE##_funcs)); \ + +#define QJSCLASSPREP_NO_FUNCS(TYPE) \ +JS_NewClassID(&js_##TYPE##_id);\ +JS_NewClass(JS_GetRuntime(js), js_##TYPE##_id, &js_##TYPE##_class);\ +JSValue TYPE##_proto = JS_NewObject(js); \ +JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \ + + +#define countof(x) (sizeof(x)/sizeof((x)[0])) + + +// Common macros for property access +#define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\ +JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \ +TARGET = js2##TYPE(JS, __##PROP##__v); \ +JS_FreeValue(JS,__##PROP##__v); }\ + +#define JS_GETATOM(JS, TARGET, VALUE, ATOM, TYPE) {\ +JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#ATOM); \ +TARGET = js2##TYPE(JS, __##PROP##__v); \ +JS_FreeValue(JS,__##PROP##__v); }\ + +// X-macro enum definition system for string<->enum conversion +#define ENUM_MAPPING_TABLE(ENUM) \ + static const struct { int value; const char *name; } ENUM##_mapping[] + +#define JS2ENUM(NAME) \ +int js2##NAME(JSContext *js, JSValue v) { \ + if (JS_IsNull(v)) return 0; \ + const char *str = JS_ToCString(js, v); \ + if (!str) return 0; \ + for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ + if(!strcmp(NAME##_mapping[i].name, str)) { \ + JS_FreeCString(js, str); \ + return NAME##_mapping[i].value; \ + } \ + JS_FreeCString(js, str); \ + return 0; \ +} \ +JSValue NAME##2js(JSContext *js, int enumval) { \ + for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ + if(NAME##_mapping[i].value == enumval) \ + return JS_NewString(js, NAME##_mapping[i].name); \ + return JS_NULL; \ +} + +#define CELL_USE_INIT(c) \ +JSValue CELL_USE_NAME(JSContext *js) { do { c ; } while(0); } + +#define CELL_USE_FUNCS(FUNCS) \ +JSValue CELL_USE_NAME(JSContext *js) { \ + JSValue mod = JS_NewObject(js); \ + JS_SetPropertyFunctionList(js, mod, FUNCS, countof(FUNCS)); \ + return mod; } + + #ifdef __cplusplus } #endif diff --git a/source/jsffi.c b/source/jsffi.c index 69604738..84b8400b 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -76,8 +76,6 @@ char *js2strdup(JSContext *js, JSValue v) { return ret; } -#include "qjs_macros.h" - JSValue angle2js(JSContext *js,double g) { return number2js(js,g*HMM_RadToTurn); } diff --git a/source/qjs_actor.c b/source/qjs_actor.c index 47f9c009..7a7a9a71 100644 --- a/source/qjs_actor.c +++ b/source/qjs_actor.c @@ -1,5 +1,4 @@ #include "qjs_actor.h" -#include "qjs_macros.h" #include "qjs_wota.h" #include "cell.h" diff --git a/source/qjs_macros.h b/source/qjs_macros.h deleted file mode 100644 index 3c766f64..00000000 --- a/source/qjs_macros.h +++ /dev/null @@ -1,203 +0,0 @@ -#define MIST_CFUNC_DEF(name, length, func1, props) { name, props, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } } - -#define MIST_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN, JS_PROP_C_W_E) -#define PROTO_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN, 0) - -#define JS_SETSIG JSContext *js, JSValue self, JSValue val -#define JSC_CCALL(NAME, ...) static JSValue js_##NAME (JSContext *js, JSValue self, int argc, JSValue *argv) { \ - JSValue ret = JS_NULL; \ - __VA_ARGS__ ;\ - return ret; \ -} - -#define JSC_CCALL_EXTERN(NAME, ...) JSValue js_##NAME (JSContext *js, JSValue self, int argc, JSValue *argv) { \ - JSValue ret = JS_NULL; \ - __VA_ARGS__ ;\ - return ret; \ -} - -#define JSC_SCALL(NAME, ...) JSC_CCALL(NAME, \ - const char *str = JS_ToCString(js,argv[0]); \ - __VA_ARGS__ ;\ - JS_FreeCString(js,str); \ -) - -#define JSC_SSCALL(NAME, ...) JSC_CCALL(NAME, \ - const char *str = NULL; \ - const char *str2 = NULL; \ - if (!JS_IsNull(argv[0])) str = JS_ToCString(js,argv[0]); \ - if (!JS_IsNull(argv[1])) str2 = JS_ToCString(js,argv[1]); \ - __VA_ARGS__ ; \ - JS_FreeCString(js,str2); \ - JS_FreeCString(js,str); \ -) \ - -#define MIST_CGETSET_BASE(name, fgetter, fsetter, props) { name, props, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } } -#define MIST_CGETSET_DEF(name, fgetter, fsetter) MIST_CGETSET_BASE(name, fgetter, fsetter, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE) -#define MIST_CGETET_HID(name, fgetter, fsetter) MIST_CGETSET_BASE(name, fgetter, fsetter, JS_PROP_CONFIGURABLE) -#define MIST_GET(name, fgetter) { #fgetter , JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = js_##name##_get_##fgetter } } } } - -#define CGETSET_ADD_NAME(ID, ENTRY, NAME) MIST_CGETSET_DEF(#NAME, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY) -#define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY) -#define CGETSET_ADD_HID(ID, ENTRY) MIST_CGETSET_BASE(#ENTRY, js_##ID##_get_##ENTRY, js_##ID##_set_##ENTRY, JS_PROP_CONFIGURABLE) - -#define JSC_DCALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(); return JS_NULL; } - -#define JSC_1CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0])); return JS_NULL; } -#define JSC_2CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1])); return JS_NULL; } -#define JSC_3CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2])); return JS_NULL; } -#define JSC_4CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3])); return JS_NULL; } -#define JSC_5CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4])); return JS_NULL; } -#define JSC_6CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4]), js2number(js,argv[5])); return JS_NULL; } -#define JSC_7CALL(FN) JSValue js_##FN (JSContext *js, JSValue self, int argc, JSValue *argv) { FN(js2number(js,argv[0]), js2number(js,argv[1]), js2number(js,argv[2]), js2number(js,argv[3]), js2number(js,argv[4]), js2number(js,argv[5]), js2number(js,argv[6])); return JS_NULL; } - -#define GETSETPAIR(ID, ENTRY, TYPE, FN) \ -JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \ - js2##ID (js, self)->ENTRY = js2##TYPE (js,val); \ - {FN;} \ - return JS_NULL; \ -} \ -\ -JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \ - return TYPE##2js(js,js2##ID (js, self)->ENTRY); \ -} \ - -#define JSC_GETSET(ID, ENTRY, TYPE) GETSETPAIR( ID , ENTRY , TYPE , ; ) -#define JSC_GETSET_APPLY(ID, ENTRY, TYPE) GETSETPAIR(ID, ENTRY, TYPE, ID##_apply(js2##ID (js, self));) -#define JSC_GETSET_CALLBACK(ID, ENTRY) \ -JSValue js_##ID##_set_##ENTRY (JS_SETSIG) { \ - JSValue fn = js2##ID (js, self)->ENTRY; \ - if (!JS_IsNull(fn)) JS_FreeValue(js, fn); \ - js2##ID (js, self)->ENTRY = JS_DupValue(js, val); \ - return JS_NULL; \ -}\ -JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { return JS_DupValue(js, js2##ID (js, self)->ENTRY); } \ - -#define JSC_GET(ID, ENTRY, TYPE) \ -JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \ - return TYPE##2js(js,js2##ID (js, self)->ENTRY); } \ - -#define QJSCLASS(TYPE, ...)\ -JSClassID js_##TYPE##_id;\ -static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\ -TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\ -TYPE##_free(rt,n);}\ -static JSClassDef js_##TYPE##_class = {\ - .class_name = #TYPE,\ - .finalizer = js_##TYPE##_finalizer,\ -};\ -TYPE *js2##TYPE (JSContext *js, JSValue val) { \ - if (JS_GetClassID(val) != js_##TYPE##_id) return NULL; \ - return JS_GetOpaque(val,js_##TYPE##_id); \ -}\ -JSValue TYPE##2js(JSContext *js, TYPE *n) { \ - JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\ - JS_SetOpaque(j,n);\ - __VA_ARGS__ \ - return j; }\ -\ - -#define QJSCLASSMARK(TYPE, ...)\ -static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\ -TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\ -TYPE##_free(rt,n);}\ -static JSClassDef js_##TYPE##_class = {\ - .class_name = #TYPE,\ - .finalizer = js_##TYPE##_finalizer,\ - .gc_mark = js_##TYPE##_mark,\ -};\ -TYPE *js2##TYPE (JSContext *js, JSValue val) { \ - if (JS_GetClassID(val) != js_##TYPE##_id) return NULL; \ - return JS_GetOpaque(val,js_##TYPE##_id); \ -}\ -JSValue TYPE##2js(JSContext *js, TYPE *n) { \ - JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\ - JS_SetOpaque(j,n);\ - __VA_ARGS__ \ - return j; }\ -\ - -#define QJSCLASSMARK_EXTERN(TYPE, ...)\ -static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\ -TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\ -TYPE##_free(rt,n);}\ -static JSClassDef js_##TYPE##_class = {\ - .class_name = #TYPE,\ - .finalizer = js_##TYPE##_finalizer,\ - .gc_mark = js_##TYPE##_mark,\ -};\ -extern JSClassID js_##TYPE##_id;\ -TYPE *js2##TYPE (JSContext *js, JSValue val) { \ - if (JS_GetClassID(val) != js_##TYPE##_id) return NULL; \ - return JS_GetOpaque(val,js_##TYPE##_id); \ -}\ -JSValue TYPE##2js(JSContext *js, TYPE *n) { \ - JSValue j = JS_NewObjectClass(js,js_##TYPE##_id);\ - JS_SetOpaque(j,n);\ - __VA_ARGS__ \ - return j; }\ -\ - -#define QJSGLOBALCLASS(NAME) \ -JSValue NAME = JS_NewObject(js); \ -JS_SetPropertyFunctionList(js, NAME, js_##NAME##_funcs, countof(js_##NAME##_funcs)); \ -JS_SetPropertyStr(js, globalThis, #NAME, NAME); \ - -/* Defines a class and uses its function list as its prototype */ -#define QJSCLASSPREP_FUNCS(TYPE) \ -QJSCLASSPREP_NO_FUNCS(TYPE) \ -JS_SetPropertyFunctionList(js, TYPE##_proto, js_##TYPE##_funcs, countof(js_##TYPE##_funcs)); \ - -#define QJSCLASSPREP_NO_FUNCS(TYPE) \ -JS_NewClassID(&js_##TYPE##_id);\ -JS_NewClass(JS_GetRuntime(js), js_##TYPE##_id, &js_##TYPE##_class);\ -JSValue TYPE##_proto = JS_NewObject(js); \ -JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \ - - -#define countof(x) (sizeof(x)/sizeof((x)[0])) - - -// Common macros for property access -#define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\ -JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \ -TARGET = js2##TYPE(JS, __##PROP##__v); \ -JS_FreeValue(JS,__##PROP##__v); }\ - -#define JS_GETATOM(JS, TARGET, VALUE, ATOM, TYPE) {\ -JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#ATOM); \ -TARGET = js2##TYPE(JS, __##PROP##__v); \ -JS_FreeValue(JS,__##PROP##__v); }\ - -// X-macro enum definition system for string<->enum conversion -#define ENUM_MAPPING_TABLE(ENUM) \ - static const struct { int value; const char *name; } ENUM##_mapping[] - -#define JS2ENUM(NAME) \ -int js2##NAME(JSContext *js, JSValue v) { \ - if (JS_IsNull(v)) return 0; \ - const char *str = JS_ToCString(js, v); \ - if (!str) return 0; \ - for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ - if(!strcmp(NAME##_mapping[i].name, str)) { \ - JS_FreeCString(js, str); \ - return NAME##_mapping[i].value; \ - } \ - JS_FreeCString(js, str); \ - return 0; \ -} \ -JSValue NAME##2js(JSContext *js, int enumval) { \ - for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ - if(NAME##_mapping[i].value == enumval) \ - return JS_NewString(js, NAME##_mapping[i].name); \ - return JS_NULL; \ -} - -#define CELL_USE_INIT(c) \ -JSValue CELL_USE_NAME(JSContext *js) { do { c ; } while(0); } - -#define CELL_USE_FUNCS(FUNCS) \ -JSValue CELL_USE_NAME(JSContext *js) { \ - JSValue mod = JS_NewObject(js); \ - JS_SetPropertyFunctionList(js, mod, FUNCS, countof(FUNCS)); \ - return mod; }