@@ -151,17 +151,7 @@ lua_load_cdb (lua_State *L) | |||
void | |||
luaopen_cdb (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{cdb}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{cdb}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, cdblib_m); | |||
lua_pop (L, 1); /* remove metatable from stack */ | |||
rspamd_lua_new_class (L, "rspamd{cdb}", cdblib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_cdb", lua_load_cdb); | |||
} |
@@ -45,6 +45,25 @@ lua_error_quark (void) | |||
return g_quark_from_static_string ("lua-routines"); | |||
} | |||
/* idea from daurnimator */ | |||
#if defined(WITH_LUAJIT) && (defined(_LP64) || defined(_LLP64) || defined(__arch64__) || defined (__arm64__) || defined (__aarch64__) || defined(_WIN64)) | |||
#define RSPAMD_USE_47BIT_LIGHTUSERDATA_HACK 1 | |||
#else | |||
#define RSPAMD_USE_47BIT_LIGHTUSERDATA_HACK 0 | |||
#endif | |||
#if RSPAMD_USE_47BIT_LIGHTUSERDATA_HACK | |||
#define RSPAMD_LIGHTUSERDATA_MASK(p) ((void *)((uintptr_t)(p) & ((1UL<<47)-1))) | |||
#else | |||
#define RSPAMD_LIGHTUSERDATA_MASK(p) ((void *)(p)) | |||
#endif | |||
/* | |||
* Used to map string to a pointer | |||
*/ | |||
KHASH_INIT (lua_class_set, const gchar *, bool, 0, rspamd_str_hash, rspamd_str_equal); | |||
khash_t (lua_class_set) *lua_classes = NULL; | |||
/* Util functions */ | |||
/** | |||
* Create new class and store metatable on top of the stack (must be popped if not needed) | |||
@@ -57,33 +76,48 @@ rspamd_lua_new_class (lua_State * L, | |||
const gchar *classname, | |||
const struct luaL_reg *methods) | |||
{ | |||
luaL_newmetatable (L, classname); /* mt */ | |||
void *class_ptr; | |||
khiter_t k; | |||
gint r, nmethods = 0; | |||
if (lua_classes == NULL) { | |||
lua_classes = kh_init (lua_class_set); | |||
} | |||
k = kh_put (lua_class_set, lua_classes, classname, &r); | |||
class_ptr = RSPAMD_LIGHTUSERDATA_MASK (kh_key (lua_classes, k)); | |||
if (methods) { | |||
for (;;) { | |||
if (methods[nmethods].name != NULL) { | |||
nmethods ++; | |||
} | |||
else { | |||
break; | |||
} | |||
} | |||
} | |||
lua_createtable (L, 0, 3 + nmethods); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); /* pushes the metatable */ | |||
lua_settable (L, -3); /* metatable.__index = metatable */ | |||
lua_pushstring (L, "class"); /* mt,"class" */ | |||
lua_pushstring (L, classname); /* mt,"class",classname */ | |||
lua_rawset (L, -3); /* mt */ | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, classname); | |||
lua_rawset (L, -3); | |||
lua_pushstring (L, "class_ptr"); | |||
lua_pushlightuserdata (L, class_ptr); | |||
lua_rawset (L, -3); | |||
if (methods) { | |||
luaL_register (L, NULL, methods); /* pushes all methods as MT fields */ | |||
} | |||
/* MT is left on stack ! */ | |||
} | |||
/** | |||
* Create and register new class with static methods and store metatable on top of the stack | |||
*/ | |||
void | |||
rspamd_lua_new_class_full (lua_State *L, | |||
const gchar *classname, | |||
const gchar *static_name, | |||
const struct luaL_reg *methods, | |||
const struct luaL_reg *func) | |||
{ | |||
rspamd_lua_new_class (L, classname, methods); | |||
luaL_register (L, static_name, func); | |||
lua_pushvalue (L, -1); /* Preserves metatable */ | |||
lua_rawsetp (L, LUA_REGISTRYINDEX, class_ptr); | |||
/* MT is left on stack ! */ | |||
} | |||
static const gchar * | |||
@@ -150,7 +184,14 @@ rspamd_lua_class_tostring (lua_State * L) | |||
void | |||
rspamd_lua_setclass (lua_State * L, const gchar *classname, gint objidx) | |||
{ | |||
luaL_getmetatable (L, classname); | |||
khiter_t k; | |||
k = kh_get (lua_class_set, lua_classes, classname); | |||
g_assert (k != kh_end (lua_classes)); | |||
lua_rawgetp (L, LUA_REGISTRYINDEX, | |||
RSPAMD_LIGHTUSERDATA_MASK (kh_key (lua_classes, k))); | |||
if (objidx < 0) { | |||
objidx--; | |||
} | |||
@@ -161,7 +202,6 @@ rspamd_lua_setclass (lua_State * L, const gchar *classname, gint objidx) | |||
void | |||
rspamd_lua_table_set (lua_State * L, const gchar *index, const gchar *value) | |||
{ | |||
lua_pushstring (L, index); | |||
if (value) { | |||
lua_pushstring (L, value); | |||
@@ -929,16 +969,10 @@ rspamd_lua_init (bool wipe_mem) | |||
lua_settop (L, 0); | |||
#endif | |||
luaL_newmetatable (L, "rspamd{ev_base}"); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{ev_base}"); | |||
lua_rawset (L, -3); | |||
rspamd_lua_new_class (L, "rspamd{ev_base}", NULL); | |||
lua_pop (L, 1); | |||
luaL_newmetatable (L, "rspamd{session}"); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{session}"); | |||
lua_rawset (L, -3); | |||
rspamd_lua_new_class (L, "rspamd{session}", NULL); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "lpeg", luaopen_lpeg); | |||
@@ -1206,12 +1240,23 @@ gpointer | |||
rspamd_lua_check_class (lua_State *L, gint index, const gchar *name) | |||
{ | |||
gpointer p; | |||
khiter_t k; | |||
if (lua_type (L, index) == LUA_TUSERDATA) { | |||
p = lua_touserdata (L, index); | |||
if (p) { | |||
if (lua_getmetatable (L, index)) { | |||
lua_getfield (L, LUA_REGISTRYINDEX, name); /* get correct metatable */ | |||
k = kh_get (lua_class_set, lua_classes, name); | |||
if (k == kh_end (lua_classes)) { | |||
lua_pop (L, 1); | |||
return NULL; | |||
} | |||
lua_rawgetp (L, LUA_REGISTRYINDEX, | |||
RSPAMD_LIGHTUSERDATA_MASK (kh_value (lua_classes, k))); | |||
if (lua_rawequal (L, -1, -2)) { /* does it have the correct mt? */ | |||
lua_pop (L, 2); /* remove both metatables */ | |||
return p; | |||
@@ -1824,6 +1869,7 @@ rspamd_lua_check_udata_common (lua_State *L, gint pos, const gchar *classname, | |||
{ | |||
void *p = lua_touserdata (L, pos); | |||
guint i, top = lua_gettop (L); | |||
khiter_t k; | |||
if (p == NULL) { | |||
goto err; | |||
@@ -1831,7 +1877,14 @@ rspamd_lua_check_udata_common (lua_State *L, gint pos, const gchar *classname, | |||
else { | |||
/* Match class */ | |||
if (lua_getmetatable (L, pos)) { | |||
luaL_getmetatable (L, classname); | |||
k = kh_get (lua_class_set, lua_classes, (gchar *)classname); | |||
if (k == kh_end (lua_classes)) { | |||
goto err; | |||
} | |||
lua_rawgetp (L, LUA_REGISTRYINDEX, | |||
RSPAMD_LIGHTUSERDATA_MASK (kh_key (lua_classes, k))); | |||
if (!lua_rawequal (L, -1, -2)) { | |||
goto err; |
@@ -154,15 +154,6 @@ void rspamd_lua_new_class (lua_State *L, | |||
const gchar *classname, | |||
const struct luaL_reg *methods); | |||
/** | |||
* Create and register new class with static methods | |||
*/ | |||
void rspamd_lua_new_class_full (lua_State *L, | |||
const gchar *classname, | |||
const gchar *static_name, | |||
const struct luaL_reg *methods, | |||
const struct luaL_reg *func); | |||
/** | |||
* Set class name for object at @param objidx position | |||
*/ |
@@ -2437,54 +2437,20 @@ lua_load_cryptobox (lua_State * L) | |||
void | |||
luaopen_cryptobox (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{cryptobox_pubkey}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{cryptobox_pubkey}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, cryptoboxpubkeylib_m); | |||
rspamd_lua_new_class (L, "rspamd{cryptobox_pubkey}", cryptoboxpubkeylib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_cryptobox_pubkey", lua_load_pubkey); | |||
luaL_newmetatable (L, "rspamd{cryptobox_keypair}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{cryptobox_keypair}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, cryptoboxkeypairlib_m); | |||
rspamd_lua_new_class (L, "rspamd{cryptobox_keypair}", cryptoboxkeypairlib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_cryptobox_keypair", lua_load_keypair); | |||
luaL_newmetatable (L, "rspamd{cryptobox_signature}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{cryptobox_signature}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, cryptoboxsignlib_m); | |||
rspamd_lua_new_class (L, "rspamd{cryptobox_signature}", cryptoboxsignlib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_cryptobox_signature", lua_load_signature); | |||
luaL_newmetatable (L, "rspamd{cryptobox_hash}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{cryptobox_hash}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, cryptoboxhashlib_m); | |||
rspamd_lua_new_class (L, "rspamd{cryptobox_hash}", cryptoboxhashlib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_cryptobox_hash", lua_load_hash); | |||
rspamd_lua_add_preload (L, "rspamd_cryptobox", lua_load_cryptobox); |
@@ -693,15 +693,7 @@ void | |||
luaopen_dns_resolver (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{resolver}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{resolver}"); | |||
lua_rawset (L, -3); | |||
rspamd_lua_new_class (L, "rspamd{resolver}", dns_resolverlib_m); | |||
{ | |||
LUA_ENUM (L, DNS_A, RDNS_REQUEST_A); | |||
LUA_ENUM (L, DNS_PTR, RDNS_REQUEST_PTR); | |||
@@ -713,8 +705,7 @@ luaopen_dns_resolver (lua_State * L) | |||
LUA_ENUM (L, DNS_SOA, RDNS_REQUEST_SOA); | |||
} | |||
luaL_register (L, NULL, dns_resolverlib_m); | |||
rspamd_lua_add_preload (L, "rspamd_resolver", lua_load_dns_resolver); | |||
lua_pop (L, 1); | |||
lua_pop (L, 1); /* remove metatable from stack */ | |||
rspamd_lua_add_preload (L, "rspamd_resolver", lua_load_dns_resolver); | |||
} |
@@ -511,17 +511,7 @@ lua_load_expression (lua_State * L) | |||
void | |||
luaopen_expression (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{expr}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{expr}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, exprlib_m); | |||
rspamd_lua_new_class (L, "rspamd{expr}", exprlib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_expression", lua_load_expression); | |||
lua_pop (L, 1); /* remove metatable from stack */ | |||
} |
@@ -584,17 +584,7 @@ lua_load_ip (lua_State * L) | |||
void | |||
luaopen_ip (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{ip}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{ip}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, iplib_m); | |||
rspamd_lua_add_preload (L, "rspamd_ip", lua_load_ip); | |||
rspamd_lua_new_class (L, "rspamd{ip}", iplib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_ip", lua_load_ip); | |||
} |
@@ -582,17 +582,7 @@ lua_load_mempool (lua_State * L) | |||
void | |||
luaopen_mempool (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{mempool}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{mempool}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, mempoollib_m); | |||
rspamd_lua_new_class (L, "rspamd{mempool}", mempoollib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_mempool", lua_load_mempool); | |||
lua_pop (L, 1); /* remove metatable from stack */ | |||
} |
@@ -1603,17 +1603,7 @@ lua_load_redis (lua_State * L) | |||
void | |||
luaopen_redis (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{redis}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{redis}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, redislib_m); | |||
rspamd_lua_new_class (L, "rspamd{redis}", redislib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_redis", lua_load_redis); | |||
} |
@@ -880,22 +880,12 @@ lua_load_regexp (lua_State * L) | |||
void | |||
luaopen_regexp (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{regexp}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{regexp}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, regexplib_m); | |||
rspamd_lua_new_class (L, "rspamd{regexp}", regexplib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_regexp", lua_load_regexp); | |||
if (regexp_static_pool == NULL) { | |||
regexp_static_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), | |||
"regexp_lua_pool"); | |||
} | |||
lua_settop (L, 0); | |||
} |
@@ -719,40 +719,16 @@ lua_load_rsa (lua_State * L) | |||
void | |||
luaopen_rsa (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{rsa_pubkey}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{rsa_pubkey}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, rsapubkeylib_m); | |||
rspamd_lua_new_class (L, "rspamd{rsa_pubkey}", rsapubkeylib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_rsa_pubkey", lua_load_pubkey); | |||
luaL_newmetatable (L, "rspamd{rsa_privkey}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{rsa_privkey}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, rsaprivkeylib_m); | |||
rspamd_lua_new_class (L, "rspamd{rsa_privkey}", rsaprivkeylib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_rsa_privkey", lua_load_privkey); | |||
luaL_newmetatable (L, "rspamd{rsa_signature}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{rsa_signature}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, rsasignlib_m); | |||
rspamd_lua_new_class (L, "rspamd{rsa_signature}", rsasignlib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_rsa_signature", lua_load_signature); | |||
rspamd_lua_add_preload (L, "rspamd_rsa", lua_load_rsa); |
@@ -373,28 +373,10 @@ lua_load_sqlite3 (lua_State * L) | |||
void | |||
luaopen_sqlite3 (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{sqlite3}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{sqlite3}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, sqlitelib_m); | |||
rspamd_lua_new_class (L, "rspamd{sqlite3}", sqlitelib_m); | |||
lua_pop (L, 1); | |||
luaL_newmetatable (L, "rspamd{sqlite3_stmt}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{sqlite3_stmt}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, sqlitestmtlib_m); | |||
rspamd_lua_new_class (L, "rspamd{sqlite3_stmt}", sqlitestmtlib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_sqlite3", lua_load_sqlite3); |
@@ -441,17 +441,7 @@ lua_load_trie (lua_State *L) | |||
void | |||
luaopen_trie (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{trie}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{trie}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, trielib_m); | |||
rspamd_lua_new_class (L, "rspamd{trie}", trielib_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_trie", lua_load_trie); | |||
lua_pop (L, 1); /* remove metatable from stack */ | |||
} |
@@ -569,30 +569,10 @@ lua_load_upstream_list (lua_State * L) | |||
void | |||
luaopen_upstream (lua_State * L) | |||
{ | |||
luaL_newmetatable (L, "rspamd{upstream_list}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{upstream_list}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, upstream_list_m); | |||
rspamd_lua_new_class (L, "rspamd{upstream_list}", upstream_list_m); | |||
lua_pop (L, 1); | |||
rspamd_lua_add_preload (L, "rspamd_upstream_list", lua_load_upstream_list); | |||
lua_pop (L, 1); /* remove metatable from stack */ | |||
luaL_newmetatable (L, "rspamd{upstream}"); | |||
lua_pushstring (L, "__index"); | |||
lua_pushvalue (L, -2); | |||
lua_settable (L, -3); | |||
lua_pushstring (L, "class"); | |||
lua_pushstring (L, "rspamd{upstream}"); | |||
lua_rawset (L, -3); | |||
luaL_register (L, NULL, upstream_m); | |||
lua_pop (L, 1); /* remove metatable from stack */ | |||
rspamd_lua_new_class (L, "rspamd{upstream}", upstream_m); | |||
lua_pop (L, 1); | |||
} |