]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Adopt lpeg for aarch64 and luajit
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 24 May 2019 15:28:17 +0000 (16:28 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 24 May 2019 15:29:02 +0000 (16:29 +0100)
Issue: #2906

contrib/lua-lpeg/lptree.c
contrib/lua-lpeg/lptypes.h
contrib/lua-lpeg/lpvm.c

index f1016c3dbd93c2f38624475516729a375851d8de..7a91931bf351a3afef46ffe41b3287cfbeaf735d 100644 (file)
@@ -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;
 }
 
 
index 78dff6220aa0c5790caf63fec32a51ca39e315f3..7173d11d3ada3206550d47633aef37ff4655b812 100644 (file)
@@ -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
 
index eaf2ebfd7271cc4dce0c1ca99824d87223e758da..711fe026dc44122f53ed75fa471395c795e25ce4 100644 (file)
@@ -3,6 +3,8 @@
 ** Copyright 2007, Lua.org & PUC-Rio  (see 'lpeg.html' for license)
 */
 
+#include "config.h"
+
 #include <limits.h>
 #include <string.h>
 
 #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;
     }
   }
+
 }
 
 /* }====================================================== */