remove qjs_macros.h
This commit is contained in:
@@ -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')
|
||||
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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]);
|
||||
|
||||
208
source/cell.h
208
source/cell.h
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "qjs_actor.h"
|
||||
#include "qjs_macros.h"
|
||||
#include "qjs_wota.h"
|
||||
#include "cell.h"
|
||||
|
||||
|
||||
@@ -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; }
|
||||
Reference in New Issue
Block a user