summaryrefslogtreecommitdiff
path: root/javascript/dukky.h
diff options
context:
space:
mode:
Diffstat (limited to 'javascript/dukky.h')
-rw-r--r--javascript/dukky.h119
1 files changed, 119 insertions, 0 deletions
diff --git a/javascript/dukky.h b/javascript/dukky.h
new file mode 100644
index 000000000..cd6286cea
--- /dev/null
+++ b/javascript/dukky.h
@@ -0,0 +1,119 @@
+/* DO NOT USE, DODGY BIT FOR VINCE */
+
+#ifndef DUKKY_H
+#define DUKKY_H
+
+#include "duktape.h"
+
+#define _MAGIC(S) ("\xFF\xFF" "NETSURF_DUKTAPE_" S)
+#define MAGIC(S) _MAGIC(#S)
+#define PROTO_MAGIC MAGIC(PROTOTYPES)
+#define PRIVATE_MAGIC MAGIC(PRIVATE)
+#define INIT_MAGIC MAGIC(INIT)
+#define _PROTO_NAME(K) _MAGIC("PROTOTYPE_" K)
+#define PROTO_NAME(K) _PROTO_NAME(#K)
+#define _PROP_NAME(K,V) _MAGIC(K "_PROPERTY_" V)
+#define PROP_NAME(K,V) _PROP_NAME(#K,#V)
+
+#define DUKKY_FUNC_T(t,e) dukky_##t##_##e
+#define DUKKY_FUNC(t,e) duk_ret_t DUKKY_FUNC_T(t,e) (duk_context *ctx)
+
+static inline void *dukky_get_private(duk_context *ctx, int idx)
+{
+ void *ret;
+ duk_get_prop_string(ctx, idx, PRIVATE_MAGIC);
+ ret = duk_get_pointer(ctx, -1);
+ duk_pop(ctx);
+ return ret;
+}
+
+#define DUKKY_CREATE_PRIVATE(klass) \
+ klass##_private_t *priv = calloc(1, sizeof(*priv)); \
+ if (priv == NULL) return 0; \
+ duk_push_pointer(ctx, priv); \
+ duk_put_prop_string(ctx, 0, PRIVATE_MAGIC)
+
+#define DUKKY_SET_DESTRUCTOR(idx,n) \
+ duk_dup(ctx, idx); \
+ duk_push_c_function(ctx, DUKKY_FUNC_T(n,__destructor), 1); \
+ duk_set_finalizer(ctx, -2); \
+ duk_pop(ctx);
+
+#define DUKKY_SET_CONSTRUCTOR(idx,n,a) \
+ duk_dup(ctx, idx); \
+ duk_push_c_function(ctx, DUKKY_FUNC_T(n,__constructor), 1 + a); \
+ duk_put_prop_string(ctx, -2, INIT_MAGIC); \
+ duk_pop(ctx);
+
+#define DUKKY_SAFE_GET_PRIVATE(t,idx) \
+ t##_private_t *priv = dukky_get_private(ctx, idx); \
+ if (priv == NULL) return 0; /* No can do */
+
+#define DUKKY_GET_METHOD_PRIVATE(t) \
+ t##_private_t *priv = NULL; \
+ duk_push_this(ctx); \
+ duk_get_prop_string(ctx, -1, PRIVATE_MAGIC); \
+ priv = duk_get_pointer(ctx, -1); \
+ duk_pop_2(ctx); \
+ if (priv == NULL) return 0; /* No can do */
+
+#define DUKKY_GET_PROTOTYPE(klass) \
+ duk_get_global_string(ctx, PROTO_MAGIC); \
+ duk_get_prop_string(ctx, -1, PROTO_NAME(klass)); \
+ duk_replace(ctx, -2); \
+ duk_pop(ctx);
+
+#define DUKKY_DECLARE_PROTOTYPE(klass) \
+ DUKKY_FUNC(klass,__proto)
+
+#define DUKKY_GETTER(klass,prop) \
+ duk_ret_t DUKKY_FUNC_T(klass,prop##_getter)(duk_context *ctx)
+
+#define DUKKY_SETTER(klass,prop) \
+ duk_ret_t DUKKY_FUNC_T(klass,prop##_setter)(duk_context *ctx)
+
+#define DUKKY_POPULATE_FULL_PROPERTY(klass,prop) \
+ duk_dup(ctx, 0); \
+ duk_push_string(ctx, #prop); \
+ duk_push_c_function(ctx, DUKKY_FUNC_T(klass,prop##_getter), 0); \
+ duk_push_c_function(ctx, DUKKY_FUNC_T(klass,prop##_setter), 1); \
+ duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER | \
+ DUK_DEFPROP_HAVE_SETTER | \
+ DUK_DEFPROP_HAVE_CONFIGURABLE); \
+ duk_pop(ctx)
+
+#define DUKKY_DUMP_STACK(ctx) \
+ do { \
+ duk_push_context_dump(ctx); \
+ LOG("Stack: %s", duk_to_string(ctx, -1)); \
+ duk_pop(ctx); \
+ } while(0)
+
+#define DUKKY_ADD_METHOD(klass,meth,nargs) \
+ duk_dup(ctx, 0); \
+ duk_push_string(ctx, #meth); \
+ duk_push_c_function(ctx, DUKKY_FUNC_T(klass,meth), nargs); \
+ DUKKY_DUMP_STACK(ctx);\
+ duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | \
+ DUK_DEFPROP_HAVE_WRITABLE | \
+ DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE | \
+ DUK_DEFPROP_HAVE_CONFIGURABLE); \
+ duk_pop(ctx)
+
+#define DUKKY_FUNC_INIT(klass,args...) \
+ void DUKKY_FUNC_T(klass, __init)(duk_context *ctx, klass##_private_t *priv, ##args)
+
+#define DUKKY_FUNC_FINI(klass) \
+ void DUKKY_FUNC_T(klass, __fini)(duk_context *ctx, klass##_private_t *priv)
+
+#define DUKKY_DECLARE_INTERFACE(klass,init...) \
+ DUKKY_FUNC(klass, __proto); \
+ DUKKY_FUNC_INIT(klass, ##init); \
+ DUKKY_FUNC_FINI(klass)
+
+#include "duktape/private.h"
+#include "duktape/prototypes.h"
+
+duk_ret_t dukky_create_object(duk_context *ctx, const char *name, int args);
+
+#endif