commit 92ec3e3: [Minor] Adopt lpeg for aarch64 and luajit

Vsevolod Stakhov vsevolod at highsecure.ru
Fri May 24 15:35:09 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-05-24 16:28:17 +0100
URL: https://github.com/rspamd/rspamd/commit/92ec3e389a7d4b4f6898fa347c35b9256bfcb792 (HEAD -> master)

[Minor] Adopt lpeg for aarch64 and luajit
Issue: #2906

---
 contrib/lua-lpeg/lptree.c  | 15 +++++++++--
 contrib/lua-lpeg/lptypes.h |  8 ++++++
 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;
     }
   }
+
 }
 
 /* }====================================================== */


More information about the Commits mailing list