diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-05-24 16:28:17 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-05-24 16:29:02 +0100 |
commit | 92ec3e389a7d4b4f6898fa347c35b9256bfcb792 (patch) | |
tree | a1321b6ce583782d100c59a815288387c3e9ff67 /contrib | |
parent | 4626766ee1cbe74b33f3194d8dda97880e8c5c2e (diff) | |
download | rspamd-92ec3e389a7d4b4f6898fa347c35b9256bfcb792.tar.gz rspamd-92ec3e389a7d4b4f6898fa347c35b9256bfcb792.zip |
[Minor] Adopt lpeg for aarch64 and luajit
Issue: #2906
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/lua-lpeg/lptree.c | 15 | ||||
-rw-r--r-- | contrib/lua-lpeg/lptypes.h | 8 | ||||
-rw-r--r-- | contrib/lua-lpeg/lpvm.c | 62 |
3 files changed, 82 insertions, 3 deletions
diff --git a/contrib/lua-lpeg/lptree.c b/contrib/lua-lpeg/lptree.c index f1016c3db..7a91931bf 100644 --- a/contrib/lua-lpeg/lptree.c +++ b/contrib/lua-lpeg/lptree.c @@ -1147,23 +1147,34 @@ static size_t initposition (lua_State *L, size_t len) { ** Main match function */ static int lp_match (lua_State *L) { +#ifdef LPEG_LUD_WORKAROUND + Capture *capture = lpeg_allocate_mem_low(sizeof(Capture) * INITCAPSIZE); +#else Capture capture[INITCAPSIZE]; +#endif const char *r; size_t l; Pattern *p = (getpatt(L, 1, NULL), getpattern(L, 1)); Instruction *code = (p->code != NULL) ? p->code : prepcompile(L, p, 1); const char *s = luaL_checklstring(L, SUBJIDX, &l); size_t i = initposition(L, l); - int ptop = lua_gettop(L); + int ptop = lua_gettop(L), rs; lua_pushnil(L); /* initialize subscache */ lua_pushlightuserdata(L, capture); /* initialize caplistidx */ lua_getuservalue(L, 1); /* initialize penvidx */ r = match(L, s, s + i, s + l, code, capture, ptop); if (r == NULL) { lua_pushnil(L); +#ifdef LPEG_LUD_WORKAROUND + lpeg_free_mem_low (capture); +#endif return 1; } - return getcaptures(L, s, r, ptop); + rs = getcaptures(L, s, r, ptop); +#ifdef LPEG_LUD_WORKAROUND + lpeg_free_mem_low (capture); +#endif + return rs; } diff --git a/contrib/lua-lpeg/lptypes.h b/contrib/lua-lpeg/lptypes.h index 78dff6220..7173d11d3 100644 --- a/contrib/lua-lpeg/lptypes.h +++ b/contrib/lua-lpeg/lptypes.h @@ -9,6 +9,8 @@ #define lptypes_h +#include "config.h" + #if !defined(LPEG_DEBUG) #define NDEBUG #endif @@ -149,6 +151,12 @@ typedef struct Charset { #define testchar(st,c) (((int)(st)[((c) >> 3)] & (1 << ((c) & 7)))) +/* Special workaround for luajit */ +#if defined(WITH_LUAJIT) && !(defined(_X86_) || defined(__x86_64__) || defined(__i386__)) +# define LPEG_LUD_WORKAROUND 1 +#endif +void * lpeg_allocate_mem_low(size_t sz); +void lpeg_free_mem_low(void *p); #endif diff --git a/contrib/lua-lpeg/lpvm.c b/contrib/lua-lpeg/lpvm.c index eaf2ebfd7..711fe026d 100644 --- a/contrib/lua-lpeg/lpvm.c +++ b/contrib/lua-lpeg/lpvm.c @@ -3,6 +3,8 @@ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ +#include "config.h" + #include <limits.h> #include <string.h> @@ -15,6 +17,53 @@ #include "lpvm.h" #include "lpprint.h" +#include <sys/mman.h> + +static uint64_t xorshifto_seed[2] = {0xdeadbabe, 0xdeadbeef}; + +static inline uint64_t +xoroshiro_rotl (const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +void * +lpeg_allocate_mem_low (size_t sz) +{ + unsigned char *cp; + unsigned flags = MAP_PRIVATE | MAP_ANON; + void *base_addr = NULL; + +#ifdef MAP_32BIT + flags |= MAP_32BIT; +#else + const uint64_t s0 = xorshifto_seed[0]; + uint64_t s1 = xorshifto_seed[1]; + + s1 ^= s0; + xorshifto_seed[0] = xoroshiro_rotl(s0, 55) ^ s1 ^ (s1 << 14); + xorshifto_seed[1] = xoroshiro_rotl (s1, 36); + flags |= MAP_FIXED; + /* Get 46 bits */ + base_addr = (void *)((xorshifto_seed[0] + xorshifto_seed[1]) & 0x7FFFFFFFF000ULL); +#endif + + cp = mmap (base_addr, sz + sizeof (sz), PROT_WRITE | PROT_READ, + flags, -1, 0); + assert (cp != NULL); + memcpy (cp, &sz, sizeof (sz)); + + return cp + sizeof (sz); +} + +void +lpeg_free_mem_low(void *p) +{ + unsigned char *cp = (unsigned char *)p; + size_t sz; + + memcpy (&sz, cp - sizeof (sz), sizeof (sz)); + munmap (cp - sizeof (sz), sz + sizeof (sz)); +} /* initial size for call/backtrack stack */ #if !defined(INITBACK) @@ -146,7 +195,11 @@ static int removedyncap (lua_State *L, Capture *capture, */ const char *match (lua_State *L, const char *o, const char *s, const char *e, Instruction *op, Capture *capture, int ptop) { +#ifdef LPEG_LUD_WORKAROUND + Stack *stackbase = lpeg_allocate_mem_low(sizeof (Stack) * INITBACK); +#else Stack stackbase[INITBACK]; +#endif Stack *stacklimit = stackbase + INITBACK; Stack *stack = stackbase; /* point to first empty slot in stack */ int capsize = INITCAPSIZE; @@ -168,10 +221,16 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, assert(stack == getstackbase(L, ptop) + 1); capture[captop].kind = Cclose; capture[captop].s = NULL; +#ifdef LPEG_LUD_WORKAROUND + lpeg_free_mem_low(stackbase); +#endif return s; } case IGiveup: { assert(stack == getstackbase(L, ptop)); +#ifdef LPEG_LUD_WORKAROUND + lpeg_free_mem_low(stackbase); +#endif return NULL; } case IRet: { @@ -306,7 +365,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, capsize = 2 * captop; } /* add new captures to 'capture' list */ - adddyncaptures(s, capture + captop - n - 2, n, fr); + adddyncaptures(s, capture + captop - n - 2, n, fr); } p++; continue; @@ -348,6 +407,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, default: assert(0); return NULL; } } + } /* }====================================================== */ |