From 147871ce1d93dc5d55baaf17ee3a60de9ea35cc7 Mon Sep 17 00:00:00 2001
From: Luigi Scarso <luigi.scarso@gmail.com>
Date: Sun, 5 Jan 2025 12:51:17 +0100
Subject: [PATCH] dos2unix of some files under luaffi/

---
 source/texk/web2c/luatexdir/luaffi/call.c     |  630 +-
 source/texk/web2c/luatexdir/luaffi/call_arm.h | 4498 +++++++--------
 .../web2c/luatexdir/luaffi/call_arm64.dasc    | 2992 +++++-----
 .../texk/web2c/luatexdir/luaffi/call_arm64.h  | 4876 ++++++++--------
 .../texk/web2c/luatexdir/luaffi/call_arm_hf.h | 5060 ++++++++---------
 source/texk/web2c/luatexdir/luaffi/ctype.c    |  630 +-
 .../texk/web2c/luatexdir/luaffi/fake_dlfcn.c  |  328 +-
 .../texk/web2c/luatexdir/luaffi/fake_dlfcn.h  |   40 +-
 .../texk/web2c/luatexdir/luatex_svnversion.h  |    2 +-
 9 files changed, 9528 insertions(+), 9528 deletions(-)

diff --git a/source/texk/web2c/luatexdir/luaffi/call.c b/source/texk/web2c/luatexdir/luaffi/call.c
index 90b464e31..09f38ed38 100644
--- a/source/texk/web2c/luatexdir/luaffi/call.c
+++ b/source/texk/web2c/luatexdir/luaffi/call.c
@@ -1,315 +1,315 @@
-/* vim: ts=4 sw=4 sts=4 et tw=78
- * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
- * Portions copyright (c) 2011 James R. McKaskill.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-#include "ffi.h"
-
-static cfunction compile(Dst_DECL, lua_State* L, cfunction func, int ref);
-
-static void* reserve_code(struct jit* jit, lua_State* L, size_t sz);
-static void commit_code(struct jit *jit, size_t sz);
-
-static void push_int(lua_State* L, int val)
-{ lua_pushinteger(L, val); }
-
-static void push_uint(lua_State* L, unsigned int val)
-{ lua_pushinteger(L, val); }
-
-static void push_float(lua_State* L, float val)
-{ lua_pushnumber(L, val); }
-
-#ifdef NDEBUG
-#define shred(a,b,c)
-#else
-#define shred(p,s,e) memset((uint8_t*)(p)+(s),0xCC,(e)-(s))
-#endif
-
-
-#ifdef _WIN64
-#include "dynasm/dasm_x86.h"
-#include "call_x64win.h"
-#elif defined __amd64__
-#include "dynasm/dasm_x86.h"
-#include "call_x64.h"
-#elif defined(ARCH_ARM)
-#include "dynasm/dasm_arm.h"
-//See http://code.google.com/p/v8/issues/detail?id=2140 for more information
-#if defined(__ARM_PCS_VFP) || (GCC_VERSION==40500||defined(__clang__))&&!defined(__ARM_PCS) && !defined(__SOFTFP__) && !defined(__SOFTFP) && \
-    defined(__VFP_FP__)
-#include "call_arm_hf.h"
-#else
-#include "call_arm.h"
-#endif
-#elif defined ARCH_ARM64
-#include "dynasm/dasm_arm64.h"
-#include "call_arm64.h"
-#else
-#include "dynasm/dasm_x86.h"
-#include "call_x86.h"
-#endif
-
-struct jit_head {
-    size_t size;
-    int ref;
-#ifndef NO_FUNCTION_EXTERN
-    uint8_t jump[JUMP_SIZE];
-#endif
-};
-
-#define LINKTABLE_MAX_SIZE ((sizeof(extnames) / sizeof(extnames[0])-1) * (JUMP_SIZE))
-
-static cfunction compile(struct jit* jit, lua_State* L, cfunction func, int ref)
-{
-    struct jit_head* code;
-    size_t codesz;
-    int err;
-
-    dasm_checkstep(jit, -1);
-    if ((err = dasm_link(jit, &codesz)) != 0) {
-        char buf[32];
-        sprintf(buf, "%x", err);
-        luaL_error(L, "dasm_link error %s", buf);
-    }
-
-    codesz += sizeof(struct jit_head);
-    code = (struct jit_head*) reserve_code(jit, L, codesz);
-    code->ref = ref;
-    code->size = codesz;
-#ifndef NO_FUNCTION_EXTERN
-    compile_extern_jump(jit, L, func, code->jump);
-#endif
-
-    if ((err = dasm_encode(jit, code+1)) != 0) {
-        char buf[32];
-        sprintf(buf, "%x", err);
-        commit_code(jit, 0);
-        luaL_error(L, "dasm_encode error %s", buf);
-    }
-
-    commit_code(jit, codesz);
-    cfunction ret = (cfunction) (code + 1);
-    return ret;
-}
-
-typedef uint8_t jump_t[JUMP_SIZE];
-
-int get_extern(struct jit* jit, uint8_t* addr, int idx, int type)
-{
-    struct page* page = jit->pages[jit->pagenum-1];
-    jump_t* jumps = (jump_t*) (page+1);
-    struct jit_head* h = (struct jit_head*) ((uint8_t*) page + page->off);
-    uint8_t* jmp;
-    ptrdiff_t off;
-#ifndef NO_FUNCTION_EXTERN
-    if (idx == jit->function_extern) {
-       jmp = h->jump;
-    } else
-#endif
-    {
-       jmp = jumps[idx];
-    }
-
-    /* compensate for room taken up for the offset so that we can work rip
-     * relative */
-    addr += BRANCH_OFF;
-
-    /* see if we can fit the offset in the branch displacement, if not use the
-     * jump instruction */
-    off = *(uint8_t**) jmp - addr;
-
-    if (MIN_BRANCH <= off && off <= MAX_BRANCH
-        // thumb address must be called by extern jump rather than direct jump
-#ifdef ARCH_ARM
-        &&((*(uintptr_t*) jmp)&1)==0
-#endif
-            ) {
-        return (int32_t) off;
-    } else {
-        return (int32_t)(jmp + sizeof(uint8_t*) - addr);
-    }
-}
-static void rawgeti(lua_State* L,int idx,ptrdiff_t key){
-     lua_rawgeti(L,idx,key);
-}
-
-static void* reserve_code(struct jit* jit, lua_State* L, size_t sz)
-{
-    struct page* page;
-    size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0;
-    size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0;
-
-    if (off + sz >= size) {
-        int i;
-        uint8_t* pdata;
-        cfunction func;
-
-        /* need to create a new page */
-        jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0]));
-
-        size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size);
-
-        page = (struct page*) AllocPage(size);
-        jit->pages[jit->pagenum-1] = page;
-        pdata = (uint8_t*) page;
-        page->size = size;
-        page->off = sizeof(struct page);
-        if(jit->default_functions!=NULL){
-            memcpy((uint8_t*)(page+1),jit->default_functions,LINKTABLE_MAX_SIZE);
-            page->off+=LINKTABLE_MAX_SIZE;
-            page->freed=page->off;
-            goto End;
-        }
-
-        lua_newtable(L);
-
-#define ADD_FUNC_WITH_NAME(DLL, NAME,FUNC) \
-        lua_pushliteral(L, #NAME); \
-        func = DLL ? (cfunction) GetProcAddressA(DLL, #FUNC) : NULL; \
-        func = func ? func : (cfunction) &FUNC; \
-        lua_pushcfunction(L, (lua_CFunction) func); \
-        lua_rawset(L, -3)
-
-#define ADDFUNC(DLL, NAME) ADD_FUNC_WITH_NAME(DLL,NAME,NAME)
-
-        ADDFUNC(NULL, check_double);
-        ADDFUNC(NULL, check_float);
-        ADDFUNC(NULL, check_uint64);
-        ADDFUNC(NULL, check_int64);
-        ADDFUNC(NULL, check_int32);
-        ADDFUNC(NULL, check_uint32);
-        ADDFUNC(NULL, check_uintptr);
-        ADDFUNC(NULL, check_enum);
-        ADDFUNC(NULL, check_struct);
-        ADDFUNC(NULL, check_typed_pointer);
-        ADDFUNC(NULL, check_typed_cfunction);
-        ADDFUNC(NULL, check_complex_double);
-        ADDFUNC(NULL, check_complex_float);
-        ADDFUNC(NULL, unpack_varargs_stack);
-        ADDFUNC(NULL, unpack_varargs_stack_skip);
-        ADDFUNC(NULL, unpack_varargs_reg);
-        ADDFUNC(NULL, unpack_varargs_float);
-        ADDFUNC(NULL, unpack_varargs_int);
-        ADDFUNC(NULL, memcpy);//for x86,x64 only
-#if ARM_HF
-        ADDFUNC(NULL, unpack_varargs_bound);
-#endif
-        ADDFUNC(NULL, push_cdata);
-        ADDFUNC(NULL, push_int);
-        ADDFUNC(NULL, push_uint);
-        ADDFUNC(NULL, lua_pushinteger);
-        ADDFUNC(NULL, push_float);
-        ADDFUNC(jit->lua_dll, luaL_error);
-        ADDFUNC(jit->lua_dll, lua_pushnumber);
-        ADDFUNC(jit->lua_dll, lua_pushboolean);
-        ADDFUNC(jit->lua_dll, lua_gettop);
-#if LUA_VERSION_NUM<503 || defined(__LP64__) || defined(__amd64__) ||defined (_WIN64)
-        ADD_FUNC_WITH_NAME(jit->lua_dll,rawgeti, lua_rawgeti);
-#else
-        ADDFUNC(NULL,rawgeti);
-
-#endif
-#if LUA_VERSION_NUM<502
-        ADD_FUNC_WITH_NAME(jit->lua_dll, lua_setuservalue,lua_setfenv);
-#else
-        ADDFUNC(jit->lua_dll, lua_setuservalue);
-#endif
-        ADDFUNC(jit->lua_dll, lua_pushnil);
-        ADDFUNC(jit->lua_dll, lua_call);
-        ADDFUNC(jit->lua_dll, lua_settop);
-        ADDFUNC(jit->lua_dll, lua_remove);
-        ADDFUNC(jit->lua_dll, lua_pushvalue);
-#undef ADDFUNC
-
-        for (i = 0; extnames[i] != NULL; i++) {
-#ifndef NO_FUNCTION_EXTERN
-            if (strcmp(extnames[i], "FUNCTION") == 0) {
-                shred(pdata + page->off, 0, JUMP_SIZE);
-                jit->function_extern = i;
-            } else
-#endif
-            {
-                lua_getfield(L, -1, extnames[i]);
-                func = (cfunction) lua_tocfunction(L, -1);
-
-                if (func == NULL) {
-                    luaL_error(L, "internal error: missing link for %s", extnames[i]);
-                }
-
-                compile_extern_jump(jit, L, func, pdata + page->off);
-                lua_pop(L, 1);
-            }
-            page->off += JUMP_SIZE;
-        }
-#ifndef NO_FUNCTION_EXTERN
-        if(jit->function_extern==0){
-            luaL_error(L, "internal error: should define extern  FUNCTION");
-        }
-#endif
-        jit->default_functions=(uint8_t*)(page+1);
-        page->freed = page->off;
-        lua_pop(L, 1);
-
-    } else {
-        page = jit->pages[jit->pagenum-1];
-        EnableWrite(page, page->size);
-    }
-    End:
-    return (uint8_t*) page + page->off;
-}
-
-static void commit_code(struct jit *jit, size_t sz)
-{
-    struct page* page = jit->pages[jit->pagenum-1];
-    page->off += sz;
-    EnableExecute(page, page->size);
-}
-
-/* push_func_ref pushes a copy of the upval table embedded in the compiled
- * function func.
- */
-void push_func_ref(lua_State* L, cfunction func)
-{
-    struct jit_head* h = ((struct jit_head*) func) - 1;
-    lua_rawgeti(L, LUA_REGISTRYINDEX, h->ref);
-}
-
-void free_code(struct jit* jit, lua_State* L, cfunction func)
-{
-    size_t i;
-    struct jit_head* h = ((struct jit_head*) func) - 1;
-    for (i = 0; i < jit->pagenum; i++) {
-        struct page* p = jit->pages[i];
-
-        if ((uint8_t*) h < (uint8_t*) p || (uint8_t*) p + p->size <= (uint8_t*) h) {
-            continue;
-        }
-
-        luaL_unref(L, LUA_REGISTRYINDEX, h->ref);
-
-        EnableWrite(p, p->size);
-        p->freed += h->size;
-
-        shred(h, 0, h->size);
-
-        if (p->freed < p->off) {
-            EnableExecute(p, p->size);
-            return;
-        }
-        if((uint8_t*)(p+1)==jit->default_functions){
-            jit->default_functions=NULL;
-        }
-        FreePage(p, p->size);
-        memmove(&jit->pages[i], &jit->pages[i+1], (jit->pagenum - (i+1)) * sizeof(jit->pages[0]));
-        jit->pagenum--;
-        return;
-    }
-
-    assert(!"couldn't find func in the jit pages");
-}
-
-
+/* vim: ts=4 sw=4 sts=4 et tw=78
+ * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+ * Portions copyright (c) 2011 James R. McKaskill.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+#include "ffi.h"
+
+static cfunction compile(Dst_DECL, lua_State* L, cfunction func, int ref);
+
+static void* reserve_code(struct jit* jit, lua_State* L, size_t sz);
+static void commit_code(struct jit *jit, size_t sz);
+
+static void push_int(lua_State* L, int val)
+{ lua_pushinteger(L, val); }
+
+static void push_uint(lua_State* L, unsigned int val)
+{ lua_pushinteger(L, val); }
+
+static void push_float(lua_State* L, float val)
+{ lua_pushnumber(L, val); }
+
+#ifdef NDEBUG
+#define shred(a,b,c)
+#else
+#define shred(p,s,e) memset((uint8_t*)(p)+(s),0xCC,(e)-(s))
+#endif
+
+
+#ifdef _WIN64
+#include "dynasm/dasm_x86.h"
+#include "call_x64win.h"
+#elif defined __amd64__
+#include "dynasm/dasm_x86.h"
+#include "call_x64.h"
+#elif defined(ARCH_ARM)
+#include "dynasm/dasm_arm.h"
+//See http://code.google.com/p/v8/issues/detail?id=2140 for more information
+#if defined(__ARM_PCS_VFP) || (GCC_VERSION==40500||defined(__clang__))&&!defined(__ARM_PCS) && !defined(__SOFTFP__) && !defined(__SOFTFP) && \
+    defined(__VFP_FP__)
+#include "call_arm_hf.h"
+#else
+#include "call_arm.h"
+#endif
+#elif defined ARCH_ARM64
+#include "dynasm/dasm_arm64.h"
+#include "call_arm64.h"
+#else
+#include "dynasm/dasm_x86.h"
+#include "call_x86.h"
+#endif
+
+struct jit_head {
+    size_t size;
+    int ref;
+#ifndef NO_FUNCTION_EXTERN
+    uint8_t jump[JUMP_SIZE];
+#endif
+};
+
+#define LINKTABLE_MAX_SIZE ((sizeof(extnames) / sizeof(extnames[0])-1) * (JUMP_SIZE))
+
+static cfunction compile(struct jit* jit, lua_State* L, cfunction func, int ref)
+{
+    struct jit_head* code;
+    size_t codesz;
+    int err;
+
+    dasm_checkstep(jit, -1);
+    if ((err = dasm_link(jit, &codesz)) != 0) {
+        char buf[32];
+        sprintf(buf, "%x", err);
+        luaL_error(L, "dasm_link error %s", buf);
+    }
+
+    codesz += sizeof(struct jit_head);
+    code = (struct jit_head*) reserve_code(jit, L, codesz);
+    code->ref = ref;
+    code->size = codesz;
+#ifndef NO_FUNCTION_EXTERN
+    compile_extern_jump(jit, L, func, code->jump);
+#endif
+
+    if ((err = dasm_encode(jit, code+1)) != 0) {
+        char buf[32];
+        sprintf(buf, "%x", err);
+        commit_code(jit, 0);
+        luaL_error(L, "dasm_encode error %s", buf);
+    }
+
+    commit_code(jit, codesz);
+    cfunction ret = (cfunction) (code + 1);
+    return ret;
+}
+
+typedef uint8_t jump_t[JUMP_SIZE];
+
+int get_extern(struct jit* jit, uint8_t* addr, int idx, int type)
+{
+    struct page* page = jit->pages[jit->pagenum-1];
+    jump_t* jumps = (jump_t*) (page+1);
+    struct jit_head* h = (struct jit_head*) ((uint8_t*) page + page->off);
+    uint8_t* jmp;
+    ptrdiff_t off;
+#ifndef NO_FUNCTION_EXTERN
+    if (idx == jit->function_extern) {
+       jmp = h->jump;
+    } else
+#endif
+    {
+       jmp = jumps[idx];
+    }
+
+    /* compensate for room taken up for the offset so that we can work rip
+     * relative */
+    addr += BRANCH_OFF;
+
+    /* see if we can fit the offset in the branch displacement, if not use the
+     * jump instruction */
+    off = *(uint8_t**) jmp - addr;
+
+    if (MIN_BRANCH <= off && off <= MAX_BRANCH
+        // thumb address must be called by extern jump rather than direct jump
+#ifdef ARCH_ARM
+        &&((*(uintptr_t*) jmp)&1)==0
+#endif
+            ) {
+        return (int32_t) off;
+    } else {
+        return (int32_t)(jmp + sizeof(uint8_t*) - addr);
+    }
+}
+static void rawgeti(lua_State* L,int idx,ptrdiff_t key){
+     lua_rawgeti(L,idx,key);
+}
+
+static void* reserve_code(struct jit* jit, lua_State* L, size_t sz)
+{
+    struct page* page;
+    size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0;
+    size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0;
+
+    if (off + sz >= size) {
+        int i;
+        uint8_t* pdata;
+        cfunction func;
+
+        /* need to create a new page */
+        jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0]));
+
+        size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size);
+
+        page = (struct page*) AllocPage(size);
+        jit->pages[jit->pagenum-1] = page;
+        pdata = (uint8_t*) page;
+        page->size = size;
+        page->off = sizeof(struct page);
+        if(jit->default_functions!=NULL){
+            memcpy((uint8_t*)(page+1),jit->default_functions,LINKTABLE_MAX_SIZE);
+            page->off+=LINKTABLE_MAX_SIZE;
+            page->freed=page->off;
+            goto End;
+        }
+
+        lua_newtable(L);
+
+#define ADD_FUNC_WITH_NAME(DLL, NAME,FUNC) \
+        lua_pushliteral(L, #NAME); \
+        func = DLL ? (cfunction) GetProcAddressA(DLL, #FUNC) : NULL; \
+        func = func ? func : (cfunction) &FUNC; \
+        lua_pushcfunction(L, (lua_CFunction) func); \
+        lua_rawset(L, -3)
+
+#define ADDFUNC(DLL, NAME) ADD_FUNC_WITH_NAME(DLL,NAME,NAME)
+
+        ADDFUNC(NULL, check_double);
+        ADDFUNC(NULL, check_float);
+        ADDFUNC(NULL, check_uint64);
+        ADDFUNC(NULL, check_int64);
+        ADDFUNC(NULL, check_int32);
+        ADDFUNC(NULL, check_uint32);
+        ADDFUNC(NULL, check_uintptr);
+        ADDFUNC(NULL, check_enum);
+        ADDFUNC(NULL, check_struct);
+        ADDFUNC(NULL, check_typed_pointer);
+        ADDFUNC(NULL, check_typed_cfunction);
+        ADDFUNC(NULL, check_complex_double);
+        ADDFUNC(NULL, check_complex_float);
+        ADDFUNC(NULL, unpack_varargs_stack);
+        ADDFUNC(NULL, unpack_varargs_stack_skip);
+        ADDFUNC(NULL, unpack_varargs_reg);
+        ADDFUNC(NULL, unpack_varargs_float);
+        ADDFUNC(NULL, unpack_varargs_int);
+        ADDFUNC(NULL, memcpy);//for x86,x64 only
+#if ARM_HF
+        ADDFUNC(NULL, unpack_varargs_bound);
+#endif
+        ADDFUNC(NULL, push_cdata);
+        ADDFUNC(NULL, push_int);
+        ADDFUNC(NULL, push_uint);
+        ADDFUNC(NULL, lua_pushinteger);
+        ADDFUNC(NULL, push_float);
+        ADDFUNC(jit->lua_dll, luaL_error);
+        ADDFUNC(jit->lua_dll, lua_pushnumber);
+        ADDFUNC(jit->lua_dll, lua_pushboolean);
+        ADDFUNC(jit->lua_dll, lua_gettop);
+#if LUA_VERSION_NUM<503 || defined(__LP64__) || defined(__amd64__) ||defined (_WIN64)
+        ADD_FUNC_WITH_NAME(jit->lua_dll,rawgeti, lua_rawgeti);
+#else
+        ADDFUNC(NULL,rawgeti);
+
+#endif
+#if LUA_VERSION_NUM<502
+        ADD_FUNC_WITH_NAME(jit->lua_dll, lua_setuservalue,lua_setfenv);
+#else
+        ADDFUNC(jit->lua_dll, lua_setuservalue);
+#endif
+        ADDFUNC(jit->lua_dll, lua_pushnil);
+        ADDFUNC(jit->lua_dll, lua_call);
+        ADDFUNC(jit->lua_dll, lua_settop);
+        ADDFUNC(jit->lua_dll, lua_remove);
+        ADDFUNC(jit->lua_dll, lua_pushvalue);
+#undef ADDFUNC
+
+        for (i = 0; extnames[i] != NULL; i++) {
+#ifndef NO_FUNCTION_EXTERN
+            if (strcmp(extnames[i], "FUNCTION") == 0) {
+                shred(pdata + page->off, 0, JUMP_SIZE);
+                jit->function_extern = i;
+            } else
+#endif
+            {
+                lua_getfield(L, -1, extnames[i]);
+                func = (cfunction) lua_tocfunction(L, -1);
+
+                if (func == NULL) {
+                    luaL_error(L, "internal error: missing link for %s", extnames[i]);
+                }
+
+                compile_extern_jump(jit, L, func, pdata + page->off);
+                lua_pop(L, 1);
+            }
+            page->off += JUMP_SIZE;
+        }
+#ifndef NO_FUNCTION_EXTERN
+        if(jit->function_extern==0){
+            luaL_error(L, "internal error: should define extern  FUNCTION");
+        }
+#endif
+        jit->default_functions=(uint8_t*)(page+1);
+        page->freed = page->off;
+        lua_pop(L, 1);
+
+    } else {
+        page = jit->pages[jit->pagenum-1];
+        EnableWrite(page, page->size);
+    }
+    End:
+    return (uint8_t*) page + page->off;
+}
+
+static void commit_code(struct jit *jit, size_t sz)
+{
+    struct page* page = jit->pages[jit->pagenum-1];
+    page->off += sz;
+    EnableExecute(page, page->size);
+}
+
+/* push_func_ref pushes a copy of the upval table embedded in the compiled
+ * function func.
+ */
+void push_func_ref(lua_State* L, cfunction func)
+{
+    struct jit_head* h = ((struct jit_head*) func) - 1;
+    lua_rawgeti(L, LUA_REGISTRYINDEX, h->ref);
+}
+
+void free_code(struct jit* jit, lua_State* L, cfunction func)
+{
+    size_t i;
+    struct jit_head* h = ((struct jit_head*) func) - 1;
+    for (i = 0; i < jit->pagenum; i++) {
+        struct page* p = jit->pages[i];
+
+        if ((uint8_t*) h < (uint8_t*) p || (uint8_t*) p + p->size <= (uint8_t*) h) {
+            continue;
+        }
+
+        luaL_unref(L, LUA_REGISTRYINDEX, h->ref);
+
+        EnableWrite(p, p->size);
+        p->freed += h->size;
+
+        shred(h, 0, h->size);
+
+        if (p->freed < p->off) {
+            EnableExecute(p, p->size);
+            return;
+        }
+        if((uint8_t*)(p+1)==jit->default_functions){
+            jit->default_functions=NULL;
+        }
+        FreePage(p, p->size);
+        memmove(&jit->pages[i], &jit->pages[i+1], (jit->pagenum - (i+1)) * sizeof(jit->pages[0]));
+        jit->pagenum--;
+        return;
+    }
+
+    assert(!"couldn't find func in the jit pages");
+}
+
+
diff --git a/source/texk/web2c/luatexdir/luaffi/call_arm.h b/source/texk/web2c/luatexdir/luaffi/call_arm.h
index 1db7b2ff4..3d1ce33e6 100644
--- a/source/texk/web2c/luatexdir/luaffi/call_arm.h
+++ b/source/texk/web2c/luatexdir/luaffi/call_arm.h
@@ -1,2249 +1,2249 @@
-/*
-** This file has been pre-processed with DynASM.
-** http://luajit.org/dynasm.html
-** DynASM version 1.4.0, DynASM arm version 1.4.0
-** DO NOT EDIT! The original file is in "call_arm.dasc".
-*/
-
-/* vim: ts=4 sw=4 sts=4 et tw=78
- * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
- * Portions copyright (c) 2011 James R. McKaskill.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
- 
-//The generate code is for arm not for thumb
-#if DASM_VERSION != 10400
-#error "Version mismatch between DynASM and included encoding engine"
-#endif
-
-static const unsigned int build_actionlist[743] = {
-0xe28dc000,
-0x000b0000,
-0xe89c100e,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c100e,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c0006,
-0x00000000,
-0xe51d1000,
-0x000e8180,
-0x00000000,
-0xe2866000,
-0x000b0000,
-0x00000000,
-0xe8b6100e,
-0x00000000,
-0xe8b60006,
-0x00000000,
-0xe4961004,
-0x00000000,
-0xe1a0c00d,
-0xe92d000f,
-0x00000000,
-0xe92d5050,
-0xe1a0600c,
-0xe3004000,
-0x000c0200,
-0xe3404000,
-0x000c0200,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe5801000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe5801000,
-0x00000000,
-0xe28d1000,
-0x000b0000,
-0x00000000,
-0xe1a01006,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe12fff3c,
-0x00000000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe880100e,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe8800006,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c000c,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe8b6000c,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030003,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe8800006,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe5801000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030004,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030005,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030006,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c000c,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe8b6000c,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030007,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3a01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030008,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3e02000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030009,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3e02000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003000a,
-0xe1a06000,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0x00000000,
-0xe5960000,
-0x00000000,
-0xe51d0000,
-0x000e8180,
-0xe1a01006,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe12fff3c,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3e02000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003000c,
-0x00000000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0x00000000,
-0xe3e01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000d,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe3500000,
-0x13a00001,
-0x00000000,
-0xe6ef0070,
-0x00000000,
-0xe6af0070,
-0x00000000,
-0xe6ff0070,
-0x00000000,
-0xe6bf0070,
-0x00000000,
-0xe3e01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000f,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030010,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030011,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030012,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030013,
-0x00000000,
-0xe3e02000,
-0xe1a01004,
-0xe51d0000,
-0x000e8180,
-0xeb000000,
-0x00030014,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0x00000000,
-0xe3e02000,
-0xe1a01004,
-0xe51d0000,
-0x000e8180,
-0xeb000000,
-0x00030015,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0x00000000,
-0xe1a06000,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0xe1a00006,
-0x00000000,
-0xe1a06000,
-0xe1a00004,
-0xe1a04001,
-0xe3e01002,
-0xeb000000,
-0x0003000b,
-0xe1a00006,
-0xe1a01004,
-0x00000000,
-0xe89da050,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe8a60003,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe88c0003,
-0x00000000,
-0xe4860004,
-0x00000000,
-0xe50d0000,
-0x000e8180,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xeca60a01,
-0x00000000,
-0xeca60b02,
-0x00000000,
-0xeca60a04,
-0x00000000,
-0xeca60b04,
-0x00000000,
-0xeca60b06,
-0x00000000,
-0xeca60b08,
-0x00000000,
-0xe92d40f0,
-0xe28d700c,
-0x00000000,
-0xe92d4870,
-0xe28db00c,
-0x00000000,
-0xe24dd004,
-0x00000000,
-0xe1a04000,
-0x00000000,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe04dd00c,
-0x00000000,
-0xe24dd000,
-0x000b0000,
-0x00000000,
-0xeb000000,
-0x00030016,
-0xe3500000,
-0x000b0000,
-0xaa000000,
-0x00050001,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030017,
-0x0006000b,
-0xe1a05000,
-0xe04dd185,
-0x00000000,
-0xe28d6000,
-0x000b0000,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe50d0000,
-0x000e8180,
-0x00000000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0x000b0000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030009,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030018,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000c,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000a,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe1a01000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0x00000000,
-0xe28d0000,
-0x000b0000,
-0x00000000,
-0xe1a00006,
-0x00000000,
-0xe12fff3c,
-0x00000000,
-0xe2866000,
-0x000b0000,
-0x00000000,
-0xe3a01000,
-0x000b0000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0xe3500000,
-0x13a00001,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe6ef0070,
-0x00000000,
-0xe6af0070,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe6ff0070,
-0x00000000,
-0xe6bf0070,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000d,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030011,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000f,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030010,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030013,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030012,
-0x00000000,
-0xe1a02001,
-0xe1a01004,
-0x00000000,
-0xe28d0000,
-0x000b0000,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe1a00006,
-0x00000000,
-0xeb000000,
-0x00030014,
-0x00000000,
-0xe1a02001,
-0xe1a01004,
-0x00000000,
-0xe28d0000,
-0x000b0000,
-0x00000000,
-0xe1a00006,
-0x00000000,
-0xeb000000,
-0x00030015,
-0x00000000,
-0xe2866000,
-0x000b0000,
-0x00000000,
-0xe3a01000,
-0x000b0000,
-0x00000000,
-0xe1a03006,
-0x00000000,
-0xe28d3000,
-0x000b0000,
-0x00000000,
-0xe1a02005,
-0xe1a00004,
-0xeb000000,
-0x00030019,
-0x00000000,
-0xe8bd000f,
-0x00000000,
-0xe8bd0003,
-0x00000000,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe12fff3c,
-0x00000000,
-0xe1a06000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0xe3a00001,
-0x00000000,
-0xe1a03001,
-0xe1a02000,
-0x00000000,
-0xe1a02001,
-0xe1a01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030003,
-0xe3a00001,
-0x00000000,
-0xe1a06000,
-0xe1a05001,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0xe5805004,
-0xe3a00001,
-0x00000000,
-0xe1a06000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0xe3a00001,
-0x00000000,
-0xe3a00000,
-0x00000000,
-0xe1a01000,
-0xe1a00004,
-0xeb000000,
-0x00030004,
-0xe3a00001,
-0x00000000,
-0xe1a01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003001a,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030005,
-0x00000000,
-0xe3a00001,
-0x00000000,
-0xe1a01000,
-0xe1a00004,
-0xeb000000,
-0x00030006,
-0xe3a00001,
-0x00000000,
-0xe1a03001,
-0xe1a02000,
-0x00000000,
-0xe1a02001,
-0xe1a01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030007,
-0xe3a00001,
-0x00000000,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x0003001b,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003001c,
-0x00000000,
-0xe3a00000,
-0x00000000,
-0xe1a06000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0x00000000,
-0xe3a00001,
-0x00000000,
-0xe247d00c,
-0xe8bd80f0,
-0x00000000,
-0xe24bd00c,
-0xe8bd8870,
-0x00000000
-};
-
-static const char *const globnames[] = {
-  (const char *)0
-};
-static const char *const extnames[] = {
-  "rawgeti",
-  "push_cdata",
-  "lua_remove",
-  "lua_pushinteger",
-  "lua_pushboolean",
-  "push_int",
-  "push_float",
-  "lua_pushnumber",
-  "lua_call",
-  "check_typed_pointer",
-  "check_struct",
-  "lua_settop",
-  "check_enum",
-  "check_uint32",
-  "check_int32",
-  "check_uint64",
-  "check_int64",
-  "check_uintptr",
-  "check_float",
-  "check_double",
-  "check_complex_double",
-  "check_complex_float",
-  "lua_gettop",
-  "luaL_error",
-  "check_typed_cfunction",
-  "unpack_varargs_stack",
-  "push_uint",
-  "lua_pushvalue",
-  "lua_setuservalue",
-  (const char *)0
-};
-
-#define JUMP_SIZE 8
-
-#define MIN_BRANCH ((INT32_MIN) >> 8)
-#define MAX_BRANCH ((INT32_MAX) >> 8)
-//arm pc offset 8 so comparing with next instruction is 4,
-//unlike x86 which pass in the current instruction address+1 rather than the next instruction 
-#define BRANCH_OFF 4	
-
-
-#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
-#ifdef TARGET_OS_IPHONE
-#define  CK_ALGIN  0
-#else
-#define  CK_ALGIN  1
-#endif
-#define ALIGNED(x, align) (!CK_ALGIN||((int)(x) & (align - 1)) == 0)
-#if defined(__ARM_PCS_VFP) || (GCC_VERSION==40500||defined(__clang__))&&!defined(__ARM_PCS) && !defined(__SOFTFP__) && !defined(__SOFTFP) && \
-    defined(__VFP_FP__)
-#define ARM_HF 1
-#else
-#define ARM_HF 0
-#endif
-#if ARM_HF&&!CK_ALGIN
-#error "Unsupported unaligned stack for hard floating point"
-#endif	
-
-static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
-{
-    /* The jump code is the function pointer followed by a stub to call the
-     * function pointer. The stub exists so we can jump to functions with an
-     * offset greater than 32MB.
-     *
-     * Note we have to manually set this up since there are commands buffered
-     * in the jit state.
-     */
-	
-    *(cfunction*) code = func;
-     //ldr pc, [pc - 12]
-    *(uint32_t*) &code[4] = 0xE51FF00CU; 
-	
-}
-
-
-
-
-void compile_globals(struct jit* jit, lua_State* L)
-{
-    (void) jit;
-}
-
-typedef struct stack_info{
-	int extra;
-	int int_off;
-	int stack_off;
-	int float_size;
-#if ARM_HF
-	int float_off; 
-#endif	
-} stack_info;
-//vfp use back-filling rule for registers until a float value on stack
-typedef struct reg_info{
-	uint16_t exs;	
-	union{
-		uint8_t ints;
-		uint8_t regs;
-	};
-#if ARM_HF
-	uint8_t float_sealed;
-	short floats;//each bit is a float: s0-s15 or v0-v7 or q0-q3
-	uint8_t left_single;
-	uint8_t highest_bit;
-#endif
-} reg_info;
-
-#define MAX_REGS 4
-#define MAX_FLOAT_REGS 16
-#ifndef bool
-#define bool uint8_t
-#endif
-
-#define has_bit(x,b) (((x)&(1<<(b)))!=0)
-#define set_bit(x,b) (x=((x)|(1<<(b)))) 
-#define FIX_ALIGN(x,al) \
-	if(!ALIGNED((x),al)){\
-		x=ROUND_UP(x,al);\
-	}
-static ALWAYS_INLINE bool is_float_sealed(reg_info* regs){
-#if ARM_HF
-return regs->float_sealed;
-#else
-return regs->regs>=MAX_REGS;
-#endif
-}
-//return size need to put on stack
-static ALWAYS_INLINE int add_int_reg(reg_info* regs){
-	if(regs->regs<MAX_REGS){
-		regs->regs++;
-		return 0;
-	}
-	return 1;
-		
-}
-//return size need to put on stack
-static ALWAYS_INLINE int add_int64_reg(reg_info* regs){
-	if(regs->regs<MAX_REGS-1){
-		regs->regs=ROUND_UP(regs->regs,2)+2;
-		return 0;
-	}else if(regs->regs==MAX_REGS-1){
-		regs->regs=MAX_REGS;
-	}
-		
-	return 2;
-}
-static ALWAYS_INLINE bool is_float_type(int t){
-    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
-}
-static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
-	struct ctype* mt;
-	int type,ele_count,i,ct_usr;
-	lua_getuservalue(L,idx);
-	ct_usr=lua_absindex(L,-1);
-    lua_rawgeti(L,ct_usr,1);
-    mt=(struct ctype*)lua_touserdata(L,-1);
-    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-        lua_pop(L,2);
-		if(ct->type==COMPLEX_DOUBLE_TYPE){
-			if(isfloat) *isfloat=0;
-			return 4;
-		}else if(ct->type==COMPLEX_FLOAT_TYPE){
-			if(isfloat) *isfloat=1;
-			return 2;
-		}
-        return 0;
-    }
-	type=mt->type;
-    ele_count=(int)(ct->base_size/mt->base_size);
-    if(ele_count>4||ct->base_size%mt->base_size){
-        lua_pop(L,2);
-        return 0;
-    }
-	lua_pop(L,1);
-    for (i = 2; i <=4 ; ++i) {
-        lua_rawgeti(L,ct_usr,i);
-		if(lua_isnil(L,-1)){//case have array member;
-            lua_pop(L,1);
-            break;
-        }
-        mt=(struct ctype*)lua_touserdata(L,-1);
-        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-            lua_pop(L,2);
-            return 0;
-        }
-        lua_pop(L,1);
-    }
-	if(isfloat){
-		*isfloat=mt->type==FLOAT_TYPE;
-	}
-	lua_pop(L,1);
-    return ele_count*(mt->type==FLOAT_TYPE?1:2);
-}
-#if ARM_HF
-static void save_float_reg(struct jit* Dst,int reg,int size,stack_info* st){
-	int sz;
-	if(reg==-1) return;
-	for(;size>0;size-=8){
-		sz=size>8?8:size;
-		switch(sz){
-		case 4:
-			switch(reg){
-				case 0:
-					break;
-				case 1:
-					break;
-				case 2:
-					break;
-				case 3:
-					break;
-				case 4:
-					break;
-				case 5:
-					break;
-				case 6:
-					break;
-				case 7:
-					break;
-				case 8:
-					break;
-				case 9:
-					break;
-				case 10:
-					break;
-				case 11:
-					break;
-				case 12:
-					break;
-				case 13:
-					break;
-				case 14:
-					break;
-				case 15:
-					break;
-			}
-			break;
-		case 8:
-			switch(reg>>1){
-				case 0:
-					break;
-				case 1:
-					break;
-				case 2:
-					break;
-				case 3:
-					break;
-				case 4:
-					break;
-				case 5:
-					break;
-				case 6:
-					break;
-				case 7:
-					break;
-			}
-			reg+=2;
-			break;
-		}
-		st->float_size+=sz;
-	}
-}
-
-//128 bit vector type is not supported by this
-static int add_float_reg(reg_info* regs,int sz,int isfloat){
-
-	if(is_float_sealed(regs)) return -1;
-	int i,ret=-1;
-	if(sz==1){
-		if(regs->left_single){
-			int n=regs->highest_bit;
-			for(i=0;i<n;++i){
-				if(!has_bit(regs->floats,i)){
-					regs->left_single--;
-					set_bit(regs->floats,i);
-					ret=i;
-				}
-			}
-		}else{
-			ret=regs->highest_bit;
-			set_bit(regs->floats,regs->highest_bit);
-			++regs->highest_bit;
-		}
-	}else{
-		if(regs->highest_bit>MAX_FLOAT_REGS-sz){
-			regs->highest_bit=MAX_FLOAT_REGS;
-		}else{
-			if(!isfloat&&!ALIGNED(regs->highest_bit, 2)){
-				regs->highest_bit++;
-				regs->left_single++;
-			}
-			ret=regs->highest_bit;
-			for(i=0;i<sz;++i){
-				set_bit(regs->floats,regs->highest_bit++);
-			}
-		}
-	}
-	if(regs->highest_bit==MAX_FLOAT_REGS){
-		regs->float_sealed=true;		
-	}
-	return ret;
-}
-#endif
-static void load_reg(struct jit* Dst,int off,int size){
-	if(size==16){
-		dasm_put(Dst, 0, off);
-	}else if(size==12){
-		dasm_put(Dst, 4, off);
-	}else if(size==8){
-		dasm_put(Dst, 8, off);
-	}else{
-		dasm_put(Dst, 12, off);
-	}
-}
-// arm store/load range for immediate value is only -256-255
-static void load_stack(struct jit* Dst,stack_info* st,int size,int align){
-	int off=st->stack_off;
-	FIX_ALIGN(st->stack_off,align);
-	if((off=st->stack_off-off)){
-		dasm_put(Dst, 15, off);
-	}
-	if(size==16){
-		dasm_put(Dst, 18);
-	}else if(size==8){
-		dasm_put(Dst, 20);
-	}else{
-		dasm_put(Dst, 22);
-	}
-	st->stack_off+=size;
-}
-
-static void load_int(struct jit* Dst,stack_info* st,int size,int align){
-	FIX_ALIGN(st->int_off,align);
-	if(st->int_off<0x40*ARM_HF+MAX_REGS*4&&(!st->stack_off||MAX_REGS*4+size<=0x40*ARM_HF+MAX_REGS*4)){
-		load_reg(Dst,st->int_off+st->extra,size);
-		st->int_off+=size;
-	}else{
-		st->int_off=0x40*ARM_HF+MAX_REGS*4;
-		load_stack(Dst,st,size,align);
-	}
-	
-}
-
-static void load_float(struct jit* Dst,stack_info* st,int size,int vfp,int align){
-	#if ARM_HF
-	if(st->float_off<st->float_size){
-		if(vfp){
-			if(size==4){//float
-			}else if(size==8){//double
-			}
-		}else load_reg(Dst,st->float_off+st->extra,size);
-		st->float_off+=size;
-	}else if(vfp){
-		if(size==4){//float
-		}else if(size==8){//double
-			int off=st->stack_off;
-			FIX_ALIGN(st->stack_off,align);
-			if((off=st->stack_off-off)){
-			}
-		}
-	}else{
-		load_stack(Dst,st,size,align);
-	}
-	#else	
-		load_int(Dst,st,size,align);
-	#endif
-}
-#if ARM_HF
-static void push_regs(lua_State* L,struct jit* Dst,int ct_usr,int nargs,stack_info* st){
-	const struct ctype* mt;
-	reg_info regs;int i;
-	memset(&regs,0,sizeof(reg_info));
-    for (i = 1; i <= nargs&&!is_float_sealed(&regs); ++i){
-		lua_rawgeti(L, ct_usr, i);
-		mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (!mt->pointers &&! mt->is_reference) {
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,4,0),16,st);
-					break;
-				case DOUBLE_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,2,0),8,st);
-					break;
-				case COMPLEX_FLOAT_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,2,1),8,st);
-					break;
-				case FLOAT_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,1,1),4,st);
-					break;
-				case STRUCT_TYPE:
-					{
-						int isfloat,hfasize=hfa_size(L,-1,mt,&isfloat);
-						if(hfasize){
-							save_float_reg(Dst,add_float_reg(&regs,hfasize,isfloat),4*hfasize,st);
-							break;
-						}
-					}
-				case UNION_TYPE:
-					break;
-				case INT64_TYPE:
-					//add_int64_reg(&regs);
-					break;
-				default:
-					//add_int_reg(&regs);//no need to check type support here
-					break;
-			}
-		}
-		lua_pop(L,1);
-	}
-	st->float_off+=st->int_off;
-	st->int_off+=0x40;
-}
-#endif
-cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals, ref;
-    const struct ctype* mt;
-	stack_info st;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    fidx = lua_absindex(L, fidx);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    dasm_setup(Dst, build_actionlist);
-
-    lua_newtable(L);
-    lua_pushvalue(L, -1);
-    ref = luaL_ref(L, LUA_REGISTRYINDEX);
-    num_upvals = 0;
-
-    if (ct->has_var_arg) {
-        luaL_error(L, "can't create callbacks with varargs");
-    }
-	memset(&st,0,sizeof(stack_info));
-	st.extra=0x10;
-    /* prolog and get the upval table */
-	dasm_put(Dst, 24);
-#if ARM_HF
-	push_regs(L,Dst,ct_usr,nargs,&st);
-#endif	
-    
-    dasm_put(Dst, 27, (unsigned short)(L), (((unsigned int)(L))>>16), (unsigned short)(ref), (((unsigned int)(ref))>>16), (unsigned short)(LUA_REGISTRYINDEX), (((unsigned int)(LUA_REGISTRYINDEX))>>16));
-	
-    /* get the lua function */
-    lua_pushvalue(L, fidx);
-    lua_rawseti(L, -2, ++num_upvals);
-	
-	
-    dasm_put(Dst, 45, num_upvals);
-
-	// Complex type is return in the address stored in r0 for softfp
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	if(!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
-	(!ARM_HF&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(ARM_HF&&hfa_size(L,-1,mt,NULL))){
-		st.int_off+=4;
-	} 
-	lua_pop(L,1);
-
-	//whether 64 bit type requires 8 bytes alignment in stack is defined by compiler.android compiler reqiures only 4 byte alignment;
-	//actually the stack it self may reqiures 8 bytes alignment
-    for (i = 1; i <= nargs; i++) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-
-        if (mt->pointers || mt->is_reference) {
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-			
-            dasm_put(Dst, 52, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-            load_int(Dst,&st,4,4);
-            dasm_put(Dst, 68);
-        } else {
-            switch (mt->type) {
-			case STRUCT_TYPE:
-			case UNION_TYPE:{
-				#if ARM_HF
-				int isfloat,hfasize=0;
-				if(mt->type!=UNION_TYPE){
-					hfasize=hfa_size(L,-1,mt,&isfloat);
-				}
-				#endif
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-                dasm_put(Dst, 74, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-				#if ARM_HF
-				if(hfasize){
-					if(hfasize<=4)load_float(Dst,&st,4*hfasize,0,4*(2-isfloat));
-					switch(hfasize){
-						case 8:
-							load_float(Dst,&st,16,0,8);
-							load_float(Dst,&st,16,0,8);
-							break;
-						case 6:
-							load_float(Dst,&st,16,0,8);
-							load_float(Dst,&st,8,0,8);
-							break;
-						case 4:
-							break;
-						case 3:
-							break;
-						case 2:
-							break;
-						case 1:
-							break;
-					}
-				}else
-				#endif
-				if(!mt->is_empty){
-					int size=mt->base_size;
-					if(size<=4){
-						load_int(Dst,&st,4,4);
-						dasm_put(Dst, 90);
-					}else{
-						size=ROUND_UP(size,4);
-						if(mt->align_mask>4){//8 byte max alignment
-							if(st.int_off<0x40*ARM_HF+MAX_REGS*4){FIX_ALIGN(st.int_off,8);} 
-							else {FIX_ALIGN(st.stack_off,8);}
-						}
-						
-						if(st.int_off<0x40*ARM_HF+MAX_REGS*4&&(!st.stack_off||st.int_off+size<=0x40*ARM_HF+MAX_REGS*4)){//to ensure consective memory for the struct
-							dasm_put(Dst, 92, st.int_off+st.extra);
-							st.int_off+=size;
-						}else{
-							st.int_off=0x40*ARM_HF+MAX_REGS*4;
-							dasm_put(Dst, 95);
-							st.stack_off+=size;
-						}
-						dasm_put(Dst, 97, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
-					}
-				}
-                dasm_put(Dst, 107);
-				break;
-			}
-				
-			case COMPLEX_DOUBLE_TYPE:
-				
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-                dasm_put(Dst, 112, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-                load_float(Dst,&st,16,0,8);
-                dasm_put(Dst, 128);
-				break;
-			case COMPLEX_FLOAT_TYPE:
-                lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-                dasm_put(Dst, 134, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-				load_float(Dst,&st,8,0,4);
-                dasm_put(Dst, 150);
-				break;
-            case INT64_TYPE:
-				
-			#if LUA_VERSION_NUM>=503
-                lua_pop(L, 1);
-				
-            #if CK_ALGIN
-				FIX_ALIGN(st.int_off,8);
-				if(st.int_off<16){
-					dasm_put(Dst, 156, st.int_off+st.extra);
-					st.int_off+=8;
-				}else{
-					if(!ALIGNED(st.stack_off,8)){
-						st.stack_off+=4;
-						dasm_put(Dst, 160);
-					}
-					dasm_put(Dst, 162);
-					st.stack_off+=8;
-				}
-			#else
-				load_int(Dst,st,8,8);
-			#endif
-                dasm_put(Dst, 164);
-			#else
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 168, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-                load_int(Dst,&st,8,8);
-                dasm_put(Dst, 177);
-			#endif
-                break;
-
-            case INTPTR_TYPE:
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 183, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-                load_int(Dst,&st,4,4);
-                dasm_put(Dst, 192);
-				
-                break;
-
-            case BOOL_TYPE:
-                lua_pop(L, 1);
-				
-                load_int(Dst,&st,4,4);
-                dasm_put(Dst, 198);
-                break;
-
-            case INT8_TYPE: // no need to narrow cause narrowed by caller
-            case INT16_TYPE: // no need to narrow cause narrowed by caller
-            case ENUM_TYPE:
-            case INT32_TYPE:
-                lua_pop(L, 1);
-				
-                load_int(Dst,&st,4,4);
-                dasm_put(Dst, 202);
-                break;
-
-            case FLOAT_TYPE:
-                lua_pop(L, 1);
-                
-                load_float(Dst,&st,4,ARM_HF,4);
-                dasm_put(Dst, 206);
-                break;
-
-            case DOUBLE_TYPE:
-                lua_pop(L, 1);
-				
-				#if ARM_HF
-				load_float(Dst,&st,8,ARM_HF,8);
-				#elif CK_ALGIN
-				FIX_ALIGN(st.int_off,8);
-				if(st.int_off<16){
-					dasm_put(Dst, 210, st.int_off+st.extra);
-					st.int_off+=8;
-				}else{
-					if(!ALIGNED(st.stack_off,8)){
-						st.stack_off+=4;
-						dasm_put(Dst, 214);
-					}
-					dasm_put(Dst, 216);
-					st.stack_off+=8;
-				}
-				#else
-				load_float(Dst,&st,8,ARM_HF,8);
-				#endif	
-                dasm_put(Dst, 218);
-                break;
-				
-            default:
-                luaL_error(L, "NYI: callback arg type");
-            }
-        }
-    }
-
-    lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-
-    dasm_put(Dst, 222, ((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0), nargs);
-    
-
-    if (mt->pointers || mt->is_reference) {
-        lua_getuservalue(L, -1);
-        lua_rawseti(L, -3, ++num_upvals); /* usr value */
-        lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-        dasm_put(Dst, 230, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-        goto single_no_pop;
-    } else {
-        switch (mt->type) {
-		case STRUCT_TYPE:
-		case UNION_TYPE:{
-			int isfloat,hfasize=0;
-			if(mt->type!=UNION_TYPE){
-				hfasize=hfa_size(L,-1,mt,&isfloat);
-			}
-			lua_getuservalue(L, -1);
-			lua_rawseti(L, -3, ++num_upvals); /* usr value */
-			lua_rawseti(L, -2, ++num_upvals); /* mt */
-            dasm_put(Dst, 246, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-			#if ARM_HF
-			if(hfasize>0){
-				switch(hfasize){
-					case 8:
-						break;
-					case 6:
-						break;
-					case 4:
-						break;
-					case 3:
-						break;
-					case 2:
-						break;
-					case 1:
-						break;	
-				}
-			}else
-			#endif
-			if(!mt->is_empty){
-				if(mt->base_size<=4){
-					dasm_put(Dst, 267);
-				}else{
-					dasm_put(Dst, 269, st.extra+0x40*ARM_HF, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
-				}
-			}
-			break;
-		}	
-        case ENUM_TYPE:
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-            dasm_put(Dst, 282, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-
-            goto single_no_pop;
-
-        case VOID_TYPE:
-            dasm_put(Dst, 298);
-            lua_pop(L, 1);
-            break;
-
-        case BOOL_TYPE:
-        case INT8_TYPE:// narrow it 
-        case INT16_TYPE:// narrow it 
-        case INT32_TYPE:
-		    dasm_put(Dst, 303);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 305);
-            } else {
-                dasm_put(Dst, 309);
-            }
-			switch(mt->type){
-				case BOOL_TYPE:
-					dasm_put(Dst, 313);
-					break;
-				case INT8_TYPE:
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 316);
-					} else {
-						dasm_put(Dst, 318);
-					}
-					break;
-				case INT16_TYPE:
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 320);
-					} else {
-						dasm_put(Dst, 322);
-					}
-					break;
-			}
-            goto single;
-
-        case INT64_TYPE:
-            dasm_put(Dst, 324);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 326);
-            } else {
-                dasm_put(Dst, 330);
-            }
-            goto dual;
-
-        case INTPTR_TYPE:
-            dasm_put(Dst, 334);
-            goto single;
-
-        case FLOAT_TYPE:
-            dasm_put(Dst, 339);
-			#if ARM_HF
-			lua_pop(L, 1);
-			#else
-            goto single;
-			#endif
-			break;
-        case DOUBLE_TYPE:
-            dasm_put(Dst, 344);
-			#if ARM_HF
-			lua_pop(L, 1);
-            #else
-			goto dual;
-			#endif
-			break;
-		case COMPLEX_DOUBLE_TYPE:
-            lua_pop(L, 1);
-			dasm_put(Dst, 349, st.extra);
-			break;
-		case COMPLEX_FLOAT_TYPE:
-            lua_pop(L, 1);
-			dasm_put(Dst, 360, st.extra);
-			break;
-			
-        single:
-            lua_pop(L, 1);
-		single_no_pop:	
-            dasm_put(Dst, 371);
-			
-            break;
-		dual:
-			dasm_put(Dst, 378);
-			
-            lua_pop(L, 1);
-			break;
-       
-
-        
-        default:
-            luaL_error(L, "NYI: callback return type");
-        }
-    }
-	
-    dasm_put(Dst, 387);
-	
-    lua_pop(L, 1); /* upval table - already in registry */
-    assert(lua_gettop(L) == top);
-
-    {
-        void* p;
-        struct ctype ft;
-        cfunction func;
-
-        func = compile(Dst, L, NULL, ref);
-
-        ft = *ct;
-        ft.is_jitted = 1;
-        p = push_cdata(L, ct_usr, &ft);
-        *(cfunction*) p = func;
-
-        assert(lua_gettop(L) == top + 1);
-
-        return func;
-    }
-}
-
-static ALWAYS_INLINE void save_int64_stack_align(struct jit* Dst,reg_info* regs,int align){
-	if(align&&!ALIGNED(regs->exs,2)){
-		regs->exs++;
-		dasm_put(Dst, 389);
-	}
-	dasm_put(Dst, 391);
-	regs->exs+=2;
-}
-
-static ALWAYS_INLINE void save_int64_align(struct jit* Dst,reg_info* regs,int align){
-	if((align&&!ALIGNED(regs->ints,2))||(regs->ints==MAX_REGS-1&&regs->exs/*to ensure consective memory*/)){
-		regs->ints++;
-	}
-	if(regs->ints<MAX_REGS){
-		dasm_put(Dst, 393, ((regs->ints<<2)+0x40*ARM_HF));
-		regs->ints+=2;
-	}else{
-		save_int64_stack_align(Dst,regs,align);
-	}
-	
-}
-
-static ALWAYS_INLINE  void save_int64(struct jit* Dst,reg_info* regs){
-	save_int64_align(Dst,regs,1);
-}
-
-static ALWAYS_INLINE void save_int_stack_align(struct jit* Dst,reg_info* regs){
-	dasm_put(Dst, 397);
-	regs->exs++;
-}
-
-static ALWAYS_INLINE void save_int(struct jit* Dst,reg_info* regs){
-	if(regs->ints<MAX_REGS){
-		dasm_put(Dst, 399, ((regs->ints++<<2)+0x40*ARM_HF));
-	}else{
-		save_int_stack_align(Dst,regs);
-	}
-}
-
-static void save_float(struct jit* Dst,reg_info* regs,int size,int isfloat){
-#if ARM_HF
-	if(!regs->float_sealed){
-		int reg=add_float_reg(regs,size,isfloat);
-		if(reg<0) goto SAVE_STACK;
-		switch(size){
-		case 8:
-		case 6:
-		case 4:
-			goto sf_2;
-		case 3:
-		case 2:
-			sf_2:
-			break;
-		case 1:
-			break;
-		}
-		return;
-	}
-	SAVE_STACK:
-	
-	if(!isfloat&&!ALIGNED(regs->exs,2)){
-		regs->exs++;
-		dasm_put(Dst, 402);
-	}
-	switch(size){
-		case 1:
-			dasm_put(Dst, 404);
-			break;
-		case 2:
-			dasm_put(Dst, 406);
-			break;
-		case 3:
-			dasm_put(Dst, 408);
-			break;
-		case 4:
-			dasm_put(Dst, 410);
-			break;
-		case 6:
-			dasm_put(Dst, 412);
-			break;
-		case 8:
-			dasm_put(Dst, 414);
-			break;	
-		
-	}
-	regs->exs+=size;
-	
-#else
-	if(size==1){
-		save_int(Dst,regs);
-	}else if(size==2){
-		save_int64_align(Dst,regs,!isfloat);
-	}
-#endif
-}
-
-static int calculate_stack(lua_State* L,int ct_usr,int nargs){
-	const struct ctype* mt;
-	reg_info regs;int i,stack=0;
-	memset(&regs,0,sizeof(reg_info));
-    for (i = 1; i <= nargs;++i){
-		lua_rawgeti(L, ct_usr, i);
-		mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (mt->pointers || mt->is_reference) {
-			stack+=add_int_reg(&regs);
-		}else{
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-					#if ARM_HF
-					stack+=add_float_reg(&regs,4,0)<0?4:0;
-					#else
-					stack+=add_int64_reg(&regs);
-					stack+=add_int64_reg(&regs);
-					#endif
-					FIX_ALIGN(stack,2);
-					break;
-				case DOUBLE_TYPE:
-					#if ARM_HF
-					stack+=add_float_reg(&regs,2,0)<0?2:0;
-					#else
-					stack+=add_int64_reg(&regs);
-					#endif
-					FIX_ALIGN(stack,2);
-					break;
-				case COMPLEX_FLOAT_TYPE:// Though complex alignment is 4, but vfp requires a sequence of regsiters
-					#if ARM_HF
-					stack+=add_float_reg(&regs,2,1)<0?2:0;
-					#else
-					stack+=add_int_reg(&regs);
-					stack+=add_int_reg(&regs);
-					#endif
-					break;
-				case FLOAT_TYPE:
-					#if ARM_HF
-					stack+=add_float_reg(&regs,1,1)<0?1:0;
-					#else
-					stack+=add_int_reg(&regs);
-					#endif
-					break;
-				case INT64_TYPE:
-					stack+=add_int64_reg(&regs);
-					FIX_ALIGN(stack,2);
-					break;
-				case STRUCT_TYPE:{
-					#if ARM_HF
-					int isfloat;
-					int hfasize=hfa_size(L,-1,mt,&isfloat);
-                    if(hfasize>0){
-						stack+=add_float_reg(&regs,2,0)<0?hfasize:0;
-						if(!isfloat){
-							FIX_ALIGN(stack,2);
-						}
-						break;
-                    }
-					#endif
-				}
-				case UNION_TYPE:{
-					int intsize=(mt->base_size+3)>>2;
-					if(mt->align_mask>4){//8-byte max alignment
-						if(regs.ints<MAX_REGS){
-							FIX_ALIGN(regs.ints,2);
-						}else{
-							FIX_ALIGN(stack,2);
-						}
-					}
-					
-					if(regs.ints+intsize<=MAX_REGS){
-						regs.ints+=intsize;
-					}else{
-						stack+=regs.ints+intsize-MAX_REGS;
-						regs.ints=MAX_REGS;
-					}
-					break;
-				}
-				default:
-					stack+=add_int_reg(&regs);//no need to check type support here
-			}
-		}
-		lua_pop(L,1);
-	}
-	FIX_ALIGN(stack,2);
-	return (regs.ints
-	#if ARM_HF
-	/**/||regs.floats
-	#endif
-	)?0x40*ARM_HF+0x10+stack*4:0;
-}
-
-void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals,ret_by_addr, stack_size;
-    const struct ctype* mt;
-    void* p; reg_info regs;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    p = push_cdata(L, ct_usr, ct);
-    *(cfunction*) p = func;
-    num_upvals = 1;
-
-    dasm_setup(Dst, build_actionlist);
-#if defined __thumb__ //keep frame pointer
-    dasm_put(Dst, 416);
-#else
-    dasm_put(Dst, 419);
-#endif
-#if CK_ALGIN
-	dasm_put(Dst, 422);
-#endif	
-    dasm_put(Dst, 424);
-    
-    /* Reserve enough stack space for all of the arguments. For hard floating point,
-	 * leave extra 64 bytes
-	 */
-	stack_size=calculate_stack(L,ct_usr,nargs);
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	
-	// Complex types in softfp and structs/unions larger than 4-bytes are return in the address stored in r0
-	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
-	(!ARM_HF&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(ARM_HF&&hfa_size(L,-1,mt,NULL));
-	lua_pop(L,1);
-	if(ret_by_addr){
-		if(stack_size==0)
-			stack_size=0x40*ARM_HF+0x10;
-		stack_size+=8;
-	}
-	if(stack_size>0){
-		if(stack_size>=1<<12){
-			dasm_put(Dst, 426, (unsigned short)(stack_size), (((unsigned int)(stack_size))>>16));
-		}else{
-			dasm_put(Dst, 432, stack_size);
-		}
-		if (ct->has_var_arg){
-			dasm_put(Dst, 435, nargs, (unsigned short)("too few arguments"), (((unsigned int)("too few arguments"))>>16));
-		}
-		dasm_put(Dst, 452, 0x40*ARM_HF+0x10);
-	} 
-	
-	memset(&regs,0,sizeof(reg_info));
-	
-    if (ret_by_addr) {	
-		regs.ints++;
-		dasm_put(Dst, 455, (unsigned short)(mt), (((unsigned int)(mt))>>16), 0x40*ARM_HF);
-	}
-	
-	
-    for (i = 1; i <= nargs; i++) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		
-        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE|| mt->type==STRUCT_TYPE || mt->type==UNION_TYPE) {
-            lua_getuservalue(L, -1);
-            num_upvals += 2;
-
-            dasm_put(Dst, 466, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16), i);
-			
-            if (mt->pointers || mt->is_reference) {
-                dasm_put(Dst, 477);
-            } else if (mt->type == FUNCTION_PTR_TYPE) {
-                dasm_put(Dst, 481);
-            } else if (mt->type == ENUM_TYPE) {
-                dasm_put(Dst, 485);
-            }else if(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE){
-				if(mt->is_empty) continue;
-				dasm_put(Dst, 489);
-				#if ARM_HF
-				{
-					int hfasize,isfloat;
-					hfasize=hfa_size(L,-2,mt,&isfloat);
-					if(hfasize){
-						switch(hfasize){
-							case 8:
-								break;
-							case 6:
-								break;
-							case 4:
-								break;
-							case 3:
-								break;
-							case 2:
-								break;
-							case 1:
-								break;
-								
-						}
-						save_float(Dst,&regs,hfasize,isfloat);
-						continue;
-					}
-				}
-				#endif
-				
-				if(mt->align_mask>4){//8 byte max alignment 
-					if(regs.ints<4){
-						FIX_ALIGN(regs.ints,2)
-					}else if(!ALIGNED(regs.exs,2)){
-						int diff=regs.exs;
-						regs.exs+=4;
-						dasm_put(Dst, 493);
-					}
-				}
-				int size=ROUND_UP(mt->base_size,4)>>2;
-				dasm_put(Dst, 495, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
-				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+size<=MAX_REGS)){//to ensure consective memory for the struct
-					dasm_put(Dst, 505, ((regs.ints<<2)+0x40*ARM_HF));
-				}else{
-					regs.ints=MAX_REGS;
-					dasm_put(Dst, 508);
-				}
-				dasm_put(Dst, 510);
-				if(regs.ints+size<=MAX_REGS){
-					regs.ints+=size;
-				}else{
-					int ex=regs.ints+size-MAX_REGS;
-					dasm_put(Dst, 512, (ex)<<2);
-					regs.exs+=ex;
-					regs.ints=MAX_REGS;
-				}
-				continue;
-			}
-
-            save_int(Dst,&regs);
-        } else {
-            lua_pop(L, 1);
-            dasm_put(Dst, 515, i);
-
-            switch (mt->type) {
-			case BOOL_TYPE:
-				dasm_put(Dst, 518);
-                save_int(Dst,&regs);
-                break;
-            case INT8_TYPE:
-                dasm_put(Dst, 524);
-                if (mt->is_unsigned) {
-                     dasm_put(Dst, 528);
-                } else {
-                     dasm_put(Dst, 530);
-                }
-                save_int(Dst,&regs);
-                break;
-
-            case INT16_TYPE:
-                dasm_put(Dst, 532);
-                if (mt->is_unsigned) {
-                    dasm_put(Dst, 536);
-                } else {
-                    dasm_put(Dst, 538);
-                }
-                save_int(Dst,&regs);
-                break;
-
-            case INT32_TYPE:
-                if (mt->is_unsigned) {
-                    dasm_put(Dst, 540);
-                } else {
-                    dasm_put(Dst, 544);
-                }
-                save_int(Dst,&regs);
-                break;
-            case INTPTR_TYPE:
-                dasm_put(Dst, 548);
-                save_int(Dst,&regs);
-				break;
-
-            case INT64_TYPE:
-                if (mt->is_unsigned) {
-                    dasm_put(Dst, 552);
-                } else {
-                    dasm_put(Dst, 556);
-                }
-				save_int64(Dst,&regs);
-                break;
-
-            case DOUBLE_TYPE:
-				dasm_put(Dst, 560);
-				save_float(Dst,&regs,2,0);
-                break;
-
-            case FLOAT_TYPE:
-				dasm_put(Dst, 564);
-                save_float(Dst,&regs,1,1);
-                break;
-				
-			case COMPLEX_DOUBLE_TYPE:
-				#if ARM_HF
-				save_float(Dst,&regs,4,0);
-				#else
-				FIX_ALIGN(regs.ints,2);
-				dasm_put(Dst, 568);
-				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+4<=MAX_REGS)){
-					dasm_put(Dst, 571, (regs.ints<<2));
-				}else{
-					regs.ints=MAX_REGS;
-					if(!ALIGNED(regs.exs,2)){
-						++regs.exs;
-						dasm_put(Dst, 574);
-					}
-					dasm_put(Dst, 576);
-				}
-				dasm_put(Dst, 578);
-				regs.ints+=4;
-				goto FIX_REG;
-				#endif
-				break;
-			case COMPLEX_FLOAT_TYPE:
-				#if ARM_HF
-				save_float(Dst,&regs,2,1);
-				#else
-				dasm_put(Dst, 581);
-				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+2<=MAX_REGS)){
-					dasm_put(Dst, 584, (regs.ints<<2));
-				}else{
-					regs.ints=MAX_REGS;
-					dasm_put(Dst, 587);
-				}
-				dasm_put(Dst, 589);
-				regs.ints+=2;
-				FIX_REG:
-				if(regs.ints>MAX_REGS){
-					dasm_put(Dst, 592, (regs.ints-4)<<2);
-					regs.exs+=regs.ints-MAX_REGS;
-					regs.ints=MAX_REGS;
-				}
-				#endif
-                break;
-            default:
-                luaL_error(L, "NYI: call arg type");
-            }
-        }
-    }
-
-    if (ct->has_var_arg) {
-		int offset=nargs+1;
-        dasm_put(Dst, 595, offset);
-		#if ARM_HF
-		    if(regs.ints==4||regs.float_sealed){
-				if(regs.ints<4&&regs.float_sealed){//some arg must be loaded to core registers.
-				}
-			} 
-		#else
-			if(regs.ints==4){
-				dasm_put(Dst, 598);
-			}
-		#endif
-		else{//no hard floating point in variadic procedure
-			dasm_put(Dst, 600, ((regs.ints<<2)+ARM_HF*0x40));
-		}
-        
-        dasm_put(Dst, 603);
-		regs.ints=4;
-    } 
-	
-	#if ARM_HF
-	switch(ROUND_UP(regs.highest_bit,4)>>1){
-		case 8 :
-			break;
-		case 7 :
-			break;
-		case 6 :
-			break;
-		case 5:
-			break;
-		case 4 :
-			break;
-		case 3 :
-			break;
-		case 2 :
-			break;
-		case 1 :
-			break;
-	}
-	if(stack_size>0){
-	}
-	#endif
-	
-	//pop registers from stack,align 8 for some compiler
-	assert(regs.ints<=4);
-	switch(regs.ints){
-	case 4:
-	case 3:
-		dasm_put(Dst, 608);
-		break;
-	case 2:
-	case 1:
-		dasm_put(Dst, 610);
-		#if ARM_HF
-		if(regs.float_sealed){
-		}
-		#endif
-		break;
-	default:
-		#if ARM_HF
-		if(regs.float_sealed){
-		}
-		#endif
-		break;
-	}
-	
-	dasm_put(Dst, 612, (unsigned short)(func), (((unsigned int)(func))>>16));
-
-    lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-
-    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
-        lua_getuservalue(L, -1);
-        num_upvals += 2;
-        dasm_put(Dst, 618, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-
-    } else {
-        switch (mt->type) {
-        case INT64_TYPE:
-        #if LUA_VERSION_NUM>=503
-             lua_pop(L, 1);
-	    #if CK_ALGIN
-            dasm_put(Dst, 633);
-		#else
-            dasm_put(Dst, 636);
-		#endif		
-            dasm_put(Dst, 639);
-            break;
-		#else
-			num_upvals++;
-            dasm_put(Dst, 644, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-            break;
-        #endif
-		
-        case INTPTR_TYPE:
-            num_upvals++;
-            dasm_put(Dst, 658, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-            break;
-
-        case VOID_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 670);
-            break;
-
-        case BOOL_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 672);
-            break;
-
-        case INT8_TYPE:
-        case INT16_TYPE:
-        case INT32_TYPE:
-        case ENUM_TYPE:// value must be narrowed before callee return
-            lua_pop(L, 1);
-			
-            dasm_put(Dst, 678);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 680);
-            } else {
-                dasm_put(Dst, 684);
-            }
-			
-            dasm_put(Dst, 688);
-            break;
-
-        case FLOAT_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 690);
-            break;
-
-        case DOUBLE_TYPE:
-            lua_pop(L, 1);
-        #if CK_ALGIN
-            dasm_put(Dst, 696);
-		#else
-			dasm_put(Dst, 699);
-		#endif	
-            dasm_put(Dst, 702);
-            break;
-		case COMPLEX_DOUBLE_TYPE:
-		case COMPLEX_FLOAT_TYPE:
-		case STRUCT_TYPE:
-		case UNION_TYPE:{
-			lua_getuservalue(L,-1);
-            num_upvals += 2;
-			#if ARM_HF
-			{
-				int isfloat,hfasize=hfa_size(L,-2,mt,&isfloat);
-				if(hfasize>0){
-					switch(hfasize){
-						case 8:
-							break;
-						case 6:
-							break;
-						case 4:
-						case 3:
-							break;
-						case 2:
-						case 1:
-							break;
-							
-					}
-					switch(hfasize){
-						case 8:
-							break;
-						case 6:
-							break;
-						case 4:
-							break;
-						case 3:
-							break;
-						case 2:
-							break;
-						case 1:
-							break;
-							
-					}
-					break;
-				}
-			}
-			
-			#endif
-			if(mt->base_size>4){
-				// value are stored in return storage in r0 for softfp, set usr value here
-				if(!lua_isnil(L,-1)){
-					dasm_put(Dst, 707, (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-				}
-			}else if(mt->is_empty){
-				dasm_put(Dst, 719);
-				break;
-			}else{
-				dasm_put(Dst, 721, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-			}
-            dasm_put(Dst, 735);
-			break;
-		}	
-        default:
-            luaL_error(L, "NYI: call return type");
-        }
-    }
-
-#ifdef __thumb__
-    dasm_put(Dst, 737);
-#else	
-    dasm_put(Dst, 740);
-#endif	
-    assert(lua_gettop(L) == top + num_upvals);
-    {
-        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
-        /* add a callback as an upval so that the jitted code gets cleaned up when
-         * the function gets gc'd */
-        push_callback(L, f, func);
-        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
-    }
-}
-
+/*
+** This file has been pre-processed with DynASM.
+** http://luajit.org/dynasm.html
+** DynASM version 1.4.0, DynASM arm version 1.4.0
+** DO NOT EDIT! The original file is in "call_arm.dasc".
+*/
+
+/* vim: ts=4 sw=4 sts=4 et tw=78
+ * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+ * Portions copyright (c) 2011 James R. McKaskill.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+ 
+//The generate code is for arm not for thumb
+#if DASM_VERSION != 10400
+#error "Version mismatch between DynASM and included encoding engine"
+#endif
+
+static const unsigned int build_actionlist[743] = {
+0xe28dc000,
+0x000b0000,
+0xe89c100e,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c100e,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c0006,
+0x00000000,
+0xe51d1000,
+0x000e8180,
+0x00000000,
+0xe2866000,
+0x000b0000,
+0x00000000,
+0xe8b6100e,
+0x00000000,
+0xe8b60006,
+0x00000000,
+0xe4961004,
+0x00000000,
+0xe1a0c00d,
+0xe92d000f,
+0x00000000,
+0xe92d5050,
+0xe1a0600c,
+0xe3004000,
+0x000c0200,
+0xe3404000,
+0x000c0200,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe5801000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe5801000,
+0x00000000,
+0xe28d1000,
+0x000b0000,
+0x00000000,
+0xe1a01006,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe12fff3c,
+0x00000000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe880100e,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe8800006,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c000c,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe8b6000c,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030003,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe8800006,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe5801000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030004,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030006,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c000c,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe8b6000c,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030007,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3a01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030008,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3e02000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030009,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3e02000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003000a,
+0xe1a06000,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0x00000000,
+0xe5960000,
+0x00000000,
+0xe51d0000,
+0x000e8180,
+0xe1a01006,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe12fff3c,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3e02000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003000c,
+0x00000000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0x00000000,
+0xe3e01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe3500000,
+0x13a00001,
+0x00000000,
+0xe6ef0070,
+0x00000000,
+0xe6af0070,
+0x00000000,
+0xe6ff0070,
+0x00000000,
+0xe6bf0070,
+0x00000000,
+0xe3e01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000f,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030010,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030011,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030012,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030013,
+0x00000000,
+0xe3e02000,
+0xe1a01004,
+0xe51d0000,
+0x000e8180,
+0xeb000000,
+0x00030014,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0x00000000,
+0xe3e02000,
+0xe1a01004,
+0xe51d0000,
+0x000e8180,
+0xeb000000,
+0x00030015,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0x00000000,
+0xe1a06000,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0xe1a00006,
+0x00000000,
+0xe1a06000,
+0xe1a00004,
+0xe1a04001,
+0xe3e01002,
+0xeb000000,
+0x0003000b,
+0xe1a00006,
+0xe1a01004,
+0x00000000,
+0xe89da050,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe8a60003,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe88c0003,
+0x00000000,
+0xe4860004,
+0x00000000,
+0xe50d0000,
+0x000e8180,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xeca60a01,
+0x00000000,
+0xeca60b02,
+0x00000000,
+0xeca60a04,
+0x00000000,
+0xeca60b04,
+0x00000000,
+0xeca60b06,
+0x00000000,
+0xeca60b08,
+0x00000000,
+0xe92d40f0,
+0xe28d700c,
+0x00000000,
+0xe92d4870,
+0xe28db00c,
+0x00000000,
+0xe24dd004,
+0x00000000,
+0xe1a04000,
+0x00000000,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe04dd00c,
+0x00000000,
+0xe24dd000,
+0x000b0000,
+0x00000000,
+0xeb000000,
+0x00030016,
+0xe3500000,
+0x000b0000,
+0xaa000000,
+0x00050001,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030017,
+0x0006000b,
+0xe1a05000,
+0xe04dd185,
+0x00000000,
+0xe28d6000,
+0x000b0000,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe50d0000,
+0x000e8180,
+0x00000000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0x000b0000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030009,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030018,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000c,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000a,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe1a01000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0x00000000,
+0xe28d0000,
+0x000b0000,
+0x00000000,
+0xe1a00006,
+0x00000000,
+0xe12fff3c,
+0x00000000,
+0xe2866000,
+0x000b0000,
+0x00000000,
+0xe3a01000,
+0x000b0000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0xe3500000,
+0x13a00001,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe6ef0070,
+0x00000000,
+0xe6af0070,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe6ff0070,
+0x00000000,
+0xe6bf0070,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030011,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000f,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030010,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030013,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030012,
+0x00000000,
+0xe1a02001,
+0xe1a01004,
+0x00000000,
+0xe28d0000,
+0x000b0000,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe1a00006,
+0x00000000,
+0xeb000000,
+0x00030014,
+0x00000000,
+0xe1a02001,
+0xe1a01004,
+0x00000000,
+0xe28d0000,
+0x000b0000,
+0x00000000,
+0xe1a00006,
+0x00000000,
+0xeb000000,
+0x00030015,
+0x00000000,
+0xe2866000,
+0x000b0000,
+0x00000000,
+0xe3a01000,
+0x000b0000,
+0x00000000,
+0xe1a03006,
+0x00000000,
+0xe28d3000,
+0x000b0000,
+0x00000000,
+0xe1a02005,
+0xe1a00004,
+0xeb000000,
+0x00030019,
+0x00000000,
+0xe8bd000f,
+0x00000000,
+0xe8bd0003,
+0x00000000,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe12fff3c,
+0x00000000,
+0xe1a06000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe3a00001,
+0x00000000,
+0xe1a03001,
+0xe1a02000,
+0x00000000,
+0xe1a02001,
+0xe1a01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030003,
+0xe3a00001,
+0x00000000,
+0xe1a06000,
+0xe1a05001,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe5805004,
+0xe3a00001,
+0x00000000,
+0xe1a06000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe3a00001,
+0x00000000,
+0xe3a00000,
+0x00000000,
+0xe1a01000,
+0xe1a00004,
+0xeb000000,
+0x00030004,
+0xe3a00001,
+0x00000000,
+0xe1a01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003001a,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe3a00001,
+0x00000000,
+0xe1a01000,
+0xe1a00004,
+0xeb000000,
+0x00030006,
+0xe3a00001,
+0x00000000,
+0xe1a03001,
+0xe1a02000,
+0x00000000,
+0xe1a02001,
+0xe1a01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030007,
+0xe3a00001,
+0x00000000,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x0003001b,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003001c,
+0x00000000,
+0xe3a00000,
+0x00000000,
+0xe1a06000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0x00000000,
+0xe3a00001,
+0x00000000,
+0xe247d00c,
+0xe8bd80f0,
+0x00000000,
+0xe24bd00c,
+0xe8bd8870,
+0x00000000
+};
+
+static const char *const globnames[] = {
+  (const char *)0
+};
+static const char *const extnames[] = {
+  "rawgeti",
+  "push_cdata",
+  "lua_remove",
+  "lua_pushinteger",
+  "lua_pushboolean",
+  "push_int",
+  "push_float",
+  "lua_pushnumber",
+  "lua_call",
+  "check_typed_pointer",
+  "check_struct",
+  "lua_settop",
+  "check_enum",
+  "check_uint32",
+  "check_int32",
+  "check_uint64",
+  "check_int64",
+  "check_uintptr",
+  "check_float",
+  "check_double",
+  "check_complex_double",
+  "check_complex_float",
+  "lua_gettop",
+  "luaL_error",
+  "check_typed_cfunction",
+  "unpack_varargs_stack",
+  "push_uint",
+  "lua_pushvalue",
+  "lua_setuservalue",
+  (const char *)0
+};
+
+#define JUMP_SIZE 8
+
+#define MIN_BRANCH ((INT32_MIN) >> 8)
+#define MAX_BRANCH ((INT32_MAX) >> 8)
+//arm pc offset 8 so comparing with next instruction is 4,
+//unlike x86 which pass in the current instruction address+1 rather than the next instruction 
+#define BRANCH_OFF 4	
+
+
+#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
+#ifdef TARGET_OS_IPHONE
+#define  CK_ALGIN  0
+#else
+#define  CK_ALGIN  1
+#endif
+#define ALIGNED(x, align) (!CK_ALGIN||((int)(x) & (align - 1)) == 0)
+#if defined(__ARM_PCS_VFP) || (GCC_VERSION==40500||defined(__clang__))&&!defined(__ARM_PCS) && !defined(__SOFTFP__) && !defined(__SOFTFP) && \
+    defined(__VFP_FP__)
+#define ARM_HF 1
+#else
+#define ARM_HF 0
+#endif
+#if ARM_HF&&!CK_ALGIN
+#error "Unsupported unaligned stack for hard floating point"
+#endif	
+
+static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
+{
+    /* The jump code is the function pointer followed by a stub to call the
+     * function pointer. The stub exists so we can jump to functions with an
+     * offset greater than 32MB.
+     *
+     * Note we have to manually set this up since there are commands buffered
+     * in the jit state.
+     */
+	
+    *(cfunction*) code = func;
+     //ldr pc, [pc - 12]
+    *(uint32_t*) &code[4] = 0xE51FF00CU; 
+	
+}
+
+
+
+
+void compile_globals(struct jit* jit, lua_State* L)
+{
+    (void) jit;
+}
+
+typedef struct stack_info{
+	int extra;
+	int int_off;
+	int stack_off;
+	int float_size;
+#if ARM_HF
+	int float_off; 
+#endif	
+} stack_info;
+//vfp use back-filling rule for registers until a float value on stack
+typedef struct reg_info{
+	uint16_t exs;	
+	union{
+		uint8_t ints;
+		uint8_t regs;
+	};
+#if ARM_HF
+	uint8_t float_sealed;
+	short floats;//each bit is a float: s0-s15 or v0-v7 or q0-q3
+	uint8_t left_single;
+	uint8_t highest_bit;
+#endif
+} reg_info;
+
+#define MAX_REGS 4
+#define MAX_FLOAT_REGS 16
+#ifndef bool
+#define bool uint8_t
+#endif
+
+#define has_bit(x,b) (((x)&(1<<(b)))!=0)
+#define set_bit(x,b) (x=((x)|(1<<(b)))) 
+#define FIX_ALIGN(x,al) \
+	if(!ALIGNED((x),al)){\
+		x=ROUND_UP(x,al);\
+	}
+static ALWAYS_INLINE bool is_float_sealed(reg_info* regs){
+#if ARM_HF
+return regs->float_sealed;
+#else
+return regs->regs>=MAX_REGS;
+#endif
+}
+//return size need to put on stack
+static ALWAYS_INLINE int add_int_reg(reg_info* regs){
+	if(regs->regs<MAX_REGS){
+		regs->regs++;
+		return 0;
+	}
+	return 1;
+		
+}
+//return size need to put on stack
+static ALWAYS_INLINE int add_int64_reg(reg_info* regs){
+	if(regs->regs<MAX_REGS-1){
+		regs->regs=ROUND_UP(regs->regs,2)+2;
+		return 0;
+	}else if(regs->regs==MAX_REGS-1){
+		regs->regs=MAX_REGS;
+	}
+		
+	return 2;
+}
+static ALWAYS_INLINE bool is_float_type(int t){
+    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
+}
+static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
+	struct ctype* mt;
+	int type,ele_count,i,ct_usr;
+	lua_getuservalue(L,idx);
+	ct_usr=lua_absindex(L,-1);
+    lua_rawgeti(L,ct_usr,1);
+    mt=(struct ctype*)lua_touserdata(L,-1);
+    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+        lua_pop(L,2);
+		if(ct->type==COMPLEX_DOUBLE_TYPE){
+			if(isfloat) *isfloat=0;
+			return 4;
+		}else if(ct->type==COMPLEX_FLOAT_TYPE){
+			if(isfloat) *isfloat=1;
+			return 2;
+		}
+        return 0;
+    }
+	type=mt->type;
+    ele_count=(int)(ct->base_size/mt->base_size);
+    if(ele_count>4||ct->base_size%mt->base_size){
+        lua_pop(L,2);
+        return 0;
+    }
+	lua_pop(L,1);
+    for (i = 2; i <=4 ; ++i) {
+        lua_rawgeti(L,ct_usr,i);
+		if(lua_isnil(L,-1)){//case have array member;
+            lua_pop(L,1);
+            break;
+        }
+        mt=(struct ctype*)lua_touserdata(L,-1);
+        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+            lua_pop(L,2);
+            return 0;
+        }
+        lua_pop(L,1);
+    }
+	if(isfloat){
+		*isfloat=mt->type==FLOAT_TYPE;
+	}
+	lua_pop(L,1);
+    return ele_count*(mt->type==FLOAT_TYPE?1:2);
+}
+#if ARM_HF
+static void save_float_reg(struct jit* Dst,int reg,int size,stack_info* st){
+	int sz;
+	if(reg==-1) return;
+	for(;size>0;size-=8){
+		sz=size>8?8:size;
+		switch(sz){
+		case 4:
+			switch(reg){
+				case 0:
+					break;
+				case 1:
+					break;
+				case 2:
+					break;
+				case 3:
+					break;
+				case 4:
+					break;
+				case 5:
+					break;
+				case 6:
+					break;
+				case 7:
+					break;
+				case 8:
+					break;
+				case 9:
+					break;
+				case 10:
+					break;
+				case 11:
+					break;
+				case 12:
+					break;
+				case 13:
+					break;
+				case 14:
+					break;
+				case 15:
+					break;
+			}
+			break;
+		case 8:
+			switch(reg>>1){
+				case 0:
+					break;
+				case 1:
+					break;
+				case 2:
+					break;
+				case 3:
+					break;
+				case 4:
+					break;
+				case 5:
+					break;
+				case 6:
+					break;
+				case 7:
+					break;
+			}
+			reg+=2;
+			break;
+		}
+		st->float_size+=sz;
+	}
+}
+
+//128 bit vector type is not supported by this
+static int add_float_reg(reg_info* regs,int sz,int isfloat){
+
+	if(is_float_sealed(regs)) return -1;
+	int i,ret=-1;
+	if(sz==1){
+		if(regs->left_single){
+			int n=regs->highest_bit;
+			for(i=0;i<n;++i){
+				if(!has_bit(regs->floats,i)){
+					regs->left_single--;
+					set_bit(regs->floats,i);
+					ret=i;
+				}
+			}
+		}else{
+			ret=regs->highest_bit;
+			set_bit(regs->floats,regs->highest_bit);
+			++regs->highest_bit;
+		}
+	}else{
+		if(regs->highest_bit>MAX_FLOAT_REGS-sz){
+			regs->highest_bit=MAX_FLOAT_REGS;
+		}else{
+			if(!isfloat&&!ALIGNED(regs->highest_bit, 2)){
+				regs->highest_bit++;
+				regs->left_single++;
+			}
+			ret=regs->highest_bit;
+			for(i=0;i<sz;++i){
+				set_bit(regs->floats,regs->highest_bit++);
+			}
+		}
+	}
+	if(regs->highest_bit==MAX_FLOAT_REGS){
+		regs->float_sealed=true;		
+	}
+	return ret;
+}
+#endif
+static void load_reg(struct jit* Dst,int off,int size){
+	if(size==16){
+		dasm_put(Dst, 0, off);
+	}else if(size==12){
+		dasm_put(Dst, 4, off);
+	}else if(size==8){
+		dasm_put(Dst, 8, off);
+	}else{
+		dasm_put(Dst, 12, off);
+	}
+}
+// arm store/load range for immediate value is only -256-255
+static void load_stack(struct jit* Dst,stack_info* st,int size,int align){
+	int off=st->stack_off;
+	FIX_ALIGN(st->stack_off,align);
+	if((off=st->stack_off-off)){
+		dasm_put(Dst, 15, off);
+	}
+	if(size==16){
+		dasm_put(Dst, 18);
+	}else if(size==8){
+		dasm_put(Dst, 20);
+	}else{
+		dasm_put(Dst, 22);
+	}
+	st->stack_off+=size;
+}
+
+static void load_int(struct jit* Dst,stack_info* st,int size,int align){
+	FIX_ALIGN(st->int_off,align);
+	if(st->int_off<0x40*ARM_HF+MAX_REGS*4&&(!st->stack_off||MAX_REGS*4+size<=0x40*ARM_HF+MAX_REGS*4)){
+		load_reg(Dst,st->int_off+st->extra,size);
+		st->int_off+=size;
+	}else{
+		st->int_off=0x40*ARM_HF+MAX_REGS*4;
+		load_stack(Dst,st,size,align);
+	}
+	
+}
+
+static void load_float(struct jit* Dst,stack_info* st,int size,int vfp,int align){
+	#if ARM_HF
+	if(st->float_off<st->float_size){
+		if(vfp){
+			if(size==4){//float
+			}else if(size==8){//double
+			}
+		}else load_reg(Dst,st->float_off+st->extra,size);
+		st->float_off+=size;
+	}else if(vfp){
+		if(size==4){//float
+		}else if(size==8){//double
+			int off=st->stack_off;
+			FIX_ALIGN(st->stack_off,align);
+			if((off=st->stack_off-off)){
+			}
+		}
+	}else{
+		load_stack(Dst,st,size,align);
+	}
+	#else	
+		load_int(Dst,st,size,align);
+	#endif
+}
+#if ARM_HF
+static void push_regs(lua_State* L,struct jit* Dst,int ct_usr,int nargs,stack_info* st){
+	const struct ctype* mt;
+	reg_info regs;int i;
+	memset(&regs,0,sizeof(reg_info));
+    for (i = 1; i <= nargs&&!is_float_sealed(&regs); ++i){
+		lua_rawgeti(L, ct_usr, i);
+		mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (!mt->pointers &&! mt->is_reference) {
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,4,0),16,st);
+					break;
+				case DOUBLE_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,2,0),8,st);
+					break;
+				case COMPLEX_FLOAT_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,2,1),8,st);
+					break;
+				case FLOAT_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,1,1),4,st);
+					break;
+				case STRUCT_TYPE:
+					{
+						int isfloat,hfasize=hfa_size(L,-1,mt,&isfloat);
+						if(hfasize){
+							save_float_reg(Dst,add_float_reg(&regs,hfasize,isfloat),4*hfasize,st);
+							break;
+						}
+					}
+				case UNION_TYPE:
+					break;
+				case INT64_TYPE:
+					//add_int64_reg(&regs);
+					break;
+				default:
+					//add_int_reg(&regs);//no need to check type support here
+					break;
+			}
+		}
+		lua_pop(L,1);
+	}
+	st->float_off+=st->int_off;
+	st->int_off+=0x40;
+}
+#endif
+cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals, ref;
+    const struct ctype* mt;
+	stack_info st;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    fidx = lua_absindex(L, fidx);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    dasm_setup(Dst, build_actionlist);
+
+    lua_newtable(L);
+    lua_pushvalue(L, -1);
+    ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    num_upvals = 0;
+
+    if (ct->has_var_arg) {
+        luaL_error(L, "can't create callbacks with varargs");
+    }
+	memset(&st,0,sizeof(stack_info));
+	st.extra=0x10;
+    /* prolog and get the upval table */
+	dasm_put(Dst, 24);
+#if ARM_HF
+	push_regs(L,Dst,ct_usr,nargs,&st);
+#endif	
+    
+    dasm_put(Dst, 27, (unsigned short)(L), (((unsigned int)(L))>>16), (unsigned short)(ref), (((unsigned int)(ref))>>16), (unsigned short)(LUA_REGISTRYINDEX), (((unsigned int)(LUA_REGISTRYINDEX))>>16));
+	
+    /* get the lua function */
+    lua_pushvalue(L, fidx);
+    lua_rawseti(L, -2, ++num_upvals);
+	
+	
+    dasm_put(Dst, 45, num_upvals);
+
+	// Complex type is return in the address stored in r0 for softfp
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	if(!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
+	(!ARM_HF&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(ARM_HF&&hfa_size(L,-1,mt,NULL))){
+		st.int_off+=4;
+	} 
+	lua_pop(L,1);
+
+	//whether 64 bit type requires 8 bytes alignment in stack is defined by compiler.android compiler reqiures only 4 byte alignment;
+	//actually the stack it self may reqiures 8 bytes alignment
+    for (i = 1; i <= nargs; i++) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+
+        if (mt->pointers || mt->is_reference) {
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+			
+            dasm_put(Dst, 52, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+            load_int(Dst,&st,4,4);
+            dasm_put(Dst, 68);
+        } else {
+            switch (mt->type) {
+			case STRUCT_TYPE:
+			case UNION_TYPE:{
+				#if ARM_HF
+				int isfloat,hfasize=0;
+				if(mt->type!=UNION_TYPE){
+					hfasize=hfa_size(L,-1,mt,&isfloat);
+				}
+				#endif
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+                dasm_put(Dst, 74, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+				#if ARM_HF
+				if(hfasize){
+					if(hfasize<=4)load_float(Dst,&st,4*hfasize,0,4*(2-isfloat));
+					switch(hfasize){
+						case 8:
+							load_float(Dst,&st,16,0,8);
+							load_float(Dst,&st,16,0,8);
+							break;
+						case 6:
+							load_float(Dst,&st,16,0,8);
+							load_float(Dst,&st,8,0,8);
+							break;
+						case 4:
+							break;
+						case 3:
+							break;
+						case 2:
+							break;
+						case 1:
+							break;
+					}
+				}else
+				#endif
+				if(!mt->is_empty){
+					int size=mt->base_size;
+					if(size<=4){
+						load_int(Dst,&st,4,4);
+						dasm_put(Dst, 90);
+					}else{
+						size=ROUND_UP(size,4);
+						if(mt->align_mask>4){//8 byte max alignment
+							if(st.int_off<0x40*ARM_HF+MAX_REGS*4){FIX_ALIGN(st.int_off,8);} 
+							else {FIX_ALIGN(st.stack_off,8);}
+						}
+						
+						if(st.int_off<0x40*ARM_HF+MAX_REGS*4&&(!st.stack_off||st.int_off+size<=0x40*ARM_HF+MAX_REGS*4)){//to ensure consective memory for the struct
+							dasm_put(Dst, 92, st.int_off+st.extra);
+							st.int_off+=size;
+						}else{
+							st.int_off=0x40*ARM_HF+MAX_REGS*4;
+							dasm_put(Dst, 95);
+							st.stack_off+=size;
+						}
+						dasm_put(Dst, 97, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
+					}
+				}
+                dasm_put(Dst, 107);
+				break;
+			}
+				
+			case COMPLEX_DOUBLE_TYPE:
+				
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+                dasm_put(Dst, 112, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+                load_float(Dst,&st,16,0,8);
+                dasm_put(Dst, 128);
+				break;
+			case COMPLEX_FLOAT_TYPE:
+                lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+                dasm_put(Dst, 134, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+				load_float(Dst,&st,8,0,4);
+                dasm_put(Dst, 150);
+				break;
+            case INT64_TYPE:
+				
+			#if LUA_VERSION_NUM>=503
+                lua_pop(L, 1);
+				
+            #if CK_ALGIN
+				FIX_ALIGN(st.int_off,8);
+				if(st.int_off<16){
+					dasm_put(Dst, 156, st.int_off+st.extra);
+					st.int_off+=8;
+				}else{
+					if(!ALIGNED(st.stack_off,8)){
+						st.stack_off+=4;
+						dasm_put(Dst, 160);
+					}
+					dasm_put(Dst, 162);
+					st.stack_off+=8;
+				}
+			#else
+				load_int(Dst,st,8,8);
+			#endif
+                dasm_put(Dst, 164);
+			#else
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 168, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+                load_int(Dst,&st,8,8);
+                dasm_put(Dst, 177);
+			#endif
+                break;
+
+            case INTPTR_TYPE:
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 183, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+                load_int(Dst,&st,4,4);
+                dasm_put(Dst, 192);
+				
+                break;
+
+            case BOOL_TYPE:
+                lua_pop(L, 1);
+				
+                load_int(Dst,&st,4,4);
+                dasm_put(Dst, 198);
+                break;
+
+            case INT8_TYPE: // no need to narrow cause narrowed by caller
+            case INT16_TYPE: // no need to narrow cause narrowed by caller
+            case ENUM_TYPE:
+            case INT32_TYPE:
+                lua_pop(L, 1);
+				
+                load_int(Dst,&st,4,4);
+                dasm_put(Dst, 202);
+                break;
+
+            case FLOAT_TYPE:
+                lua_pop(L, 1);
+                
+                load_float(Dst,&st,4,ARM_HF,4);
+                dasm_put(Dst, 206);
+                break;
+
+            case DOUBLE_TYPE:
+                lua_pop(L, 1);
+				
+				#if ARM_HF
+				load_float(Dst,&st,8,ARM_HF,8);
+				#elif CK_ALGIN
+				FIX_ALIGN(st.int_off,8);
+				if(st.int_off<16){
+					dasm_put(Dst, 210, st.int_off+st.extra);
+					st.int_off+=8;
+				}else{
+					if(!ALIGNED(st.stack_off,8)){
+						st.stack_off+=4;
+						dasm_put(Dst, 214);
+					}
+					dasm_put(Dst, 216);
+					st.stack_off+=8;
+				}
+				#else
+				load_float(Dst,&st,8,ARM_HF,8);
+				#endif	
+                dasm_put(Dst, 218);
+                break;
+				
+            default:
+                luaL_error(L, "NYI: callback arg type");
+            }
+        }
+    }
+
+    lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+
+    dasm_put(Dst, 222, ((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0), nargs);
+    
+
+    if (mt->pointers || mt->is_reference) {
+        lua_getuservalue(L, -1);
+        lua_rawseti(L, -3, ++num_upvals); /* usr value */
+        lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+        dasm_put(Dst, 230, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+        goto single_no_pop;
+    } else {
+        switch (mt->type) {
+		case STRUCT_TYPE:
+		case UNION_TYPE:{
+			int isfloat,hfasize=0;
+			if(mt->type!=UNION_TYPE){
+				hfasize=hfa_size(L,-1,mt,&isfloat);
+			}
+			lua_getuservalue(L, -1);
+			lua_rawseti(L, -3, ++num_upvals); /* usr value */
+			lua_rawseti(L, -2, ++num_upvals); /* mt */
+            dasm_put(Dst, 246, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+			#if ARM_HF
+			if(hfasize>0){
+				switch(hfasize){
+					case 8:
+						break;
+					case 6:
+						break;
+					case 4:
+						break;
+					case 3:
+						break;
+					case 2:
+						break;
+					case 1:
+						break;	
+				}
+			}else
+			#endif
+			if(!mt->is_empty){
+				if(mt->base_size<=4){
+					dasm_put(Dst, 267);
+				}else{
+					dasm_put(Dst, 269, st.extra+0x40*ARM_HF, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
+				}
+			}
+			break;
+		}	
+        case ENUM_TYPE:
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+            dasm_put(Dst, 282, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+
+            goto single_no_pop;
+
+        case VOID_TYPE:
+            dasm_put(Dst, 298);
+            lua_pop(L, 1);
+            break;
+
+        case BOOL_TYPE:
+        case INT8_TYPE:// narrow it 
+        case INT16_TYPE:// narrow it 
+        case INT32_TYPE:
+		    dasm_put(Dst, 303);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 305);
+            } else {
+                dasm_put(Dst, 309);
+            }
+			switch(mt->type){
+				case BOOL_TYPE:
+					dasm_put(Dst, 313);
+					break;
+				case INT8_TYPE:
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 316);
+					} else {
+						dasm_put(Dst, 318);
+					}
+					break;
+				case INT16_TYPE:
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 320);
+					} else {
+						dasm_put(Dst, 322);
+					}
+					break;
+			}
+            goto single;
+
+        case INT64_TYPE:
+            dasm_put(Dst, 324);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 326);
+            } else {
+                dasm_put(Dst, 330);
+            }
+            goto dual;
+
+        case INTPTR_TYPE:
+            dasm_put(Dst, 334);
+            goto single;
+
+        case FLOAT_TYPE:
+            dasm_put(Dst, 339);
+			#if ARM_HF
+			lua_pop(L, 1);
+			#else
+            goto single;
+			#endif
+			break;
+        case DOUBLE_TYPE:
+            dasm_put(Dst, 344);
+			#if ARM_HF
+			lua_pop(L, 1);
+            #else
+			goto dual;
+			#endif
+			break;
+		case COMPLEX_DOUBLE_TYPE:
+            lua_pop(L, 1);
+			dasm_put(Dst, 349, st.extra);
+			break;
+		case COMPLEX_FLOAT_TYPE:
+            lua_pop(L, 1);
+			dasm_put(Dst, 360, st.extra);
+			break;
+			
+        single:
+            lua_pop(L, 1);
+		single_no_pop:	
+            dasm_put(Dst, 371);
+			
+            break;
+		dual:
+			dasm_put(Dst, 378);
+			
+            lua_pop(L, 1);
+			break;
+       
+
+        
+        default:
+            luaL_error(L, "NYI: callback return type");
+        }
+    }
+	
+    dasm_put(Dst, 387);
+	
+    lua_pop(L, 1); /* upval table - already in registry */
+    assert(lua_gettop(L) == top);
+
+    {
+        void* p;
+        struct ctype ft;
+        cfunction func;
+
+        func = compile(Dst, L, NULL, ref);
+
+        ft = *ct;
+        ft.is_jitted = 1;
+        p = push_cdata(L, ct_usr, &ft);
+        *(cfunction*) p = func;
+
+        assert(lua_gettop(L) == top + 1);
+
+        return func;
+    }
+}
+
+static ALWAYS_INLINE void save_int64_stack_align(struct jit* Dst,reg_info* regs,int align){
+	if(align&&!ALIGNED(regs->exs,2)){
+		regs->exs++;
+		dasm_put(Dst, 389);
+	}
+	dasm_put(Dst, 391);
+	regs->exs+=2;
+}
+
+static ALWAYS_INLINE void save_int64_align(struct jit* Dst,reg_info* regs,int align){
+	if((align&&!ALIGNED(regs->ints,2))||(regs->ints==MAX_REGS-1&&regs->exs/*to ensure consective memory*/)){
+		regs->ints++;
+	}
+	if(regs->ints<MAX_REGS){
+		dasm_put(Dst, 393, ((regs->ints<<2)+0x40*ARM_HF));
+		regs->ints+=2;
+	}else{
+		save_int64_stack_align(Dst,regs,align);
+	}
+	
+}
+
+static ALWAYS_INLINE  void save_int64(struct jit* Dst,reg_info* regs){
+	save_int64_align(Dst,regs,1);
+}
+
+static ALWAYS_INLINE void save_int_stack_align(struct jit* Dst,reg_info* regs){
+	dasm_put(Dst, 397);
+	regs->exs++;
+}
+
+static ALWAYS_INLINE void save_int(struct jit* Dst,reg_info* regs){
+	if(regs->ints<MAX_REGS){
+		dasm_put(Dst, 399, ((regs->ints++<<2)+0x40*ARM_HF));
+	}else{
+		save_int_stack_align(Dst,regs);
+	}
+}
+
+static void save_float(struct jit* Dst,reg_info* regs,int size,int isfloat){
+#if ARM_HF
+	if(!regs->float_sealed){
+		int reg=add_float_reg(regs,size,isfloat);
+		if(reg<0) goto SAVE_STACK;
+		switch(size){
+		case 8:
+		case 6:
+		case 4:
+			goto sf_2;
+		case 3:
+		case 2:
+			sf_2:
+			break;
+		case 1:
+			break;
+		}
+		return;
+	}
+	SAVE_STACK:
+	
+	if(!isfloat&&!ALIGNED(regs->exs,2)){
+		regs->exs++;
+		dasm_put(Dst, 402);
+	}
+	switch(size){
+		case 1:
+			dasm_put(Dst, 404);
+			break;
+		case 2:
+			dasm_put(Dst, 406);
+			break;
+		case 3:
+			dasm_put(Dst, 408);
+			break;
+		case 4:
+			dasm_put(Dst, 410);
+			break;
+		case 6:
+			dasm_put(Dst, 412);
+			break;
+		case 8:
+			dasm_put(Dst, 414);
+			break;	
+		
+	}
+	regs->exs+=size;
+	
+#else
+	if(size==1){
+		save_int(Dst,regs);
+	}else if(size==2){
+		save_int64_align(Dst,regs,!isfloat);
+	}
+#endif
+}
+
+static int calculate_stack(lua_State* L,int ct_usr,int nargs){
+	const struct ctype* mt;
+	reg_info regs;int i,stack=0;
+	memset(&regs,0,sizeof(reg_info));
+    for (i = 1; i <= nargs;++i){
+		lua_rawgeti(L, ct_usr, i);
+		mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (mt->pointers || mt->is_reference) {
+			stack+=add_int_reg(&regs);
+		}else{
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+					#if ARM_HF
+					stack+=add_float_reg(&regs,4,0)<0?4:0;
+					#else
+					stack+=add_int64_reg(&regs);
+					stack+=add_int64_reg(&regs);
+					#endif
+					FIX_ALIGN(stack,2);
+					break;
+				case DOUBLE_TYPE:
+					#if ARM_HF
+					stack+=add_float_reg(&regs,2,0)<0?2:0;
+					#else
+					stack+=add_int64_reg(&regs);
+					#endif
+					FIX_ALIGN(stack,2);
+					break;
+				case COMPLEX_FLOAT_TYPE:// Though complex alignment is 4, but vfp requires a sequence of regsiters
+					#if ARM_HF
+					stack+=add_float_reg(&regs,2,1)<0?2:0;
+					#else
+					stack+=add_int_reg(&regs);
+					stack+=add_int_reg(&regs);
+					#endif
+					break;
+				case FLOAT_TYPE:
+					#if ARM_HF
+					stack+=add_float_reg(&regs,1,1)<0?1:0;
+					#else
+					stack+=add_int_reg(&regs);
+					#endif
+					break;
+				case INT64_TYPE:
+					stack+=add_int64_reg(&regs);
+					FIX_ALIGN(stack,2);
+					break;
+				case STRUCT_TYPE:{
+					#if ARM_HF
+					int isfloat;
+					int hfasize=hfa_size(L,-1,mt,&isfloat);
+                    if(hfasize>0){
+						stack+=add_float_reg(&regs,2,0)<0?hfasize:0;
+						if(!isfloat){
+							FIX_ALIGN(stack,2);
+						}
+						break;
+                    }
+					#endif
+				}
+				case UNION_TYPE:{
+					int intsize=(mt->base_size+3)>>2;
+					if(mt->align_mask>4){//8-byte max alignment
+						if(regs.ints<MAX_REGS){
+							FIX_ALIGN(regs.ints,2);
+						}else{
+							FIX_ALIGN(stack,2);
+						}
+					}
+					
+					if(regs.ints+intsize<=MAX_REGS){
+						regs.ints+=intsize;
+					}else{
+						stack+=regs.ints+intsize-MAX_REGS;
+						regs.ints=MAX_REGS;
+					}
+					break;
+				}
+				default:
+					stack+=add_int_reg(&regs);//no need to check type support here
+			}
+		}
+		lua_pop(L,1);
+	}
+	FIX_ALIGN(stack,2);
+	return (regs.ints
+	#if ARM_HF
+	/**/||regs.floats
+	#endif
+	)?0x40*ARM_HF+0x10+stack*4:0;
+}
+
+void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals,ret_by_addr, stack_size;
+    const struct ctype* mt;
+    void* p; reg_info regs;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    p = push_cdata(L, ct_usr, ct);
+    *(cfunction*) p = func;
+    num_upvals = 1;
+
+    dasm_setup(Dst, build_actionlist);
+#if defined __thumb__ //keep frame pointer
+    dasm_put(Dst, 416);
+#else
+    dasm_put(Dst, 419);
+#endif
+#if CK_ALGIN
+	dasm_put(Dst, 422);
+#endif	
+    dasm_put(Dst, 424);
+    
+    /* Reserve enough stack space for all of the arguments. For hard floating point,
+	 * leave extra 64 bytes
+	 */
+	stack_size=calculate_stack(L,ct_usr,nargs);
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	
+	// Complex types in softfp and structs/unions larger than 4-bytes are return in the address stored in r0
+	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
+	(!ARM_HF&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(ARM_HF&&hfa_size(L,-1,mt,NULL));
+	lua_pop(L,1);
+	if(ret_by_addr){
+		if(stack_size==0)
+			stack_size=0x40*ARM_HF+0x10;
+		stack_size+=8;
+	}
+	if(stack_size>0){
+		if(stack_size>=1<<12){
+			dasm_put(Dst, 426, (unsigned short)(stack_size), (((unsigned int)(stack_size))>>16));
+		}else{
+			dasm_put(Dst, 432, stack_size);
+		}
+		if (ct->has_var_arg){
+			dasm_put(Dst, 435, nargs, (unsigned short)("too few arguments"), (((unsigned int)("too few arguments"))>>16));
+		}
+		dasm_put(Dst, 452, 0x40*ARM_HF+0x10);
+	} 
+	
+	memset(&regs,0,sizeof(reg_info));
+	
+    if (ret_by_addr) {	
+		regs.ints++;
+		dasm_put(Dst, 455, (unsigned short)(mt), (((unsigned int)(mt))>>16), 0x40*ARM_HF);
+	}
+	
+	
+    for (i = 1; i <= nargs; i++) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		
+        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE|| mt->type==STRUCT_TYPE || mt->type==UNION_TYPE) {
+            lua_getuservalue(L, -1);
+            num_upvals += 2;
+
+            dasm_put(Dst, 466, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16), i);
+			
+            if (mt->pointers || mt->is_reference) {
+                dasm_put(Dst, 477);
+            } else if (mt->type == FUNCTION_PTR_TYPE) {
+                dasm_put(Dst, 481);
+            } else if (mt->type == ENUM_TYPE) {
+                dasm_put(Dst, 485);
+            }else if(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE){
+				if(mt->is_empty) continue;
+				dasm_put(Dst, 489);
+				#if ARM_HF
+				{
+					int hfasize,isfloat;
+					hfasize=hfa_size(L,-2,mt,&isfloat);
+					if(hfasize){
+						switch(hfasize){
+							case 8:
+								break;
+							case 6:
+								break;
+							case 4:
+								break;
+							case 3:
+								break;
+							case 2:
+								break;
+							case 1:
+								break;
+								
+						}
+						save_float(Dst,&regs,hfasize,isfloat);
+						continue;
+					}
+				}
+				#endif
+				
+				if(mt->align_mask>4){//8 byte max alignment 
+					if(regs.ints<4){
+						FIX_ALIGN(regs.ints,2)
+					}else if(!ALIGNED(regs.exs,2)){
+						int diff=regs.exs;
+						regs.exs+=4;
+						dasm_put(Dst, 493);
+					}
+				}
+				int size=ROUND_UP(mt->base_size,4)>>2;
+				dasm_put(Dst, 495, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
+				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+size<=MAX_REGS)){//to ensure consective memory for the struct
+					dasm_put(Dst, 505, ((regs.ints<<2)+0x40*ARM_HF));
+				}else{
+					regs.ints=MAX_REGS;
+					dasm_put(Dst, 508);
+				}
+				dasm_put(Dst, 510);
+				if(regs.ints+size<=MAX_REGS){
+					regs.ints+=size;
+				}else{
+					int ex=regs.ints+size-MAX_REGS;
+					dasm_put(Dst, 512, (ex)<<2);
+					regs.exs+=ex;
+					regs.ints=MAX_REGS;
+				}
+				continue;
+			}
+
+            save_int(Dst,&regs);
+        } else {
+            lua_pop(L, 1);
+            dasm_put(Dst, 515, i);
+
+            switch (mt->type) {
+			case BOOL_TYPE:
+				dasm_put(Dst, 518);
+                save_int(Dst,&regs);
+                break;
+            case INT8_TYPE:
+                dasm_put(Dst, 524);
+                if (mt->is_unsigned) {
+                     dasm_put(Dst, 528);
+                } else {
+                     dasm_put(Dst, 530);
+                }
+                save_int(Dst,&regs);
+                break;
+
+            case INT16_TYPE:
+                dasm_put(Dst, 532);
+                if (mt->is_unsigned) {
+                    dasm_put(Dst, 536);
+                } else {
+                    dasm_put(Dst, 538);
+                }
+                save_int(Dst,&regs);
+                break;
+
+            case INT32_TYPE:
+                if (mt->is_unsigned) {
+                    dasm_put(Dst, 540);
+                } else {
+                    dasm_put(Dst, 544);
+                }
+                save_int(Dst,&regs);
+                break;
+            case INTPTR_TYPE:
+                dasm_put(Dst, 548);
+                save_int(Dst,&regs);
+				break;
+
+            case INT64_TYPE:
+                if (mt->is_unsigned) {
+                    dasm_put(Dst, 552);
+                } else {
+                    dasm_put(Dst, 556);
+                }
+				save_int64(Dst,&regs);
+                break;
+
+            case DOUBLE_TYPE:
+				dasm_put(Dst, 560);
+				save_float(Dst,&regs,2,0);
+                break;
+
+            case FLOAT_TYPE:
+				dasm_put(Dst, 564);
+                save_float(Dst,&regs,1,1);
+                break;
+				
+			case COMPLEX_DOUBLE_TYPE:
+				#if ARM_HF
+				save_float(Dst,&regs,4,0);
+				#else
+				FIX_ALIGN(regs.ints,2);
+				dasm_put(Dst, 568);
+				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+4<=MAX_REGS)){
+					dasm_put(Dst, 571, (regs.ints<<2));
+				}else{
+					regs.ints=MAX_REGS;
+					if(!ALIGNED(regs.exs,2)){
+						++regs.exs;
+						dasm_put(Dst, 574);
+					}
+					dasm_put(Dst, 576);
+				}
+				dasm_put(Dst, 578);
+				regs.ints+=4;
+				goto FIX_REG;
+				#endif
+				break;
+			case COMPLEX_FLOAT_TYPE:
+				#if ARM_HF
+				save_float(Dst,&regs,2,1);
+				#else
+				dasm_put(Dst, 581);
+				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+2<=MAX_REGS)){
+					dasm_put(Dst, 584, (regs.ints<<2));
+				}else{
+					regs.ints=MAX_REGS;
+					dasm_put(Dst, 587);
+				}
+				dasm_put(Dst, 589);
+				regs.ints+=2;
+				FIX_REG:
+				if(regs.ints>MAX_REGS){
+					dasm_put(Dst, 592, (regs.ints-4)<<2);
+					regs.exs+=regs.ints-MAX_REGS;
+					regs.ints=MAX_REGS;
+				}
+				#endif
+                break;
+            default:
+                luaL_error(L, "NYI: call arg type");
+            }
+        }
+    }
+
+    if (ct->has_var_arg) {
+		int offset=nargs+1;
+        dasm_put(Dst, 595, offset);
+		#if ARM_HF
+		    if(regs.ints==4||regs.float_sealed){
+				if(regs.ints<4&&regs.float_sealed){//some arg must be loaded to core registers.
+				}
+			} 
+		#else
+			if(regs.ints==4){
+				dasm_put(Dst, 598);
+			}
+		#endif
+		else{//no hard floating point in variadic procedure
+			dasm_put(Dst, 600, ((regs.ints<<2)+ARM_HF*0x40));
+		}
+        
+        dasm_put(Dst, 603);
+		regs.ints=4;
+    } 
+	
+	#if ARM_HF
+	switch(ROUND_UP(regs.highest_bit,4)>>1){
+		case 8 :
+			break;
+		case 7 :
+			break;
+		case 6 :
+			break;
+		case 5:
+			break;
+		case 4 :
+			break;
+		case 3 :
+			break;
+		case 2 :
+			break;
+		case 1 :
+			break;
+	}
+	if(stack_size>0){
+	}
+	#endif
+	
+	//pop registers from stack,align 8 for some compiler
+	assert(regs.ints<=4);
+	switch(regs.ints){
+	case 4:
+	case 3:
+		dasm_put(Dst, 608);
+		break;
+	case 2:
+	case 1:
+		dasm_put(Dst, 610);
+		#if ARM_HF
+		if(regs.float_sealed){
+		}
+		#endif
+		break;
+	default:
+		#if ARM_HF
+		if(regs.float_sealed){
+		}
+		#endif
+		break;
+	}
+	
+	dasm_put(Dst, 612, (unsigned short)(func), (((unsigned int)(func))>>16));
+
+    lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+
+    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
+        lua_getuservalue(L, -1);
+        num_upvals += 2;
+        dasm_put(Dst, 618, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+
+    } else {
+        switch (mt->type) {
+        case INT64_TYPE:
+        #if LUA_VERSION_NUM>=503
+             lua_pop(L, 1);
+	    #if CK_ALGIN
+            dasm_put(Dst, 633);
+		#else
+            dasm_put(Dst, 636);
+		#endif		
+            dasm_put(Dst, 639);
+            break;
+		#else
+			num_upvals++;
+            dasm_put(Dst, 644, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+            break;
+        #endif
+		
+        case INTPTR_TYPE:
+            num_upvals++;
+            dasm_put(Dst, 658, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+            break;
+
+        case VOID_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 670);
+            break;
+
+        case BOOL_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 672);
+            break;
+
+        case INT8_TYPE:
+        case INT16_TYPE:
+        case INT32_TYPE:
+        case ENUM_TYPE:// value must be narrowed before callee return
+            lua_pop(L, 1);
+			
+            dasm_put(Dst, 678);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 680);
+            } else {
+                dasm_put(Dst, 684);
+            }
+			
+            dasm_put(Dst, 688);
+            break;
+
+        case FLOAT_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 690);
+            break;
+
+        case DOUBLE_TYPE:
+            lua_pop(L, 1);
+        #if CK_ALGIN
+            dasm_put(Dst, 696);
+		#else
+			dasm_put(Dst, 699);
+		#endif	
+            dasm_put(Dst, 702);
+            break;
+		case COMPLEX_DOUBLE_TYPE:
+		case COMPLEX_FLOAT_TYPE:
+		case STRUCT_TYPE:
+		case UNION_TYPE:{
+			lua_getuservalue(L,-1);
+            num_upvals += 2;
+			#if ARM_HF
+			{
+				int isfloat,hfasize=hfa_size(L,-2,mt,&isfloat);
+				if(hfasize>0){
+					switch(hfasize){
+						case 8:
+							break;
+						case 6:
+							break;
+						case 4:
+						case 3:
+							break;
+						case 2:
+						case 1:
+							break;
+							
+					}
+					switch(hfasize){
+						case 8:
+							break;
+						case 6:
+							break;
+						case 4:
+							break;
+						case 3:
+							break;
+						case 2:
+							break;
+						case 1:
+							break;
+							
+					}
+					break;
+				}
+			}
+			
+			#endif
+			if(mt->base_size>4){
+				// value are stored in return storage in r0 for softfp, set usr value here
+				if(!lua_isnil(L,-1)){
+					dasm_put(Dst, 707, (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+				}
+			}else if(mt->is_empty){
+				dasm_put(Dst, 719);
+				break;
+			}else{
+				dasm_put(Dst, 721, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+			}
+            dasm_put(Dst, 735);
+			break;
+		}	
+        default:
+            luaL_error(L, "NYI: call return type");
+        }
+    }
+
+#ifdef __thumb__
+    dasm_put(Dst, 737);
+#else	
+    dasm_put(Dst, 740);
+#endif	
+    assert(lua_gettop(L) == top + num_upvals);
+    {
+        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
+        /* add a callback as an upval so that the jitted code gets cleaned up when
+         * the function gets gc'd */
+        push_callback(L, f, func);
+        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
+    }
+}
+
diff --git a/source/texk/web2c/luatexdir/luaffi/call_arm64.dasc b/source/texk/web2c/luatexdir/luaffi/call_arm64.dasc
index e6198451b..275365e2b 100644
--- a/source/texk/web2c/luatexdir/luaffi/call_arm64.dasc
+++ b/source/texk/web2c/luatexdir/luaffi/call_arm64.dasc
@@ -1,1496 +1,1496 @@
-/* vim: ts=4 sw=4 sts=4 et tw=78
- * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
- * Portions copyright (c) 2011 James R. McKaskill.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-|.arch arm64
-
-|.actionlist build_actionlist
-|.globalnames globnames
-|.externnames extnames
-
-#define JUMP_SIZE 16
-
-//in aarch64 the pc is indicated the current 
-#define MIN_BRANCH ((INT32_MIN) >> 6)
-#define MAX_BRANCH ((INT32_MAX) >> 6)
-//arm64 pc has no offset so comparing with next instruction is -4 
-#define BRANCH_OFF -4
-#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
-
-static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
-{
-    /* The jump code is the function pointer followed by a stub to call the
-     * function pointer. The stub exists so we can jump to functions with an
-     * offset greater than 128MB.
-     *
-     * Note we have to manually set this up since there are commands buffered
-     * in the jit state.
-     */
-	 
-	 //l: ptr
-	 *(cfunction*) code = func;
-	 // ldr x9,#-8
-	  *(uint32_t*) &code[8] = 0x58FFFFC9;
-	 //br x9
-	 *(uint32_t*) &code[12] = 0xD61F0120;
-	
-}
-
-|.define TOP, x19
-|.define DATA,x20
-|.define L_ARG,x21
-|.macro load64, reg, val
-//| ldr reg, >5
-//| b >6
-//|5:
-//|.long64 val
-//|6:
-| mov reg, #(unsigned short)(val)
-| movk reg, #(((unsigned int)(val))>>16), lsl #16
-| movk reg, #(unsigned short)((unsigned long)(val)>>32), lsl #32
-| movk reg, #(unsigned short)((unsigned long)(val)>>48), lsl #48
-|.endmacro
-
-|.macro load32, reg, val
-| mov reg, #(unsigned short)(val)
-| movk reg, #(((unsigned int)(val))>>16), lsl #16
-|.endmacro
-
-|.macro lcall, func
-| mov x0, L_ARG
-| bl func
-|.endmacro
-
-void compile_globals(struct jit* jit, lua_State* L)
-{
-    (void) jit;
-}
-typedef struct reg_info{
-	uint8_t ints;
-	uint8_t floats;
-	uint16_t ex;
-} reg_info;
-
-static ALWAYS_INLINE bool is_float_type(int t){
-    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
-}
-
-static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
-	struct ctype* mt;
-	int type,ele_count,i,ct_usr;
-	lua_getuservalue(L,idx);
-	ct_usr=lua_absindex(L,-1);
-    lua_rawgeti(L,ct_usr,1);
-    mt=(struct ctype*)lua_touserdata(L,-1);
-    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-        lua_pop(L,2);
-        return 0;
-    }
-	type=mt->type;
-    ele_count=(int)(ct->base_size/mt->base_size);
-    if(ele_count>4||ct->base_size%mt->base_size){
-        lua_pop(L,2);
-        return 0;
-    }
-	lua_pop(L,1);
-    for (i = 2;i<=4; ++i) {
-        lua_rawgeti(L,ct_usr,i);
-		if(lua_isnil(L,-1)){//case have array member;
-            lua_pop(L,1);
-            break;
-        }
-        mt=(struct ctype*)lua_touserdata(L,-1);
-        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-            lua_pop(L,2);
-            return 0;
-        }
-        lua_pop(L,1);
-    }
-	if(isfloat){
-		*isfloat=mt->type==FLOAT_TYPE;
-	}
-	lua_pop(L,1);
-    return ele_count;
-}
-
-static reg_info caculate_regs(lua_State* L,int ct_usr,int nargs){
-    int i;reg_info regs;
-    const struct ctype* mt;
-    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs&&(regs.floats<8||regs.ints<8); ++i){
-		lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (mt->pointers || mt->is_reference) {
-			if(regs.ints<8)regs.ints++;
-		}else{
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-				case COMPLEX_FLOAT_TYPE:
-					if(regs.floats<7)
-						regs.floats+=2;
-					else if(regs.floats==7)
-						regs.floats=8;
-					break;
-				case FLOAT_TYPE:
-				case DOUBLE_TYPE:
-					if(regs.floats<8) ++regs.floats;
-					break;
-				case STRUCT_TYPE:{
-                    int hfasize=hfa_size(L,-1,mt,NULL);
-                    if(hfasize>0){
-						regs.floats+=hfasize;
-						if(regs.floats>8)
-							regs.floats=8;
-						break;
-                    }
-                }
-				case UNION_TYPE:{
-					int size=mt->base_size;
-					if(size>16){//passed by address
-						if(regs.ints<8)++regs.ints;
-						break;
-					}
-					if(mt->is_empty){
-						break; //ignored empty struct
-					}
-					size=(size+7)>>3;
-					if(regs.ints+size<=8) regs.ints+=size;
-					break;
-				}
-				default:
-					if(regs.ints<8)++regs.ints;//no need to check type support here
-			}
-		}
-		lua_pop(L,1);
-	}
-	
-	return regs;
-}
-
-// arm store/load range for immediate value is only -256-255
-static ALWAYS_INLINE void load_int(struct jit* Dst,reg_info* regs){
-	if(regs->ints<8)
-		| ldr x1, [sp, #0x60+(regs->ints++<<3)] //64 bit ptr
-	else
-		| ldr x1, [DATA],  #(regs->ex++,8)
-}
-
-static void load_float(struct jit* Dst,reg_info* regs,int isfloat,int exSize){
-	if(regs->floats+exSize<8){
-		switch(exSize){
-			case 3:
-				| ldp d2,d3, [sp, #0x30+(regs->floats<<3)]
-				goto l_dual;
-			case 2:
-			    | ldr d2, [sp, #0x30+(regs->floats<<3)]
-			case 1:
-			    l_dual:
-				| ldp d0,d1, [sp, #0x20+(regs->floats<<3)]
-				break;
-			case 0:
-			    | ldr d0, [sp, #0x20+(regs->floats<<3)]
-				break;
-		}
-		regs->floats+=exSize+1;
-		
-	}else{
-		regs->floats=8;
-		regs->ex+=exSize+1;
-		switch(exSize){
-			case 3:
-				if(isfloat){
-					| ldp s0,s1, [DATA], #8
-					| ldp s2,s3, [DATA], #8
-				}else{
-					| ldp d0, d1, [DATA], #16
-					| ldp d2, d3, [DATA], #16
-				}
-			     break;
-			case 2:
-				if(isfloat){ //12 bytes rounded to 16
-					| ldp s0,s1, [DATA], #8
-					| ldr s2, [DATA], #8
-					break;
-				}else {
-					| ldp d0, d1, [DATA], #16
-					| ldr d2, [DATA], #8
-				}
-			     break;
-			case 1:
-				if(isfloat){
-					| ldp s0,s1, [DATA], #8
-				}else{
-					| ldp d0, d1, [DATA], #16
-				}
-				break;
-			case 0:
-				if(isfloat){
-					| ldr s0, [DATA], #8
-				}else {
-					| ldr d0, [DATA], #8
-				}
-				break;
-		}
-	
-	}
-}
-
-cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals, ref,ret_by_addr;
-    const struct ctype* mt;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    fidx = lua_absindex(L, fidx);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    dasm_setup(Dst, build_actionlist);
-
-    lua_newtable(L);
-    lua_pushvalue(L, -1);
-    ref = luaL_ref(L, LUA_REGISTRYINDEX);
-    num_upvals = 0;
-
-    if (ct->has_var_arg) {
-        luaL_error(L, "can't create callbacks with varargs");
-    }
-	
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
-				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
-	if(ret_by_addr){
-		| str x8, [sp, #-16]! //preserve ret address;
-	}
-	lua_pop(L,1);	
-	reg_info regs=caculate_regs(L,ct_usr,nargs);
-	
-	if(regs.ints||regs.floats){
-		| sub sp,sp,#0xa0
-	}else{
-		| sub sp,sp,#0x20
-	}
-	//8 integer reigsters and 8 floating registers
-	switch(regs.ints){
-		case 8:
-		case 7:
-			| stp x6,x7, [sp,#0x90]
-		case 6:
-		case 5:
-			| stp x4,x5, [sp,#0x80]
-		case 4:
-		case 3:
-			| stp x2,x3, [sp,#0x70]
-		case 2:
-		case 1:
-			| stp x0,x1, [sp,#0x60]	
-	}	
-
-	switch(regs.floats){
-		case 8:
-		case 7:
-			| stp d6,d7, [sp,#0x50]
-		case 6:
-		case 5:
-			| stp d4,d5, [sp,#0x40]
-		case 4:
-		case 3:
-			| stp d2,d3, [sp,#0x30]
-		case 2:
-		case 1:
-			| stp d0,d1, [sp,#0x20]
-	} 
-	| stp DATA, L_ARG,[sp,#0x10]
-	| stp x29, x30,[sp]
-	
-	if(regs.ints==8||regs.floats==8){ // may be overflowed if it's full
-		| add DATA, sp, #0xa0+ret_by_addr*0x10
-	}
-	
-    /* get the lua function */
-    lua_pushvalue(L, fidx);
-    lua_rawseti(L, -2, ++num_upvals);
-	
-	| load64 L_ARG, L
-	| load32 w2, ref
-	| load32 w1, LUA_REGISTRYINDEX
-	| lcall extern rawgeti //get the table
-	
-	| mov w2, #num_upvals
-    | movn x1, #0 // -1
-    | lcall extern rawgeti //get the function
-	
-
-    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; ++i) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-
-        if (mt->pointers || mt->is_reference) {
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-			
-            | mov w2, #num_upvals-1 // usr value
-            | movn x1, #i // -i-1, stack is upval table, func, i-1 args
-            | lcall extern rawgeti
-            | load64 x2, mt
-            | movn w1, #0 // -1
-            | lcall extern push_cdata
-			load_int(Dst,&regs);
-            | str x1, [x0]
-            | movn w1, #1 //-2
-            | lcall extern lua_remove // remove the usr value
-
-        } else {
-            switch (mt->type) {
-			case STRUCT_TYPE:
-			case UNION_TYPE:{
-				int isfloat,hfasize=0;
-				if(mt->type!=UNION_TYPE){
-					hfasize=hfa_size(L,-1,mt,&isfloat);
-				}
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-				| mov w2, #num_upvals-1 // usr value
-				| movn x1, #i // -i-1, stack is upval table, func, i-1 args
-				| lcall extern rawgeti
-				| load64 x2, mt
-				| movn w1, #0 // -1
-                | lcall extern push_cdata
-				
-				if(hfasize){
-					load_float(Dst,&regs,isfloat,hfasize-1);
-					switch(hfasize){
-						case 4:
-							if(isfloat){
-								| stp s2, s3, [x0,#8]
-							}else{
-								| stp d2, d3, [x0,#16]
-							}
-							goto hfa2;
-						case 3:
-							if(isfloat){
-								| str s2, [x0,#8]
-							}else{
-								| str d2, [x0,#16]
-							}
-						case 2:
-            			hfa2:
-							if(isfloat){
-								| stp s0, s1, [x0]
-							}else{
-								| stp d0, d1, [x0]
-							}
-							break;
-						case 1:
-							if(isfloat){
-								| str s0, [x0]
-							}else{
-								| str d0, [x0]
-							}
-							break;
-         							
-					}
-				}else if(!mt->is_empty){
-					size_t size=mt->base_size;
-					if(size>16){
-						load_int(Dst,&regs);
-						| load64 x2, mt->base_size
-						| load64 x9, memcpy
-						| blr x9
-					}else{
-						size=(size+7)>>3;
-						if(mt->align_mask>8){
-							if(regs.ints&1) regs.ints++;
-							else if(regs.ex&1) regs.ex++;
-						}
-						if(regs.ints+size<=8){
-							if(size>1){
-								| ldp x1,x2, [sp,#0x60+(regs.ints<<3)]
-								| stp x1, x2, [x0]
-							}else{
-								| ldr x1, [sp,#0x60+(regs.ints<<3)]
-								| str x1, [x0]
-							}
-							regs.ints+=size;
-						}else{
-							regs.ints=8;
-							if(size>1){
-								| ldp x1,x2, [DATA], #16
-								| stp x1, x2, [x0]
-							}else{
-								| ldr x1, [DATA], #8
-								| str x1, [x0]
-							}
-							
-						} 
-					}
-					
-					
-				}
-				
-                | movn w1, #1 // -2
-                | lcall extern lua_remove // remove the nil usr
-			    break;
-			}
-			case COMPLEX_DOUBLE_TYPE:
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-				| mov w2, #num_upvals-1 // usr value
-				| movn x1, #i // -i-1, stack is upval table, func, i-1 args
-				| lcall extern rawgeti
-				| load64 x2, mt
-				| movn w1, #0 // -1
-                | lcall extern push_cdata
-				load_float(Dst,&regs,0,1);
-				|stp d0,d1,[x0]
-                | movn w1, #1 // -2
-                | lcall extern lua_remove // remove the nil usr
-				
-				break;
-			case COMPLEX_FLOAT_TYPE:
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                | mov w2, #num_upvals-1 // usr value
-                | movn x1, #i // -i-1, stack is upval table, func, i-1 args
-                | lcall extern rawgeti
-                | load64 x2, mt
-                | movn w1, #0 // -1
-                | lcall extern push_cdata
-				load_float(Dst,&regs,1,1);
-                | stp s0,s1, [x0]
-                | movn w1, #1 // -2
-                | lcall extern lua_remove // remove the nil usr
-				
-				break;
-            case INT64_TYPE:
-			    #if LUA_VERSION_NUM>=503
-                lua_pop(L, 1);
-				load_int(Dst,&regs);
-                | lcall extern lua_pushinteger
-				
-				#else
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                | load64 x2, mt
-                | mov w1, wzr
-                | lcall extern push_cdata
-                load_int(Dst,&regs);
-                | str x1, [x0]
-                | movn w1, #1 // -2
-                | lcall extern lua_remove // remove the nil usr
-				
-				#endif
-                break;
-
-            case INTPTR_TYPE:
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                | load64 x2, mt
-                | mov w1, wzr
-                | lcall extern push_cdata
-                load_int(Dst,&regs);
-                | str x1, [x0]
-                | movn w1, #1 // -2
-                | lcall extern lua_remove // remove the nil usr
-				
-                break;
-
-            case BOOL_TYPE:
-                lua_pop(L, 1);
-				
-				load_int(Dst,&regs);
-				| lcall extern lua_pushboolean
-				
-                break;
-
-            case INT8_TYPE:// need to narrow for caller doesn't do it
-				lua_pop(L, 1);
-				if(regs.ints<8){
-					if (mt->is_unsigned) {
-						| ldrb w1, [sp,#0x60+(regs.ints++<<3)]
-					} else {
-						| ldrsb w1, [sp,#0x60+(regs.ints++<<3)]
-					}
-				}else {
-					if (mt->is_unsigned) {
-						| ldrb w1, [DATA], #8
-					} else {
-						| ldrsb w1, [DATA], #8
-					}
-				}
-				| lcall extern push_int
-				break;
-			
-            case INT16_TYPE:// need to narrow for caller doesn't do it
-				lua_pop(L, 1);
-				if(regs.ints<8){
-					if (mt->is_unsigned) {
-						| ldrh w1, [sp,#0x60+(regs.ints++<<3)]
-					} else {
-						| ldrsh w1, [sp,#0x60+(regs.ints++<<3)]
-					}
-				}else {
-					if (mt->is_unsigned) {
-						| ldrh w1, [DATA], #8
-					} else {
-						| ldrsh w1, [DATA], #8
-					}
-				}
-				| lcall extern push_int
-				break;
-				
-            case ENUM_TYPE:
-            case INT32_TYPE:
-                lua_pop(L, 1);
-				load_int(Dst,&regs);
-				
-                | lcall extern push_int
-                break;
-
-            case FLOAT_TYPE:
-                lua_pop(L, 1);
-				load_float(Dst,&regs,1,0);
-                | lcall extern push_float
-                break;
-
-            case DOUBLE_TYPE:
-                lua_pop(L, 1);
-				load_float(Dst,&regs,0,0);
-                | lcall extern lua_pushnumber
-                break;
-            default:
-                luaL_error(L, "NYI: callback arg type");
-            }
-        }
-    }
-
-    lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-
-    | mov w2, #((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0)
-    | mov w1, #nargs
-    | lcall extern lua_call
-    
-	|.macro retcdata, func
-	| mov w2, #num_upvals-1 // usr value
-	| movn x1, #1 // -2 stack is (upval table, ret val)
-	| lcall extern rawgeti
-	| load64 x3, mt
-	| movn x2, #0 // -1 - ct_usr
-	| movn x1, #1 // -2 - val
-	| lcall extern func
-	|.endmacro
-
-	
-    if (mt->pointers || mt->is_reference) {
-        lua_getuservalue(L, -1);
-        lua_rawseti(L, -3, ++num_upvals); /* usr value */
-        lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-        | retcdata check_typed_pointer
-        goto single_no_pop;
-    } else {
-        switch (mt->type) {
-		case STRUCT_TYPE:
-		case UNION_TYPE:{
-			int hfasize=0,isfloat;
-			if(mt->type!=UNION_TYPE){
-				hfasize=hfa_size(L,-1,mt,&isfloat);
-			}
-			lua_getuservalue(L, -1);
-			lua_rawseti(L, -3, ++num_upvals); /* usr value */
-			lua_rawseti(L, -2, ++num_upvals); /* mt */
-			| retcdata check_struct
-			| mov DATA ,x0
-			| movn w1, #2 // -3
-            | lcall extern lua_settop
-			if(hfasize){
-				switch(hfasize){
-					case 4:
-					    if(isfloat){
-							| ldp s2,s3, [DATA,#8]
-						}else{
-							| ldp d2,d3, [DATA,#16]
-						}
-						goto ld_hfa;
-					case 3:
-						if(isfloat){
-							| ldr s2, [DATA,#8]
-						}else{
-							| ldr d2, [DATA,#16]
-						}
-					case 2:
-						ld_hfa:
-					    if(isfloat){
-							| ldp s0,s1, [DATA]
-						}else{
-							| ldp d0,d1, [DATA]
-						}
-						break;
-					case 1:
-						if(isfloat){
-							| ldr s0, [DATA]
-						}else{
-							| ldr d0, [DATA]
-						}
-					    break;
-				}
-			}else{
-				if(mt->base_size>16){
-					| ldr x0, [sp, #0x20+((regs.ints||regs.floats)?0x80:0)]
-					| mov x1, DATA
-					| load64 x2, mt->base_size
-					| load64 x9, memcpy
-					| blr x9
-				}else{
-					if(mt->base_size>8){
-						| ldp x0, x1, [DATA]
-					}else{
-						| ldr x0, [DATA]
-					}
-				}
-			}
-			break;
-		}
-        case ENUM_TYPE:
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-            | retcdata check_enum
-
-            goto single_no_pop;
-
-        case VOID_TYPE:
-		    | movn w1,#1 //-2
-            | lcall extern lua_settop
-            lua_pop(L, 1);
-            break;
-
-        case BOOL_TYPE:
-        case INT8_TYPE:
-        case INT16_TYPE:
-        case INT32_TYPE: //caller's responsiblity to narrow 
-		    | movn w1,#0
-            if (mt->is_unsigned) {
-                | lcall extern check_uint32
-            } else {
-                | lcall extern check_int32
-            }
-			
-            goto single;
-
-        case INT64_TYPE:
-            | movn w1,#0 //-1
-            if (mt->is_unsigned) {
-                | lcall extern check_uint64
-            } else {
-                | lcall extern check_int64
-            }
-			
-			goto single;
-
-        case INTPTR_TYPE:
-            | movn w1,#0 //-1
-            | lcall extern check_uintptr
-            goto single;
-
-        case FLOAT_TYPE:
-            | movn w1,#0 //-1
-            | lcall extern check_float
-			
-            | fmov DATA,d0
-            | movn w1, #2 // -3
-            | lcall extern lua_settop
-            | fmov d0,DATA
-            lua_pop(L, 1);
-			break;
-        case DOUBLE_TYPE:
-            | movn w1,#0 //-1
-            | lcall extern check_double
-			
-			| fmov DATA,d0
-            | movn w1, #2 // -3
-            | lcall extern lua_settop
-            | fmov d0,DATA
-			
-            lua_pop(L, 1);
-			break;
-			
-		case COMPLEX_DOUBLE_TYPE:
-
-			| movn w1, #0 // -1
-			| lcall extern check_complex_double
-		    
-			goto complex_ret;
-		case COMPLEX_FLOAT_TYPE:
-			| movn w1, #0 // -1
-			| lcall extern check_complex_float
-			
-		complex_ret:	
-			| mov x0,L_ARG
-            | movn w1, #2 // -3
-		    | fmov DATA,d0
-			| fmov L_ARG,d1
-            | bl extern lua_settop
-            | fmov d0,DATA
-			| fmov d1,L_ARG
-
-            lua_pop(L, 1);			
-			break;
-        single:
-            lua_pop(L, 1);
-		single_no_pop:	
-            | mov DATA, x0
-            | movn w1, #2 // -3
-            | lcall extern lua_settop
-            | mov x0, DATA
-            break;
-
-        
-        default:
-            luaL_error(L, "NYI: callback return type");
-        }
-    }
-	
-	| ldp x29,x30,[sp] 
-	| ldp DATA, L_ARG,[sp,#0x10]
-	| add sp,sp, # (0x20 +ret_by_addr*0x10+ ((regs.floats!=0)||(regs.ints!=0)) * 0x80)
-	| ret
-	
-    lua_pop(L, 1); /* upval table - already in registry */
-    assert(lua_gettop(L) == top);
-
-    {
-        void* p;
-        struct ctype ft;
-        cfunction func;
-
-        func = compile(Dst, L, NULL, ref);
-
-        ft = *ct;
-        ft.is_jitted = 1;
-        p = push_cdata(L, ct_usr, &ft);
-        *(cfunction*) p = func;
-
-        assert(lua_gettop(L) == top + 1);
-
-        return func;
-    }
-}
-
-//arm64 argument can only be in stack or registers. An argument can't be splited between stack and register.
-static  void store_float(struct jit* Dst,reg_info* regs,int isfloat,int ex){
-	if(regs->floats+ex<8){
-		
-		switch(ex){
-			case 3:
-				| stp d2,d3, [sp, #0x10+(regs->floats<<3)] 
-			     goto sd_dual;
-			case 2:
-			    | str d2, [sp, #0x10+(regs->floats<<3)]
-			case 1:
-			    sd_dual:
-				| stp d0,d1, [sp, #(regs->floats<<3)] 
-				break;
-			case 0:
-				| str d0, [sp, #(regs->floats<<3)]
-				break;
-		}
-		regs->floats+=1+ex;
-	}else {
-		regs->floats=8;
-		switch(ex){
-			case 3:
-			    if(isfloat){
-					| stp s0,s1, [DATA], #8
-					| stp s2,s3, [DATA], #8
-				}else{
-					| stp d0, d1, [DATA], #16
-					| stp d2, d3, [DATA], #16
-				}				
-			    break;
-			case 2:
-			    if(isfloat){
-					| stp s0,s1, [DATA], #8
-					| str s2, [DATA], #8
-				}else{
-					| stp d0, d1,[DATA], #16
-					| str d2, [DATA], #8
-				}
-				break;
-			case 1:
-			    if(isfloat){
-					| stp s0,s1, [DATA], #8
-				}else{
-					| stp d0, d1,[DATA], #16
-				}
-				break;
-			case 0:
-				if(isfloat){
-					| str s0, [DATA], #8
-				}else {
-					| str d0, [DATA], #8
-				}
-				break;
-		}
-		//complex float is packed as one double on stack
-		regs->ex+=ex+1;
-	} 
-}
-
-static void store_int(struct jit* Dst,reg_info* regs,int intSize){
-	switch(intSize){
-		case 1:
-			if(regs->ints<8)
-				| str w0, [sp,#0x40+(regs->ints++<<3)]
-			else
-				| str w0, [DATA], #(regs->ex++,8)
-            break;
-		case 2:
-			if(regs->ints<8)
-				| str x0, [sp,#0x40+(regs->ints++<<3)]
-			else
-				| str x0, [DATA], #(regs->ex++,8)
-			break;
-		case 3:
-		case 4:
-			if(regs->ints<7){
-				| stp x0,x1, [sp,#0x40+(regs->ints<<3)]
-				regs->ints+=2;
-			}
-			else{
-				if(regs->ints==7)
-					regs->ints=8;
-				| stp x0,x1, [DATA], #16
-				regs->ex+=2;
-			}
-				
-			break;
-	}
-}
-
-static int caculate_stack(lua_State* L,int ct_usr,int nargs){
-    int i;reg_info regs={0,0,0};
-    const struct ctype* mt;int stack=0,extra=0;
-    for (i = 1; i <= nargs; ++i){
-		lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (mt->pointers || mt->is_reference) {
-			if(regs.ints<8)regs.ints++;
-			else stack++;
-		}else{
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-				case COMPLEX_FLOAT_TYPE:
-					if(regs.floats<7)
-						regs.floats+=2;
-					else if(regs.floats==7)
-						regs.floats=8;
-					else stack+=mt->base_size>>3;
-					break;
-				case FLOAT_TYPE:
-				case DOUBLE_TYPE:
-					if(regs.floats<8) ++regs.floats;
-					else stack++;
-					break;
-				case STRUCT_TYPE:{
-					int isfloat;
-                    int hfasize=hfa_size(L,-1,mt,&isfloat);
-                    if(hfasize>0){
-						if(regs.floats+hfasize<=8)
-							regs.floats +=hfasize;
-						else {
-						    regs.floats=8;
-							stack+=(hfasize*(2-isfloat)+1)>>1;	
-						}
-						break;
-                    }
-                }
-				case UNION_TYPE:{
-					int size=mt->base_size;
-					size=(size+7)>>3;
-					if(size>2){//passed by address
-						if(regs.ints<8)++regs.ints;
-						else stack++;
-					    extra+=size;//extra copy stack;
-						break;
-					}
-					if(mt->is_empty){
-						break; //ignored empty struct
-					}
-					if(mt->align_mask>8){
-						if(regs.ints&1) regs.ints++;
-						else if(stack&1) stack++;
-					}
-					if(regs.ints+size<=8) regs.ints+=size;
-					else{
-						regs.ints=8;
-						stack+=size;
-					} 
-					
-					break;
-				}
-				default:
-					if(regs.ints<8)++regs.ints;//no need to check type support here
-					else stack++;
-			}
-		}
-		lua_pop(L,1);
-	}
-	
-	return (regs.ints||regs.floats)?((stack+extra+17/*16 for regs, 1 for align*/)>>1)<<4:0;//2 eightbytes align
-}
-
-
-void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals,ret_by_addr;
-    const struct ctype* mt;
-	int stack_size,struct_offset;
-    void* p;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    p = push_cdata(L, ct_usr, ct);
-    *(cfunction*) p = func;
-    num_upvals = 1;
-
-    dasm_setup(Dst, build_actionlist);
-
-    reg_info regs={0,0};
-	
-	| sub sp,sp,#0x30
-	| str L_ARG, [sp,#20]
-	| stp TOP,DATA,[sp,#0x10]
-	| stp x29,x30,[sp]
-	| mov x29,sp
-	| mov L_ARG,x0
-	
-    /* reserve enough stack space for all of the arguments. */
-	stack_size=caculate_stack(L,ct_usr,nargs);
-	struct_offset=0;
-	if(stack_size>0){
-		if(stack_size>=1<<12){
-			| load32 x9, stack_size //trick x9
-			| sub sp, sp, x9
-		}
-		else{
-			| sub sp, sp, #stack_size
-		}
-		 if (ct->has_var_arg) {
-			| bl extern lua_gettop
-			| cmp w0, #nargs
-			| bge >1
-			| load64 x1, "too few arguments"
-			| lcall extern luaL_error
-			|1:
-			| mov TOP, x0
-			| add x0, x0, #1
-			| bfm x0,xzr, #0, #0 //round up 2 for stack alignment.
-			| sub sp, sp, x0, lsl #3
-		}
-		| add DATA,sp,#0x80
-    }
-	
-    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; i++) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		
-        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE||mt->type==STRUCT_TYPE||mt->type==UNION_TYPE) {
-            lua_getuservalue(L, -1);
-            num_upvals += 2;
-
-			
-			| load64 x3,mt
-			| load32 w2,lua_upvalueindex(num_upvals)
-			| mov x1,#i
-			
-            if (mt->pointers || mt->is_reference) {
-                | lcall extern check_typed_pointer
-            } else{
-				switch (mt->type) {
-					case FUNCTION_PTR_TYPE: {
-						| lcall extern check_typed_cfunction
-						break;
-					}
-					case ENUM_TYPE:{
-						| lcall extern check_enum
-						break;
-					} 
-					case STRUCT_TYPE:
-					case UNION_TYPE:{
-						if(mt->is_empty) continue;
-		
-						int isfloat;
-						int hfasize=hfa_size(L,-2,mt,&isfloat);
-						| lcall extern check_struct
-                        if(hfasize>0){
-							switch(hfasize){
-								case 4:
-									if(isfloat){
-										| ldp s2,s3, [x0,#8]
-									}else{
-										| ldp d2,d3, [x0,#16]
-									}
-									goto ld_hfa;
-								case 3:
-									if(isfloat){
-										| ldr s2, [x0,#8]
-									}else{
-										| ldr d2, [x0,#16]
-									}
-								case 2:
-									ld_hfa:
-									if(isfloat){
-										| ldp s0,s1, [x0]
-									}else{
-										| ldp d0,d1, [x0]
-									}
-									break;
-								case 1:
-									if(isfloat){
-										| ldr s0, [x0]
-									}else{
-										| ldr d0, [x0]
-									}
-									break;
-									
-							}
-							store_float(Dst,&regs,isfloat,hfasize-1);
-							continue;
-						}
-						if(mt->base_size>16){
-							| mov x1 ,x0
-							struct_offset+=(mt->base_size+7)&(~7);
-							if(struct_offset>=1<<12){
-								| load32 x0, struct_offset //trick x0
-								| sub x0, x29, x0
-							}
-							else{
-								| sub x0, x29, #struct_offset
-							}
-							store_int(Dst,&regs,2);
-							| mov x2, #mt->base_size
-							| load64 x9, memcpy
-							| blr x9
-						}else{
-							if(mt->align_mask>8){//==15
-								if(regs.ints&1) regs.ints++;
-								else if(regs.ex&1) regs.ex++;
-							}
-							int intSize=(mt->base_size+3)>>2;
-							switch(intSize){
-								case 1:
-									| ldr w0, [x0]
-									break;
-								case 2:
-									| ldr x0, [x0]
-									break;
-								case 3:
-								case 4:
-								    | ldp x0, x1, [x0]
-									break;
-							}
-							store_int(Dst,&regs,intSize);
-						}
-						continue;
-					}	
-				}
-			}
-			goto longstore;
-
-        } else {
-            lua_pop(L, 1);
-            | mov w1, #i
-
-            switch (mt->type) {
-            case BOOL_TYPE:
-                | lcall extern check_uint32
-                | cmp w0, wzr
-                | cset w0, ne
-                goto intstore;
-				
-            case INT8_TYPE:
-            case INT16_TYPE: //arm64 requires callee to narrow the type
-            case INT32_TYPE:
-                
-                | lcall extern check_int32
-                
- 				goto intstore;
-
-            case INT64_TYPE:
-               
-                | lcall extern check_int64
-               
-              	goto longstore;
-				
-            case INTPTR_TYPE:
-                | lcall extern check_uintptr
-                
-                goto longstore;
-
-            case DOUBLE_TYPE:
-                | lcall extern check_double
-                store_float(Dst,&regs,0,0);
-                break;
-
-            case FLOAT_TYPE:
-                | lcall extern check_float
-                store_float(Dst,&regs,1,0);
-                break;
-			case COMPLEX_DOUBLE_TYPE:
-                | lcall extern check_complex_double
-				store_float(Dst,&regs,0,1);
-                break;
-
-            case COMPLEX_FLOAT_TYPE:
-                | lcall extern check_complex_float
-				store_float(Dst,&regs,1,1);
-                break;
-				
-			intstore:
-				store_int(Dst,&regs,1);
-                break;
-			longstore:
-				store_int(Dst,&regs,2);
-                break;
-				
-            default:
-                luaL_error(L, "NYI: call arg type");
-            }
-        }
-    }
-
-    if (ct->has_var_arg) {
-		if(regs.floats<8){
-			| add x4, sp ,#regs.floats<<3
-			| mov w3, #(8-regs.floats)
-			| mov x2, TOP
-			| mov w1, #nargs+1
-			| lcall extern unpack_varargs_float 
-		}
-		if(regs.ints<8){
-			| add x4, sp ,#0x40+(regs.ints<<3)
-			| mov w3, #(8-regs.ints)
-			| mov x2, TOP
-			| mov w1, #nargs+1
-			| lcall extern unpack_varargs_int
-		}
-		|//case when DATA is not allocated, all arg is skipped
-		| cmp TOP,#(nargs>8?nargs:8)
-		| ble >1
-		| mov x5, DATA
-		| mov w3, #(8-regs.floats)
-		| mov w3, #(8-regs.ints)
-		| mov x2, TOP
-		| mov w1, #nargs+1
-		| lcall extern unpack_varargs_stack_skip
-		| 1:
-		regs.floats=regs.ints=8;
-    }
-	
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
-				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
-	if(ret_by_addr){
-		| load64 x2, mt
-		| mov x1, #0 
-		| lcall extern push_cdata	
-		| mov x8, x0
-	}
-	
-	//pop all args in registers
-	switch(regs.ints){
-		case 8:
-		case 7:
-            | ldp x6,x7,[sp,#0x70]
-		case 6:
-		case 5:
-            | ldp x4,x5,[sp,#0x60]
-		case 4:
-		case 3:
-            | ldp x2,x3,[sp,#0x50]
-		case 2:
-		case 1:
-			| ldp x0,x1,[sp,#0x40]
-    }
-	
-	switch(regs.floats){
-		case 8:
-		case 7:
-            | ldp d6,d7,[sp,#0x30]
-		case 6:
-		case 5:
-            | ldp d4,d5,[sp,#0x20]
-		case 4:
-		case 3:
-            | ldp d2,d3,[sp,#0x10]
-		case 2:
-		case 1:
-			| ldp d0,d1,[sp]
-    }
-	if(regs.ints==8|| regs.floats==8){// fix stack case registers is full
-		| add sp,sp,#0x80
-	}
-	
-	| load64 x9,func
-    | blr x9
-
-    |.macro return
-	| mov sp, x29
-	| ldp x29, x30, [sp]
-	| ldp TOP, DATA, [sp,#0x10]
-	| ldr L_ARG, [sp,#0x20]
-	| add sp, sp, #0x30
-	| ret
-    |.endmacro
-
-    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
-        lua_getuservalue(L, -1);
-        num_upvals += 2;
-        | mov DATA, x0
-        | load64 x2, mt
-        | load32 w1, lua_upvalueindex(num_upvals)
-        | lcall extern push_cdata
-        | str DATA, [x0]
-        | mov w0, #1
-        | return
-
-    } else {
-        switch (mt->type) {
-        case INT64_TYPE:
-		#if LUA_VERSION_NUM>=503
-			 lua_pop(L, 1);
-            | mov x1, x0
-            | lcall extern lua_pushinteger
-            | mov w0, #1
-            | return
-            break;
-		#endif
-
-        case INTPTR_TYPE:
-            num_upvals++;
-            | mov DATA, x0
-            | load64 x2, mt
-            | mov w1, wzr
-            | lcall extern push_cdata
-            | str DATA, [x0]
-            | mov w0, #1
-            | return
-			break;
-        case VOID_TYPE:
-            lua_pop(L, 1);
-            | mov w0, wzr
-            | return
-            break;
-
-        case BOOL_TYPE:
-            lua_pop(L, 1);
-            | mov w1, w0
-            | lcall extern lua_pushboolean
-            | mov w0, #1
-            | return
-            break;
-
-        case INT8_TYPE:// we need to narrow the value before return
-			lua_pop(L, 1);
-            | mov w1, w0
-            if (mt->is_unsigned) {
-				| uxtb w1, w1
-                | lcall extern push_uint
-            } else {
-				| sxtb w1, w1
-                | lcall extern push_int
-            }
-            | mov w0, #1
-            | return
-			break;
-        case INT16_TYPE:// we need to narrow the value before return
-			lua_pop(L, 1);
-            | mov w1, w0
-            if (mt->is_unsigned) {
-				| uxth w1, w1
-                | lcall extern push_uint
-            } else {
-				| sxth w1, w1
-                | lcall extern push_int
-            }
-            | mov w0, #1
-            | return
-			break;
-        case INT32_TYPE:
-        case ENUM_TYPE:
-            lua_pop(L, 1);
-            | mov w1, w0
-            if (mt->is_unsigned) {
-                | lcall extern push_uint
-            } else {
-                | lcall extern push_int
-            }
-            | mov w0, #1
-            | return
-            break;
-
-        case FLOAT_TYPE:
-            lua_pop(L, 1);
-            | lcall extern push_float
-            | mov w0, #1
-            | return
-            break;
-
-        case DOUBLE_TYPE:
-            lua_pop(L, 1);
-            | lcall extern lua_pushnumber
-            | mov w0, #1
-            | return
-            break;
-		case COMPLEX_FLOAT_TYPE:
-            lua_getuservalue(L, -1);
-            num_upvals+=2;
-            | fmov w0, s0
-            | fmov w1, s1
-            | orr x0, x0, x1, lsl #32
-            | mov DATA, x0
-            | load64 x2, mt
-            | load32 w1, lua_upvalueindex(num_upvals)
-            | lcall extern push_cdata
-            | str DATA, [x0]
-            | mov w0, #1
-            | return
-            break;
-
-        case COMPLEX_DOUBLE_TYPE:
-            lua_getuservalue(L, -1);
-            num_upvals+=2;
-            | fmov TOP, d0
-            | fmov DATA, d1
-            | load64 x2, mt
-            | load32 w1, lua_upvalueindex(num_upvals)
-            | lcall extern push_cdata
-            | stp TOP,DATA, [x0]
-            | mov w0, #1
-            | return
-            break;
-		case STRUCT_TYPE:
-		case UNION_TYPE:
-			lua_getuservalue(L, -1);
-            num_upvals+=2;
-		    if(ret_by_addr){
-				if(!lua_isnil(L,-1)){
-					| load32 w1, lua_upvalueindex(num_upvals)
-					| lcall extern lua_pushvalue // lua_pushvalue(L,lua_upvalueindex(num_upvals))
-					| movn w1, #1 //-2
-					| lcall extern lua_setuservalue // lua_setuservalue(L,-2)
-				}
-				| mov w0, #1
-				| return
-			}else if(mt->is_empty){
-				| mov w0, #0
-				| return
-			}else{
-				int isfloat;
-				int hfasize=hfa_size(L,-2,mt,&isfloat);
-				if(hfasize){
-					switch(hfasize){
-						case 4:
-							| stp d2, d3, [sp, #-16]!
-							goto hfs_dual;
-						case 3:
-							| str d2, [sp, #-16]!
-						case 2:
-							hfs_dual:
-							| fmov TOP, d1
-						case 1:
-							| fmov DATA, d0
-							break;
-					}
-				}else{
-					if(mt->base_size>8){
-						| mov TOP, x1
-					}
-					| mov DATA, x0 
-					
-				} 
-				| load64 x2, mt
-				| load32 w1, lua_upvalueindex(num_upvals)
-				| lcall extern push_cdata
-				if(hfasize){
-					switch(hfasize){
-						case 4:
-							| ldp d0, d1, [sp], #16
-							if(isfloat){
-								| stp s0,s1, [x0,#8]
-							}else{
-								| stp d0,d1, [x0,#16]
-							} 
-							goto hfl_dual;
-						case 3:
-							| ldr d0, [sp], #16
-							if(isfloat){
-								| str s0, [x0,#8]
-							}else{
-								| str d0, [x0,#16]
-							}
-						case 2:
-							hfl_dual:
-							if(isfloat){
-								| fmov d0, TOP
-								| str s0, [x0,#4]
-							}else{
-								| str TOP, [x0,#8]
-							}
-						case 1:
-							if(isfloat){
-								| fmov d0, DATA
-								| str s0, [x0]
-							}else{
-								| str DATA, [x0]
-							}
-							break;
-					}
-				}else{
-					if(mt->base_size>8){
-						| str TOP, [x0, #8]
-					}
-					| str DATA, [x0]
-					
-				} 
-				| mov w0, #1
-				| return
-			}
-			break;	
-		
-        default:
-            luaL_error(L, "NYI: call return type");
-        }
-    }
-
-    assert(lua_gettop(L) == top + num_upvals);
-	{
-        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
-        /* add a callback as an upval so that the jitted code gets cleaned up when
-         * the function gets gc'd */
-        push_callback(L, f, func);
-        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
-    }
-}
-
+/* vim: ts=4 sw=4 sts=4 et tw=78
+ * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+ * Portions copyright (c) 2011 James R. McKaskill.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+|.arch arm64
+
+|.actionlist build_actionlist
+|.globalnames globnames
+|.externnames extnames
+
+#define JUMP_SIZE 16
+
+//in aarch64 the pc is indicated the current 
+#define MIN_BRANCH ((INT32_MIN) >> 6)
+#define MAX_BRANCH ((INT32_MAX) >> 6)
+//arm64 pc has no offset so comparing with next instruction is -4 
+#define BRANCH_OFF -4
+#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
+
+static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
+{
+    /* The jump code is the function pointer followed by a stub to call the
+     * function pointer. The stub exists so we can jump to functions with an
+     * offset greater than 128MB.
+     *
+     * Note we have to manually set this up since there are commands buffered
+     * in the jit state.
+     */
+	 
+	 //l: ptr
+	 *(cfunction*) code = func;
+	 // ldr x9,#-8
+	  *(uint32_t*) &code[8] = 0x58FFFFC9;
+	 //br x9
+	 *(uint32_t*) &code[12] = 0xD61F0120;
+	
+}
+
+|.define TOP, x19
+|.define DATA,x20
+|.define L_ARG,x21
+|.macro load64, reg, val
+//| ldr reg, >5
+//| b >6
+//|5:
+//|.long64 val
+//|6:
+| mov reg, #(unsigned short)(val)
+| movk reg, #(((unsigned int)(val))>>16), lsl #16
+| movk reg, #(unsigned short)((unsigned long)(val)>>32), lsl #32
+| movk reg, #(unsigned short)((unsigned long)(val)>>48), lsl #48
+|.endmacro
+
+|.macro load32, reg, val
+| mov reg, #(unsigned short)(val)
+| movk reg, #(((unsigned int)(val))>>16), lsl #16
+|.endmacro
+
+|.macro lcall, func
+| mov x0, L_ARG
+| bl func
+|.endmacro
+
+void compile_globals(struct jit* jit, lua_State* L)
+{
+    (void) jit;
+}
+typedef struct reg_info{
+	uint8_t ints;
+	uint8_t floats;
+	uint16_t ex;
+} reg_info;
+
+static ALWAYS_INLINE bool is_float_type(int t){
+    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
+}
+
+static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
+	struct ctype* mt;
+	int type,ele_count,i,ct_usr;
+	lua_getuservalue(L,idx);
+	ct_usr=lua_absindex(L,-1);
+    lua_rawgeti(L,ct_usr,1);
+    mt=(struct ctype*)lua_touserdata(L,-1);
+    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+        lua_pop(L,2);
+        return 0;
+    }
+	type=mt->type;
+    ele_count=(int)(ct->base_size/mt->base_size);
+    if(ele_count>4||ct->base_size%mt->base_size){
+        lua_pop(L,2);
+        return 0;
+    }
+	lua_pop(L,1);
+    for (i = 2;i<=4; ++i) {
+        lua_rawgeti(L,ct_usr,i);
+		if(lua_isnil(L,-1)){//case have array member;
+            lua_pop(L,1);
+            break;
+        }
+        mt=(struct ctype*)lua_touserdata(L,-1);
+        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+            lua_pop(L,2);
+            return 0;
+        }
+        lua_pop(L,1);
+    }
+	if(isfloat){
+		*isfloat=mt->type==FLOAT_TYPE;
+	}
+	lua_pop(L,1);
+    return ele_count;
+}
+
+static reg_info caculate_regs(lua_State* L,int ct_usr,int nargs){
+    int i;reg_info regs;
+    const struct ctype* mt;
+    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs&&(regs.floats<8||regs.ints<8); ++i){
+		lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (mt->pointers || mt->is_reference) {
+			if(regs.ints<8)regs.ints++;
+		}else{
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+				case COMPLEX_FLOAT_TYPE:
+					if(regs.floats<7)
+						regs.floats+=2;
+					else if(regs.floats==7)
+						regs.floats=8;
+					break;
+				case FLOAT_TYPE:
+				case DOUBLE_TYPE:
+					if(regs.floats<8) ++regs.floats;
+					break;
+				case STRUCT_TYPE:{
+                    int hfasize=hfa_size(L,-1,mt,NULL);
+                    if(hfasize>0){
+						regs.floats+=hfasize;
+						if(regs.floats>8)
+							regs.floats=8;
+						break;
+                    }
+                }
+				case UNION_TYPE:{
+					int size=mt->base_size;
+					if(size>16){//passed by address
+						if(regs.ints<8)++regs.ints;
+						break;
+					}
+					if(mt->is_empty){
+						break; //ignored empty struct
+					}
+					size=(size+7)>>3;
+					if(regs.ints+size<=8) regs.ints+=size;
+					break;
+				}
+				default:
+					if(regs.ints<8)++regs.ints;//no need to check type support here
+			}
+		}
+		lua_pop(L,1);
+	}
+	
+	return regs;
+}
+
+// arm store/load range for immediate value is only -256-255
+static ALWAYS_INLINE void load_int(struct jit* Dst,reg_info* regs){
+	if(regs->ints<8)
+		| ldr x1, [sp, #0x60+(regs->ints++<<3)] //64 bit ptr
+	else
+		| ldr x1, [DATA],  #(regs->ex++,8)
+}
+
+static void load_float(struct jit* Dst,reg_info* regs,int isfloat,int exSize){
+	if(regs->floats+exSize<8){
+		switch(exSize){
+			case 3:
+				| ldp d2,d3, [sp, #0x30+(regs->floats<<3)]
+				goto l_dual;
+			case 2:
+			    | ldr d2, [sp, #0x30+(regs->floats<<3)]
+			case 1:
+			    l_dual:
+				| ldp d0,d1, [sp, #0x20+(regs->floats<<3)]
+				break;
+			case 0:
+			    | ldr d0, [sp, #0x20+(regs->floats<<3)]
+				break;
+		}
+		regs->floats+=exSize+1;
+		
+	}else{
+		regs->floats=8;
+		regs->ex+=exSize+1;
+		switch(exSize){
+			case 3:
+				if(isfloat){
+					| ldp s0,s1, [DATA], #8
+					| ldp s2,s3, [DATA], #8
+				}else{
+					| ldp d0, d1, [DATA], #16
+					| ldp d2, d3, [DATA], #16
+				}
+			     break;
+			case 2:
+				if(isfloat){ //12 bytes rounded to 16
+					| ldp s0,s1, [DATA], #8
+					| ldr s2, [DATA], #8
+					break;
+				}else {
+					| ldp d0, d1, [DATA], #16
+					| ldr d2, [DATA], #8
+				}
+			     break;
+			case 1:
+				if(isfloat){
+					| ldp s0,s1, [DATA], #8
+				}else{
+					| ldp d0, d1, [DATA], #16
+				}
+				break;
+			case 0:
+				if(isfloat){
+					| ldr s0, [DATA], #8
+				}else {
+					| ldr d0, [DATA], #8
+				}
+				break;
+		}
+	
+	}
+}
+
+cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals, ref,ret_by_addr;
+    const struct ctype* mt;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    fidx = lua_absindex(L, fidx);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    dasm_setup(Dst, build_actionlist);
+
+    lua_newtable(L);
+    lua_pushvalue(L, -1);
+    ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    num_upvals = 0;
+
+    if (ct->has_var_arg) {
+        luaL_error(L, "can't create callbacks with varargs");
+    }
+	
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
+				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
+	if(ret_by_addr){
+		| str x8, [sp, #-16]! //preserve ret address;
+	}
+	lua_pop(L,1);	
+	reg_info regs=caculate_regs(L,ct_usr,nargs);
+	
+	if(regs.ints||regs.floats){
+		| sub sp,sp,#0xa0
+	}else{
+		| sub sp,sp,#0x20
+	}
+	//8 integer reigsters and 8 floating registers
+	switch(regs.ints){
+		case 8:
+		case 7:
+			| stp x6,x7, [sp,#0x90]
+		case 6:
+		case 5:
+			| stp x4,x5, [sp,#0x80]
+		case 4:
+		case 3:
+			| stp x2,x3, [sp,#0x70]
+		case 2:
+		case 1:
+			| stp x0,x1, [sp,#0x60]	
+	}	
+
+	switch(regs.floats){
+		case 8:
+		case 7:
+			| stp d6,d7, [sp,#0x50]
+		case 6:
+		case 5:
+			| stp d4,d5, [sp,#0x40]
+		case 4:
+		case 3:
+			| stp d2,d3, [sp,#0x30]
+		case 2:
+		case 1:
+			| stp d0,d1, [sp,#0x20]
+	} 
+	| stp DATA, L_ARG,[sp,#0x10]
+	| stp x29, x30,[sp]
+	
+	if(regs.ints==8||regs.floats==8){ // may be overflowed if it's full
+		| add DATA, sp, #0xa0+ret_by_addr*0x10
+	}
+	
+    /* get the lua function */
+    lua_pushvalue(L, fidx);
+    lua_rawseti(L, -2, ++num_upvals);
+	
+	| load64 L_ARG, L
+	| load32 w2, ref
+	| load32 w1, LUA_REGISTRYINDEX
+	| lcall extern rawgeti //get the table
+	
+	| mov w2, #num_upvals
+    | movn x1, #0 // -1
+    | lcall extern rawgeti //get the function
+	
+
+    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; ++i) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+
+        if (mt->pointers || mt->is_reference) {
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+			
+            | mov w2, #num_upvals-1 // usr value
+            | movn x1, #i // -i-1, stack is upval table, func, i-1 args
+            | lcall extern rawgeti
+            | load64 x2, mt
+            | movn w1, #0 // -1
+            | lcall extern push_cdata
+			load_int(Dst,&regs);
+            | str x1, [x0]
+            | movn w1, #1 //-2
+            | lcall extern lua_remove // remove the usr value
+
+        } else {
+            switch (mt->type) {
+			case STRUCT_TYPE:
+			case UNION_TYPE:{
+				int isfloat,hfasize=0;
+				if(mt->type!=UNION_TYPE){
+					hfasize=hfa_size(L,-1,mt,&isfloat);
+				}
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+				| mov w2, #num_upvals-1 // usr value
+				| movn x1, #i // -i-1, stack is upval table, func, i-1 args
+				| lcall extern rawgeti
+				| load64 x2, mt
+				| movn w1, #0 // -1
+                | lcall extern push_cdata
+				
+				if(hfasize){
+					load_float(Dst,&regs,isfloat,hfasize-1);
+					switch(hfasize){
+						case 4:
+							if(isfloat){
+								| stp s2, s3, [x0,#8]
+							}else{
+								| stp d2, d3, [x0,#16]
+							}
+							goto hfa2;
+						case 3:
+							if(isfloat){
+								| str s2, [x0,#8]
+							}else{
+								| str d2, [x0,#16]
+							}
+						case 2:
+            			hfa2:
+							if(isfloat){
+								| stp s0, s1, [x0]
+							}else{
+								| stp d0, d1, [x0]
+							}
+							break;
+						case 1:
+							if(isfloat){
+								| str s0, [x0]
+							}else{
+								| str d0, [x0]
+							}
+							break;
+         							
+					}
+				}else if(!mt->is_empty){
+					size_t size=mt->base_size;
+					if(size>16){
+						load_int(Dst,&regs);
+						| load64 x2, mt->base_size
+						| load64 x9, memcpy
+						| blr x9
+					}else{
+						size=(size+7)>>3;
+						if(mt->align_mask>8){
+							if(regs.ints&1) regs.ints++;
+							else if(regs.ex&1) regs.ex++;
+						}
+						if(regs.ints+size<=8){
+							if(size>1){
+								| ldp x1,x2, [sp,#0x60+(regs.ints<<3)]
+								| stp x1, x2, [x0]
+							}else{
+								| ldr x1, [sp,#0x60+(regs.ints<<3)]
+								| str x1, [x0]
+							}
+							regs.ints+=size;
+						}else{
+							regs.ints=8;
+							if(size>1){
+								| ldp x1,x2, [DATA], #16
+								| stp x1, x2, [x0]
+							}else{
+								| ldr x1, [DATA], #8
+								| str x1, [x0]
+							}
+							
+						} 
+					}
+					
+					
+				}
+				
+                | movn w1, #1 // -2
+                | lcall extern lua_remove // remove the nil usr
+			    break;
+			}
+			case COMPLEX_DOUBLE_TYPE:
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+				| mov w2, #num_upvals-1 // usr value
+				| movn x1, #i // -i-1, stack is upval table, func, i-1 args
+				| lcall extern rawgeti
+				| load64 x2, mt
+				| movn w1, #0 // -1
+                | lcall extern push_cdata
+				load_float(Dst,&regs,0,1);
+				|stp d0,d1,[x0]
+                | movn w1, #1 // -2
+                | lcall extern lua_remove // remove the nil usr
+				
+				break;
+			case COMPLEX_FLOAT_TYPE:
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                | mov w2, #num_upvals-1 // usr value
+                | movn x1, #i // -i-1, stack is upval table, func, i-1 args
+                | lcall extern rawgeti
+                | load64 x2, mt
+                | movn w1, #0 // -1
+                | lcall extern push_cdata
+				load_float(Dst,&regs,1,1);
+                | stp s0,s1, [x0]
+                | movn w1, #1 // -2
+                | lcall extern lua_remove // remove the nil usr
+				
+				break;
+            case INT64_TYPE:
+			    #if LUA_VERSION_NUM>=503
+                lua_pop(L, 1);
+				load_int(Dst,&regs);
+                | lcall extern lua_pushinteger
+				
+				#else
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                | load64 x2, mt
+                | mov w1, wzr
+                | lcall extern push_cdata
+                load_int(Dst,&regs);
+                | str x1, [x0]
+                | movn w1, #1 // -2
+                | lcall extern lua_remove // remove the nil usr
+				
+				#endif
+                break;
+
+            case INTPTR_TYPE:
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                | load64 x2, mt
+                | mov w1, wzr
+                | lcall extern push_cdata
+                load_int(Dst,&regs);
+                | str x1, [x0]
+                | movn w1, #1 // -2
+                | lcall extern lua_remove // remove the nil usr
+				
+                break;
+
+            case BOOL_TYPE:
+                lua_pop(L, 1);
+				
+				load_int(Dst,&regs);
+				| lcall extern lua_pushboolean
+				
+                break;
+
+            case INT8_TYPE:// need to narrow for caller doesn't do it
+				lua_pop(L, 1);
+				if(regs.ints<8){
+					if (mt->is_unsigned) {
+						| ldrb w1, [sp,#0x60+(regs.ints++<<3)]
+					} else {
+						| ldrsb w1, [sp,#0x60+(regs.ints++<<3)]
+					}
+				}else {
+					if (mt->is_unsigned) {
+						| ldrb w1, [DATA], #8
+					} else {
+						| ldrsb w1, [DATA], #8
+					}
+				}
+				| lcall extern push_int
+				break;
+			
+            case INT16_TYPE:// need to narrow for caller doesn't do it
+				lua_pop(L, 1);
+				if(regs.ints<8){
+					if (mt->is_unsigned) {
+						| ldrh w1, [sp,#0x60+(regs.ints++<<3)]
+					} else {
+						| ldrsh w1, [sp,#0x60+(regs.ints++<<3)]
+					}
+				}else {
+					if (mt->is_unsigned) {
+						| ldrh w1, [DATA], #8
+					} else {
+						| ldrsh w1, [DATA], #8
+					}
+				}
+				| lcall extern push_int
+				break;
+				
+            case ENUM_TYPE:
+            case INT32_TYPE:
+                lua_pop(L, 1);
+				load_int(Dst,&regs);
+				
+                | lcall extern push_int
+                break;
+
+            case FLOAT_TYPE:
+                lua_pop(L, 1);
+				load_float(Dst,&regs,1,0);
+                | lcall extern push_float
+                break;
+
+            case DOUBLE_TYPE:
+                lua_pop(L, 1);
+				load_float(Dst,&regs,0,0);
+                | lcall extern lua_pushnumber
+                break;
+            default:
+                luaL_error(L, "NYI: callback arg type");
+            }
+        }
+    }
+
+    lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+
+    | mov w2, #((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0)
+    | mov w1, #nargs
+    | lcall extern lua_call
+    
+	|.macro retcdata, func
+	| mov w2, #num_upvals-1 // usr value
+	| movn x1, #1 // -2 stack is (upval table, ret val)
+	| lcall extern rawgeti
+	| load64 x3, mt
+	| movn x2, #0 // -1 - ct_usr
+	| movn x1, #1 // -2 - val
+	| lcall extern func
+	|.endmacro
+
+	
+    if (mt->pointers || mt->is_reference) {
+        lua_getuservalue(L, -1);
+        lua_rawseti(L, -3, ++num_upvals); /* usr value */
+        lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+        | retcdata check_typed_pointer
+        goto single_no_pop;
+    } else {
+        switch (mt->type) {
+		case STRUCT_TYPE:
+		case UNION_TYPE:{
+			int hfasize=0,isfloat;
+			if(mt->type!=UNION_TYPE){
+				hfasize=hfa_size(L,-1,mt,&isfloat);
+			}
+			lua_getuservalue(L, -1);
+			lua_rawseti(L, -3, ++num_upvals); /* usr value */
+			lua_rawseti(L, -2, ++num_upvals); /* mt */
+			| retcdata check_struct
+			| mov DATA ,x0
+			| movn w1, #2 // -3
+            | lcall extern lua_settop
+			if(hfasize){
+				switch(hfasize){
+					case 4:
+					    if(isfloat){
+							| ldp s2,s3, [DATA,#8]
+						}else{
+							| ldp d2,d3, [DATA,#16]
+						}
+						goto ld_hfa;
+					case 3:
+						if(isfloat){
+							| ldr s2, [DATA,#8]
+						}else{
+							| ldr d2, [DATA,#16]
+						}
+					case 2:
+						ld_hfa:
+					    if(isfloat){
+							| ldp s0,s1, [DATA]
+						}else{
+							| ldp d0,d1, [DATA]
+						}
+						break;
+					case 1:
+						if(isfloat){
+							| ldr s0, [DATA]
+						}else{
+							| ldr d0, [DATA]
+						}
+					    break;
+				}
+			}else{
+				if(mt->base_size>16){
+					| ldr x0, [sp, #0x20+((regs.ints||regs.floats)?0x80:0)]
+					| mov x1, DATA
+					| load64 x2, mt->base_size
+					| load64 x9, memcpy
+					| blr x9
+				}else{
+					if(mt->base_size>8){
+						| ldp x0, x1, [DATA]
+					}else{
+						| ldr x0, [DATA]
+					}
+				}
+			}
+			break;
+		}
+        case ENUM_TYPE:
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+            | retcdata check_enum
+
+            goto single_no_pop;
+
+        case VOID_TYPE:
+		    | movn w1,#1 //-2
+            | lcall extern lua_settop
+            lua_pop(L, 1);
+            break;
+
+        case BOOL_TYPE:
+        case INT8_TYPE:
+        case INT16_TYPE:
+        case INT32_TYPE: //caller's responsiblity to narrow 
+		    | movn w1,#0
+            if (mt->is_unsigned) {
+                | lcall extern check_uint32
+            } else {
+                | lcall extern check_int32
+            }
+			
+            goto single;
+
+        case INT64_TYPE:
+            | movn w1,#0 //-1
+            if (mt->is_unsigned) {
+                | lcall extern check_uint64
+            } else {
+                | lcall extern check_int64
+            }
+			
+			goto single;
+
+        case INTPTR_TYPE:
+            | movn w1,#0 //-1
+            | lcall extern check_uintptr
+            goto single;
+
+        case FLOAT_TYPE:
+            | movn w1,#0 //-1
+            | lcall extern check_float
+			
+            | fmov DATA,d0
+            | movn w1, #2 // -3
+            | lcall extern lua_settop
+            | fmov d0,DATA
+            lua_pop(L, 1);
+			break;
+        case DOUBLE_TYPE:
+            | movn w1,#0 //-1
+            | lcall extern check_double
+			
+			| fmov DATA,d0
+            | movn w1, #2 // -3
+            | lcall extern lua_settop
+            | fmov d0,DATA
+			
+            lua_pop(L, 1);
+			break;
+			
+		case COMPLEX_DOUBLE_TYPE:
+
+			| movn w1, #0 // -1
+			| lcall extern check_complex_double
+		    
+			goto complex_ret;
+		case COMPLEX_FLOAT_TYPE:
+			| movn w1, #0 // -1
+			| lcall extern check_complex_float
+			
+		complex_ret:	
+			| mov x0,L_ARG
+            | movn w1, #2 // -3
+		    | fmov DATA,d0
+			| fmov L_ARG,d1
+            | bl extern lua_settop
+            | fmov d0,DATA
+			| fmov d1,L_ARG
+
+            lua_pop(L, 1);			
+			break;
+        single:
+            lua_pop(L, 1);
+		single_no_pop:	
+            | mov DATA, x0
+            | movn w1, #2 // -3
+            | lcall extern lua_settop
+            | mov x0, DATA
+            break;
+
+        
+        default:
+            luaL_error(L, "NYI: callback return type");
+        }
+    }
+	
+	| ldp x29,x30,[sp] 
+	| ldp DATA, L_ARG,[sp,#0x10]
+	| add sp,sp, # (0x20 +ret_by_addr*0x10+ ((regs.floats!=0)||(regs.ints!=0)) * 0x80)
+	| ret
+	
+    lua_pop(L, 1); /* upval table - already in registry */
+    assert(lua_gettop(L) == top);
+
+    {
+        void* p;
+        struct ctype ft;
+        cfunction func;
+
+        func = compile(Dst, L, NULL, ref);
+
+        ft = *ct;
+        ft.is_jitted = 1;
+        p = push_cdata(L, ct_usr, &ft);
+        *(cfunction*) p = func;
+
+        assert(lua_gettop(L) == top + 1);
+
+        return func;
+    }
+}
+
+//arm64 argument can only be in stack or registers. An argument can't be splited between stack and register.
+static  void store_float(struct jit* Dst,reg_info* regs,int isfloat,int ex){
+	if(regs->floats+ex<8){
+		
+		switch(ex){
+			case 3:
+				| stp d2,d3, [sp, #0x10+(regs->floats<<3)] 
+			     goto sd_dual;
+			case 2:
+			    | str d2, [sp, #0x10+(regs->floats<<3)]
+			case 1:
+			    sd_dual:
+				| stp d0,d1, [sp, #(regs->floats<<3)] 
+				break;
+			case 0:
+				| str d0, [sp, #(regs->floats<<3)]
+				break;
+		}
+		regs->floats+=1+ex;
+	}else {
+		regs->floats=8;
+		switch(ex){
+			case 3:
+			    if(isfloat){
+					| stp s0,s1, [DATA], #8
+					| stp s2,s3, [DATA], #8
+				}else{
+					| stp d0, d1, [DATA], #16
+					| stp d2, d3, [DATA], #16
+				}				
+			    break;
+			case 2:
+			    if(isfloat){
+					| stp s0,s1, [DATA], #8
+					| str s2, [DATA], #8
+				}else{
+					| stp d0, d1,[DATA], #16
+					| str d2, [DATA], #8
+				}
+				break;
+			case 1:
+			    if(isfloat){
+					| stp s0,s1, [DATA], #8
+				}else{
+					| stp d0, d1,[DATA], #16
+				}
+				break;
+			case 0:
+				if(isfloat){
+					| str s0, [DATA], #8
+				}else {
+					| str d0, [DATA], #8
+				}
+				break;
+		}
+		//complex float is packed as one double on stack
+		regs->ex+=ex+1;
+	} 
+}
+
+static void store_int(struct jit* Dst,reg_info* regs,int intSize){
+	switch(intSize){
+		case 1:
+			if(regs->ints<8)
+				| str w0, [sp,#0x40+(regs->ints++<<3)]
+			else
+				| str w0, [DATA], #(regs->ex++,8)
+            break;
+		case 2:
+			if(regs->ints<8)
+				| str x0, [sp,#0x40+(regs->ints++<<3)]
+			else
+				| str x0, [DATA], #(regs->ex++,8)
+			break;
+		case 3:
+		case 4:
+			if(regs->ints<7){
+				| stp x0,x1, [sp,#0x40+(regs->ints<<3)]
+				regs->ints+=2;
+			}
+			else{
+				if(regs->ints==7)
+					regs->ints=8;
+				| stp x0,x1, [DATA], #16
+				regs->ex+=2;
+			}
+				
+			break;
+	}
+}
+
+static int caculate_stack(lua_State* L,int ct_usr,int nargs){
+    int i;reg_info regs={0,0,0};
+    const struct ctype* mt;int stack=0,extra=0;
+    for (i = 1; i <= nargs; ++i){
+		lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (mt->pointers || mt->is_reference) {
+			if(regs.ints<8)regs.ints++;
+			else stack++;
+		}else{
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+				case COMPLEX_FLOAT_TYPE:
+					if(regs.floats<7)
+						regs.floats+=2;
+					else if(regs.floats==7)
+						regs.floats=8;
+					else stack+=mt->base_size>>3;
+					break;
+				case FLOAT_TYPE:
+				case DOUBLE_TYPE:
+					if(regs.floats<8) ++regs.floats;
+					else stack++;
+					break;
+				case STRUCT_TYPE:{
+					int isfloat;
+                    int hfasize=hfa_size(L,-1,mt,&isfloat);
+                    if(hfasize>0){
+						if(regs.floats+hfasize<=8)
+							regs.floats +=hfasize;
+						else {
+						    regs.floats=8;
+							stack+=(hfasize*(2-isfloat)+1)>>1;	
+						}
+						break;
+                    }
+                }
+				case UNION_TYPE:{
+					int size=mt->base_size;
+					size=(size+7)>>3;
+					if(size>2){//passed by address
+						if(regs.ints<8)++regs.ints;
+						else stack++;
+					    extra+=size;//extra copy stack;
+						break;
+					}
+					if(mt->is_empty){
+						break; //ignored empty struct
+					}
+					if(mt->align_mask>8){
+						if(regs.ints&1) regs.ints++;
+						else if(stack&1) stack++;
+					}
+					if(regs.ints+size<=8) regs.ints+=size;
+					else{
+						regs.ints=8;
+						stack+=size;
+					} 
+					
+					break;
+				}
+				default:
+					if(regs.ints<8)++regs.ints;//no need to check type support here
+					else stack++;
+			}
+		}
+		lua_pop(L,1);
+	}
+	
+	return (regs.ints||regs.floats)?((stack+extra+17/*16 for regs, 1 for align*/)>>1)<<4:0;//2 eightbytes align
+}
+
+
+void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals,ret_by_addr;
+    const struct ctype* mt;
+	int stack_size,struct_offset;
+    void* p;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    p = push_cdata(L, ct_usr, ct);
+    *(cfunction*) p = func;
+    num_upvals = 1;
+
+    dasm_setup(Dst, build_actionlist);
+
+    reg_info regs={0,0};
+	
+	| sub sp,sp,#0x30
+	| str L_ARG, [sp,#20]
+	| stp TOP,DATA,[sp,#0x10]
+	| stp x29,x30,[sp]
+	| mov x29,sp
+	| mov L_ARG,x0
+	
+    /* reserve enough stack space for all of the arguments. */
+	stack_size=caculate_stack(L,ct_usr,nargs);
+	struct_offset=0;
+	if(stack_size>0){
+		if(stack_size>=1<<12){
+			| load32 x9, stack_size //trick x9
+			| sub sp, sp, x9
+		}
+		else{
+			| sub sp, sp, #stack_size
+		}
+		 if (ct->has_var_arg) {
+			| bl extern lua_gettop
+			| cmp w0, #nargs
+			| bge >1
+			| load64 x1, "too few arguments"
+			| lcall extern luaL_error
+			|1:
+			| mov TOP, x0
+			| add x0, x0, #1
+			| bfm x0,xzr, #0, #0 //round up 2 for stack alignment.
+			| sub sp, sp, x0, lsl #3
+		}
+		| add DATA,sp,#0x80
+    }
+	
+    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; i++) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		
+        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE||mt->type==STRUCT_TYPE||mt->type==UNION_TYPE) {
+            lua_getuservalue(L, -1);
+            num_upvals += 2;
+
+			
+			| load64 x3,mt
+			| load32 w2,lua_upvalueindex(num_upvals)
+			| mov x1,#i
+			
+            if (mt->pointers || mt->is_reference) {
+                | lcall extern check_typed_pointer
+            } else{
+				switch (mt->type) {
+					case FUNCTION_PTR_TYPE: {
+						| lcall extern check_typed_cfunction
+						break;
+					}
+					case ENUM_TYPE:{
+						| lcall extern check_enum
+						break;
+					} 
+					case STRUCT_TYPE:
+					case UNION_TYPE:{
+						if(mt->is_empty) continue;
+		
+						int isfloat;
+						int hfasize=hfa_size(L,-2,mt,&isfloat);
+						| lcall extern check_struct
+                        if(hfasize>0){
+							switch(hfasize){
+								case 4:
+									if(isfloat){
+										| ldp s2,s3, [x0,#8]
+									}else{
+										| ldp d2,d3, [x0,#16]
+									}
+									goto ld_hfa;
+								case 3:
+									if(isfloat){
+										| ldr s2, [x0,#8]
+									}else{
+										| ldr d2, [x0,#16]
+									}
+								case 2:
+									ld_hfa:
+									if(isfloat){
+										| ldp s0,s1, [x0]
+									}else{
+										| ldp d0,d1, [x0]
+									}
+									break;
+								case 1:
+									if(isfloat){
+										| ldr s0, [x0]
+									}else{
+										| ldr d0, [x0]
+									}
+									break;
+									
+							}
+							store_float(Dst,&regs,isfloat,hfasize-1);
+							continue;
+						}
+						if(mt->base_size>16){
+							| mov x1 ,x0
+							struct_offset+=(mt->base_size+7)&(~7);
+							if(struct_offset>=1<<12){
+								| load32 x0, struct_offset //trick x0
+								| sub x0, x29, x0
+							}
+							else{
+								| sub x0, x29, #struct_offset
+							}
+							store_int(Dst,&regs,2);
+							| mov x2, #mt->base_size
+							| load64 x9, memcpy
+							| blr x9
+						}else{
+							if(mt->align_mask>8){//==15
+								if(regs.ints&1) regs.ints++;
+								else if(regs.ex&1) regs.ex++;
+							}
+							int intSize=(mt->base_size+3)>>2;
+							switch(intSize){
+								case 1:
+									| ldr w0, [x0]
+									break;
+								case 2:
+									| ldr x0, [x0]
+									break;
+								case 3:
+								case 4:
+								    | ldp x0, x1, [x0]
+									break;
+							}
+							store_int(Dst,&regs,intSize);
+						}
+						continue;
+					}	
+				}
+			}
+			goto longstore;
+
+        } else {
+            lua_pop(L, 1);
+            | mov w1, #i
+
+            switch (mt->type) {
+            case BOOL_TYPE:
+                | lcall extern check_uint32
+                | cmp w0, wzr
+                | cset w0, ne
+                goto intstore;
+				
+            case INT8_TYPE:
+            case INT16_TYPE: //arm64 requires callee to narrow the type
+            case INT32_TYPE:
+                
+                | lcall extern check_int32
+                
+ 				goto intstore;
+
+            case INT64_TYPE:
+               
+                | lcall extern check_int64
+               
+              	goto longstore;
+				
+            case INTPTR_TYPE:
+                | lcall extern check_uintptr
+                
+                goto longstore;
+
+            case DOUBLE_TYPE:
+                | lcall extern check_double
+                store_float(Dst,&regs,0,0);
+                break;
+
+            case FLOAT_TYPE:
+                | lcall extern check_float
+                store_float(Dst,&regs,1,0);
+                break;
+			case COMPLEX_DOUBLE_TYPE:
+                | lcall extern check_complex_double
+				store_float(Dst,&regs,0,1);
+                break;
+
+            case COMPLEX_FLOAT_TYPE:
+                | lcall extern check_complex_float
+				store_float(Dst,&regs,1,1);
+                break;
+				
+			intstore:
+				store_int(Dst,&regs,1);
+                break;
+			longstore:
+				store_int(Dst,&regs,2);
+                break;
+				
+            default:
+                luaL_error(L, "NYI: call arg type");
+            }
+        }
+    }
+
+    if (ct->has_var_arg) {
+		if(regs.floats<8){
+			| add x4, sp ,#regs.floats<<3
+			| mov w3, #(8-regs.floats)
+			| mov x2, TOP
+			| mov w1, #nargs+1
+			| lcall extern unpack_varargs_float 
+		}
+		if(regs.ints<8){
+			| add x4, sp ,#0x40+(regs.ints<<3)
+			| mov w3, #(8-regs.ints)
+			| mov x2, TOP
+			| mov w1, #nargs+1
+			| lcall extern unpack_varargs_int
+		}
+		|//case when DATA is not allocated, all arg is skipped
+		| cmp TOP,#(nargs>8?nargs:8)
+		| ble >1
+		| mov x5, DATA
+		| mov w3, #(8-regs.floats)
+		| mov w3, #(8-regs.ints)
+		| mov x2, TOP
+		| mov w1, #nargs+1
+		| lcall extern unpack_varargs_stack_skip
+		| 1:
+		regs.floats=regs.ints=8;
+    }
+	
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
+				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
+	if(ret_by_addr){
+		| load64 x2, mt
+		| mov x1, #0 
+		| lcall extern push_cdata	
+		| mov x8, x0
+	}
+	
+	//pop all args in registers
+	switch(regs.ints){
+		case 8:
+		case 7:
+            | ldp x6,x7,[sp,#0x70]
+		case 6:
+		case 5:
+            | ldp x4,x5,[sp,#0x60]
+		case 4:
+		case 3:
+            | ldp x2,x3,[sp,#0x50]
+		case 2:
+		case 1:
+			| ldp x0,x1,[sp,#0x40]
+    }
+	
+	switch(regs.floats){
+		case 8:
+		case 7:
+            | ldp d6,d7,[sp,#0x30]
+		case 6:
+		case 5:
+            | ldp d4,d5,[sp,#0x20]
+		case 4:
+		case 3:
+            | ldp d2,d3,[sp,#0x10]
+		case 2:
+		case 1:
+			| ldp d0,d1,[sp]
+    }
+	if(regs.ints==8|| regs.floats==8){// fix stack case registers is full
+		| add sp,sp,#0x80
+	}
+	
+	| load64 x9,func
+    | blr x9
+
+    |.macro return
+	| mov sp, x29
+	| ldp x29, x30, [sp]
+	| ldp TOP, DATA, [sp,#0x10]
+	| ldr L_ARG, [sp,#0x20]
+	| add sp, sp, #0x30
+	| ret
+    |.endmacro
+
+    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
+        lua_getuservalue(L, -1);
+        num_upvals += 2;
+        | mov DATA, x0
+        | load64 x2, mt
+        | load32 w1, lua_upvalueindex(num_upvals)
+        | lcall extern push_cdata
+        | str DATA, [x0]
+        | mov w0, #1
+        | return
+
+    } else {
+        switch (mt->type) {
+        case INT64_TYPE:
+		#if LUA_VERSION_NUM>=503
+			 lua_pop(L, 1);
+            | mov x1, x0
+            | lcall extern lua_pushinteger
+            | mov w0, #1
+            | return
+            break;
+		#endif
+
+        case INTPTR_TYPE:
+            num_upvals++;
+            | mov DATA, x0
+            | load64 x2, mt
+            | mov w1, wzr
+            | lcall extern push_cdata
+            | str DATA, [x0]
+            | mov w0, #1
+            | return
+			break;
+        case VOID_TYPE:
+            lua_pop(L, 1);
+            | mov w0, wzr
+            | return
+            break;
+
+        case BOOL_TYPE:
+            lua_pop(L, 1);
+            | mov w1, w0
+            | lcall extern lua_pushboolean
+            | mov w0, #1
+            | return
+            break;
+
+        case INT8_TYPE:// we need to narrow the value before return
+			lua_pop(L, 1);
+            | mov w1, w0
+            if (mt->is_unsigned) {
+				| uxtb w1, w1
+                | lcall extern push_uint
+            } else {
+				| sxtb w1, w1
+                | lcall extern push_int
+            }
+            | mov w0, #1
+            | return
+			break;
+        case INT16_TYPE:// we need to narrow the value before return
+			lua_pop(L, 1);
+            | mov w1, w0
+            if (mt->is_unsigned) {
+				| uxth w1, w1
+                | lcall extern push_uint
+            } else {
+				| sxth w1, w1
+                | lcall extern push_int
+            }
+            | mov w0, #1
+            | return
+			break;
+        case INT32_TYPE:
+        case ENUM_TYPE:
+            lua_pop(L, 1);
+            | mov w1, w0
+            if (mt->is_unsigned) {
+                | lcall extern push_uint
+            } else {
+                | lcall extern push_int
+            }
+            | mov w0, #1
+            | return
+            break;
+
+        case FLOAT_TYPE:
+            lua_pop(L, 1);
+            | lcall extern push_float
+            | mov w0, #1
+            | return
+            break;
+
+        case DOUBLE_TYPE:
+            lua_pop(L, 1);
+            | lcall extern lua_pushnumber
+            | mov w0, #1
+            | return
+            break;
+		case COMPLEX_FLOAT_TYPE:
+            lua_getuservalue(L, -1);
+            num_upvals+=2;
+            | fmov w0, s0
+            | fmov w1, s1
+            | orr x0, x0, x1, lsl #32
+            | mov DATA, x0
+            | load64 x2, mt
+            | load32 w1, lua_upvalueindex(num_upvals)
+            | lcall extern push_cdata
+            | str DATA, [x0]
+            | mov w0, #1
+            | return
+            break;
+
+        case COMPLEX_DOUBLE_TYPE:
+            lua_getuservalue(L, -1);
+            num_upvals+=2;
+            | fmov TOP, d0
+            | fmov DATA, d1
+            | load64 x2, mt
+            | load32 w1, lua_upvalueindex(num_upvals)
+            | lcall extern push_cdata
+            | stp TOP,DATA, [x0]
+            | mov w0, #1
+            | return
+            break;
+		case STRUCT_TYPE:
+		case UNION_TYPE:
+			lua_getuservalue(L, -1);
+            num_upvals+=2;
+		    if(ret_by_addr){
+				if(!lua_isnil(L,-1)){
+					| load32 w1, lua_upvalueindex(num_upvals)
+					| lcall extern lua_pushvalue // lua_pushvalue(L,lua_upvalueindex(num_upvals))
+					| movn w1, #1 //-2
+					| lcall extern lua_setuservalue // lua_setuservalue(L,-2)
+				}
+				| mov w0, #1
+				| return
+			}else if(mt->is_empty){
+				| mov w0, #0
+				| return
+			}else{
+				int isfloat;
+				int hfasize=hfa_size(L,-2,mt,&isfloat);
+				if(hfasize){
+					switch(hfasize){
+						case 4:
+							| stp d2, d3, [sp, #-16]!
+							goto hfs_dual;
+						case 3:
+							| str d2, [sp, #-16]!
+						case 2:
+							hfs_dual:
+							| fmov TOP, d1
+						case 1:
+							| fmov DATA, d0
+							break;
+					}
+				}else{
+					if(mt->base_size>8){
+						| mov TOP, x1
+					}
+					| mov DATA, x0 
+					
+				} 
+				| load64 x2, mt
+				| load32 w1, lua_upvalueindex(num_upvals)
+				| lcall extern push_cdata
+				if(hfasize){
+					switch(hfasize){
+						case 4:
+							| ldp d0, d1, [sp], #16
+							if(isfloat){
+								| stp s0,s1, [x0,#8]
+							}else{
+								| stp d0,d1, [x0,#16]
+							} 
+							goto hfl_dual;
+						case 3:
+							| ldr d0, [sp], #16
+							if(isfloat){
+								| str s0, [x0,#8]
+							}else{
+								| str d0, [x0,#16]
+							}
+						case 2:
+							hfl_dual:
+							if(isfloat){
+								| fmov d0, TOP
+								| str s0, [x0,#4]
+							}else{
+								| str TOP, [x0,#8]
+							}
+						case 1:
+							if(isfloat){
+								| fmov d0, DATA
+								| str s0, [x0]
+							}else{
+								| str DATA, [x0]
+							}
+							break;
+					}
+				}else{
+					if(mt->base_size>8){
+						| str TOP, [x0, #8]
+					}
+					| str DATA, [x0]
+					
+				} 
+				| mov w0, #1
+				| return
+			}
+			break;	
+		
+        default:
+            luaL_error(L, "NYI: call return type");
+        }
+    }
+
+    assert(lua_gettop(L) == top + num_upvals);
+	{
+        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
+        /* add a callback as an upval so that the jitted code gets cleaned up when
+         * the function gets gc'd */
+        push_callback(L, f, func);
+        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
+    }
+}
+
diff --git a/source/texk/web2c/luatexdir/luaffi/call_arm64.h b/source/texk/web2c/luatexdir/luaffi/call_arm64.h
index 748ca6dd3..aee72759e 100644
--- a/source/texk/web2c/luatexdir/luaffi/call_arm64.h
+++ b/source/texk/web2c/luatexdir/luaffi/call_arm64.h
@@ -1,2438 +1,2438 @@
-/*
-** This file has been pre-processed with DynASM.
-** http://luajit.org/dynasm.html
-** DynASM version 1.4.0, DynASM arm version 1.4.0
-** DO NOT EDIT! The original file is in "call_arm64.dasc".
-*/
-
-/* vim: ts=4 sw=4 sts=4 et tw=78
- * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
- * Portions copyright (c) 2011 James R. McKaskill.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-#if DASM_VERSION != 10400
-#error "Version mismatch between DynASM and included encoding engine"
-#endif
-
-static const unsigned int build_actionlist[1117] = {
-0xf84003e1,
-0x000f0000,
-0x00000000,
-0xf8400681,
-0x000a812c,
-0x00000000,
-0x6d400fe2,
-0x000a8cef,
-0x00000000,
-0xfc4003e2,
-0x000f0000,
-0x00000000,
-0x6d4007e0,
-0x000a8cef,
-0x00000000,
-0xfc4003e0,
-0x000f0000,
-0x00000000,
-0x2cc10680,
-0x2cc10e82,
-0x00000000,
-0x6cc10680,
-0x6cc10e82,
-0x00000000,
-0x2cc10680,
-0xbc408682,
-0x00000000,
-0x6cc10680,
-0xfc408682,
-0x00000000,
-0x2cc10680,
-0x00000000,
-0x6cc10680,
-0x00000000,
-0xbc408680,
-0x00000000,
-0xfc408680,
-0x00000000,
-0xf81f0fe8,
-0x00000000,
-0xd10283ff,
-0x00000000,
-0xd10083ff,
-0x00000000,
-0xa9091fe6,
-0x00000000,
-0xa90817e4,
-0x00000000,
-0xa9070fe2,
-0x00000000,
-0xa90607e0,
-0x00000000,
-0x6d051fe6,
-0x00000000,
-0x6d0417e4,
-0x00000000,
-0x6d030fe2,
-0x00000000,
-0x6d0207e0,
-0x00000000,
-0xa90157f4,
-0xa9007bfd,
-0x00000000,
-0x910003f4,
-0x000c0000,
-0x00000000,
-0x52800015,
-0x000a0205,
-0xf2a00015,
-0x000a0205,
-0xf2c00015,
-0x000a0205,
-0xf2e00015,
-0x000a0205,
-0x52800002,
-0x000a0205,
-0x72a00002,
-0x000a0205,
-0x52800001,
-0x000a0205,
-0x72a00001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800001,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0x00000000,
-0xf9000001,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x00030002,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0x00000000,
-0x2d010c02,
-0x00000000,
-0x6d010c02,
-0x00000000,
-0xbd000802,
-0x00000000,
-0xfd000802,
-0x00000000,
-0x2d000400,
-0x00000000,
-0x6d000400,
-0x00000000,
-0xbd000000,
-0x00000000,
-0xfd000000,
-0x00000000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x52800009,
-0x000a0205,
-0xf2a00009,
-0x000a0205,
-0xf2c00009,
-0x000a0205,
-0xf2e00009,
-0x000a0205,
-0xd63f0120,
-0x00000000,
-0xa9400be1,
-0x000a8cef,
-0xa9000801,
-0x00000000,
-0xf84003e1,
-0x000f0000,
-0xf9000001,
-0x00000000,
-0xa8c10a81,
-0xa9000801,
-0x00000000,
-0xf8408681,
-0xf9000001,
-0x00000000,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x00030002,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0x00000000,
-0x6d000400,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x00030002,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0x00000000,
-0x2d000400,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x00030002,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030003,
-0x00000000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x2a1f03e1,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0x00000000,
-0xf9000001,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x00030002,
-0x00000000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x2a1f03e1,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0x00000000,
-0xf9000001,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x00030002,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030004,
-0x00000000,
-0x384003e1,
-0x000f0000,
-0x00000000,
-0x38c003e1,
-0x000f0000,
-0x00000000,
-0x38408681,
-0x00000000,
-0x38c08681,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030005,
-0x00000000,
-0x784003e1,
-0x000f0000,
-0x00000000,
-0x78c003e1,
-0x000f0000,
-0x00000000,
-0x78408681,
-0x00000000,
-0x78c08681,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030005,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030005,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030006,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030007,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x52800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030008,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800021,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x52800003,
-0x000a0205,
-0xf2a00003,
-0x000a0205,
-0xf2c00003,
-0x000a0205,
-0xf2e00003,
-0x000a0205,
-0x92800002,
-0x92800021,
-0xaa1503e0,
-0x94000000,
-0x00030009,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800021,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x52800003,
-0x000a0205,
-0xf2a00003,
-0x000a0205,
-0xf2c00003,
-0x000a0205,
-0xf2e00003,
-0x000a0205,
-0x92800002,
-0x92800021,
-0xaa1503e0,
-0x94000000,
-0x0003000a,
-0xaa0003f4,
-0x12800041,
-0xaa1503e0,
-0x94000000,
-0x0003000b,
-0x00000000,
-0x2d410e82,
-0x00000000,
-0x6d410e82,
-0x00000000,
-0xbd400a82,
-0x00000000,
-0xfd400a82,
-0x00000000,
-0x2d400680,
-0x00000000,
-0x6d400680,
-0x00000000,
-0xbd400280,
-0x00000000,
-0xfd400280,
-0x00000000,
-0xf84003e0,
-0x000f0000,
-0xaa1403e1,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x52800009,
-0x000a0205,
-0xf2a00009,
-0x000a0205,
-0xf2c00009,
-0x000a0205,
-0xf2e00009,
-0x000a0205,
-0xd63f0120,
-0x00000000,
-0xa9400680,
-0x00000000,
-0xf9400280,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x92800021,
-0xaa1503e0,
-0x94000000,
-0x00030000,
-0x52800003,
-0x000a0205,
-0xf2a00003,
-0x000a0205,
-0xf2c00003,
-0x000a0205,
-0xf2e00003,
-0x000a0205,
-0x92800002,
-0x92800021,
-0xaa1503e0,
-0x94000000,
-0x0003000c,
-0x00000000,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x0003000b,
-0x00000000,
-0x12800001,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003000d,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003000e,
-0x00000000,
-0x12800001,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003000f,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030010,
-0x00000000,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030011,
-0x00000000,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030012,
-0x00000000,
-0x9e660014,
-0x12800041,
-0xaa1503e0,
-0x94000000,
-0x0003000b,
-0x9e670280,
-0x00000000,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030013,
-0x00000000,
-0x9e660014,
-0x12800041,
-0xaa1503e0,
-0x94000000,
-0x0003000b,
-0x9e670280,
-0x00000000,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030014,
-0x00000000,
-0x12800001,
-0xaa1503e0,
-0x94000000,
-0x00030015,
-0x00000000,
-0xaa1503e0,
-0x12800041,
-0x9e660014,
-0x9e660035,
-0x94000000,
-0x0003000b,
-0x9e670280,
-0x9e6702a1,
-0x00000000,
-0xaa0003f4,
-0x12800041,
-0xaa1503e0,
-0x94000000,
-0x0003000b,
-0xaa1403e0,
-0x00000000,
-0xa9407bfd,
-0xa94157f4,
-0x910003ff,
-0x000c0000,
-0xd65f03c0,
-0x00000000,
-0x6d000fe2,
-0x000a8cef,
-0x00000000,
-0xfc0003e2,
-0x000f0000,
-0x00000000,
-0x6d0007e0,
-0x000a8cef,
-0x00000000,
-0xfc0003e0,
-0x000f0000,
-0x00000000,
-0x2c810680,
-0x2c810e82,
-0x00000000,
-0x6c810680,
-0x6c810e82,
-0x00000000,
-0x2c810680,
-0xbc008682,
-0x00000000,
-0x6c810680,
-0xfc008682,
-0x00000000,
-0x2c810680,
-0x00000000,
-0x6c810680,
-0x00000000,
-0xbc008680,
-0x00000000,
-0xfc008680,
-0x00000000,
-0xb80003e0,
-0x000f0000,
-0x00000000,
-0xb8000680,
-0x000a812c,
-0x00000000,
-0xf80003e0,
-0x000f0000,
-0x00000000,
-0xf8000680,
-0x000a812c,
-0x00000000,
-0xa90007e0,
-0x000a8cef,
-0x00000000,
-0xa8810680,
-0x00000000,
-0xd100c3ff,
-0xf80143f5,
-0xa90153f3,
-0xa9007bfd,
-0x910003fd,
-0xaa0003f5,
-0x00000000,
-0x52800009,
-0x000a0205,
-0xf2a00009,
-0x000a0205,
-0xcb2963ff,
-0x00000000,
-0xd10003ff,
-0x000c0000,
-0x00000000,
-0x94000000,
-0x00030016,
-0x7100001f,
-0x000c0000,
-0x5400000a,
-0x00050801,
-0x52800001,
-0x000a0205,
-0xf2a00001,
-0x000a0205,
-0xf2c00001,
-0x000a0205,
-0xf2e00001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030017,
-0x0006000b,
-0xaa0003f3,
-0x91000400,
-0xb34003e0,
-0xcb206fff,
-0x00000000,
-0x910203f4,
-0x00000000,
-0x52800003,
-0x000a0205,
-0xf2a00003,
-0x000a0205,
-0xf2c00003,
-0x000a0205,
-0xf2e00003,
-0x000a0205,
-0x52800002,
-0x000a0205,
-0x72a00002,
-0x000a0205,
-0x52800001,
-0x000a0205,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030009,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030018,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003000c,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003000a,
-0x00000000,
-0x2d410c02,
-0x00000000,
-0x6d410c02,
-0x00000000,
-0xbd400802,
-0x00000000,
-0xfd400802,
-0x00000000,
-0x2d400400,
-0x00000000,
-0x6d400400,
-0x00000000,
-0xbd400000,
-0x00000000,
-0xfd400000,
-0x00000000,
-0xaa0003e1,
-0x00000000,
-0x52800000,
-0x000a0205,
-0xf2a00000,
-0x000a0205,
-0xcb0003a0,
-0x00000000,
-0xd10003a0,
-0x000c0000,
-0x00000000,
-0x52800002,
-0x000a0205,
-0x52800009,
-0x000a0205,
-0xf2a00009,
-0x000a0205,
-0xf2c00009,
-0x000a0205,
-0xf2e00009,
-0x000a0205,
-0xd63f0120,
-0x00000000,
-0xb9400000,
-0x00000000,
-0xf9400000,
-0x00000000,
-0xa9400400,
-0x00000000,
-0x52800001,
-0x000a0205,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003000d,
-0x6b1f001f,
-0x1a9f07e0,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003000e,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030010,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030011,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030013,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030012,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030014,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030015,
-0x00000000,
-0x910003e4,
-0x000c0000,
-0x52800003,
-0x000a0205,
-0xaa1303e2,
-0x52800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030019,
-0x00000000,
-0x910003e4,
-0x000c0000,
-0x52800003,
-0x000a0205,
-0xaa1303e2,
-0x52800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x0003001a,
-0x00000000,
-0xf100027f,
-0x000c0000,
-0x5400000d,
-0x00050801,
-0xaa1403e5,
-0x52800003,
-0x000a0205,
-0x52800003,
-0x000a0205,
-0xaa1303e2,
-0x52800001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x0003001b,
-0x0006000b,
-0x00000000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x52800001,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0xaa0003e8,
-0x00000000,
-0xa9471fe6,
-0x00000000,
-0xa94617e4,
-0x00000000,
-0xa9450fe2,
-0x00000000,
-0xa94407e0,
-0x00000000,
-0x6d431fe6,
-0x00000000,
-0x6d4217e4,
-0x00000000,
-0x6d410fe2,
-0x00000000,
-0x6d4007e0,
-0x00000000,
-0x910203ff,
-0x00000000,
-0x52800009,
-0x000a0205,
-0xf2a00009,
-0x000a0205,
-0xf2c00009,
-0x000a0205,
-0xf2e00009,
-0x000a0205,
-0xd63f0120,
-0x00000000,
-0xaa0003f4,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x52800001,
-0x000a0205,
-0x72a00001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0xf9000014,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0xaa0003e1,
-0xaa1503e0,
-0x94000000,
-0x00030003,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0xaa0003f4,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x2a1f03e1,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0xf9000014,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x2a1f03e0,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x2a0003e1,
-0xaa1503e0,
-0x94000000,
-0x00030004,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x2a0003e1,
-0x00000000,
-0x53001c21,
-0xaa1503e0,
-0x94000000,
-0x0003001c,
-0x00000000,
-0x13001c21,
-0xaa1503e0,
-0x94000000,
-0x00030005,
-0x00000000,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x2a0003e1,
-0x00000000,
-0x53003c21,
-0xaa1503e0,
-0x94000000,
-0x0003001c,
-0x00000000,
-0x13003c21,
-0xaa1503e0,
-0x94000000,
-0x00030005,
-0x00000000,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x2a0003e1,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x0003001c,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030005,
-0x00000000,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030006,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0xaa1503e0,
-0x94000000,
-0x00030007,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x1e260000,
-0x1e260021,
-0xaa018000,
-0xaa0003f4,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x52800001,
-0x000a0205,
-0x72a00001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0xf9000014,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x9e660013,
-0x9e660034,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x52800001,
-0x000a0205,
-0x72a00001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0xa9005013,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x52800001,
-0x000a0205,
-0x72a00001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x0003001d,
-0x12800021,
-0xaa1503e0,
-0x94000000,
-0x0003001e,
-0x00000000,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x52800000,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000,
-0x6dbf0fe2,
-0x00000000,
-0xfc1f0fe2,
-0x00000000,
-0x9e660033,
-0x00000000,
-0x9e660014,
-0x00000000,
-0xaa0103f3,
-0x00000000,
-0xaa0003f4,
-0x00000000,
-0x52800002,
-0x000a0205,
-0xf2a00002,
-0x000a0205,
-0xf2c00002,
-0x000a0205,
-0xf2e00002,
-0x000a0205,
-0x52800001,
-0x000a0205,
-0x72a00001,
-0x000a0205,
-0xaa1503e0,
-0x94000000,
-0x00030001,
-0x00000000,
-0x6cc107e0,
-0x00000000,
-0x2d010400,
-0x00000000,
-0x6d010400,
-0x00000000,
-0xfc4107e0,
-0x00000000,
-0xbd000800,
-0x00000000,
-0xfd000800,
-0x00000000,
-0x9e670260,
-0xbd000400,
-0x00000000,
-0xf9000413,
-0x00000000,
-0x9e670280,
-0xbd000000,
-0x00000000,
-0xf9000014,
-0x00000000,
-0xf9000413,
-0x00000000,
-0xf9000014,
-0x00000000,
-0x52800020,
-0x910003bf,
-0xa9407bfd,
-0xa94153f3,
-0xf94013f5,
-0x9100c3ff,
-0xd65f03c0,
-0x00000000
-};
-
-static const char *const globnames[] = {
-  (const char *)0
-};
-static const char *const extnames[] = {
-  "rawgeti",
-  "push_cdata",
-  "lua_remove",
-  "lua_pushinteger",
-  "lua_pushboolean",
-  "push_int",
-  "push_float",
-  "lua_pushnumber",
-  "lua_call",
-  "check_typed_pointer",
-  "check_struct",
-  "lua_settop",
-  "check_enum",
-  "check_uint32",
-  "check_int32",
-  "check_uint64",
-  "check_int64",
-  "check_uintptr",
-  "check_float",
-  "check_double",
-  "check_complex_double",
-  "check_complex_float",
-  "lua_gettop",
-  "luaL_error",
-  "check_typed_cfunction",
-  "unpack_varargs_float",
-  "unpack_varargs_int",
-  "unpack_varargs_stack_skip",
-  "push_uint",
-  "lua_pushvalue",
-  "lua_setuservalue",
-  (const char *)0
-};
-
-#define JUMP_SIZE 16
-
-//in aarch64 the pc is indicated the current 
-#define MIN_BRANCH ((INT32_MIN) >> 6)
-#define MAX_BRANCH ((INT32_MAX) >> 6)
-//arm64 pc has no offset so comparing with next instruction is -4 
-#define BRANCH_OFF -4
-#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
-
-static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
-{
-    /* The jump code is the function pointer followed by a stub to call the
-     * function pointer. The stub exists so we can jump to functions with an
-     * offset greater than 128MB.
-     *
-     * Note we have to manually set this up since there are commands buffered
-     * in the jit state.
-     */
-	 
-	 //l: ptr
-	 *(cfunction*) code = func;
-	 // ldr x9,#-8
-	  *(uint32_t*) &code[8] = 0x58FFFFC9;
-	 //br x9
-	 *(uint32_t*) &code[12] = 0xD61F0120;
-	
-}
-
-//| ldr reg, >5
-//| b >6
-//|5:
-//|.long64 val
-//|6:
-
-
-
-void compile_globals(struct jit* jit, lua_State* L)
-{
-    (void) jit;
-}
-typedef struct reg_info{
-	uint8_t ints;
-	uint8_t floats;
-	uint16_t ex;
-} reg_info;
-
-static ALWAYS_INLINE bool is_float_type(int t){
-    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
-}
-
-static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
-	struct ctype* mt;
-	int type,ele_count,i,ct_usr;
-	lua_getuservalue(L,idx);
-	ct_usr=lua_absindex(L,-1);
-    lua_rawgeti(L,ct_usr,1);
-    mt=(struct ctype*)lua_touserdata(L,-1);
-    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-        lua_pop(L,2);
-        return 0;
-    }
-	type=mt->type;
-    ele_count=(int)(ct->base_size/mt->base_size);
-    if(ele_count>4||ct->base_size%mt->base_size){
-        lua_pop(L,2);
-        return 0;
-    }
-	lua_pop(L,1);
-    for (i = 2;i<=4; ++i) {
-        lua_rawgeti(L,ct_usr,i);
-		if(lua_isnil(L,-1)){//case have array member;
-            lua_pop(L,1);
-            break;
-        }
-        mt=(struct ctype*)lua_touserdata(L,-1);
-        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-            lua_pop(L,2);
-            return 0;
-        }
-        lua_pop(L,1);
-    }
-	if(isfloat){
-		*isfloat=mt->type==FLOAT_TYPE;
-	}
-	lua_pop(L,1);
-    return ele_count;
-}
-
-static reg_info caculate_regs(lua_State* L,int ct_usr,int nargs){
-    int i;reg_info regs;
-    const struct ctype* mt;
-    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs&&(regs.floats<8||regs.ints<8); ++i){
-		lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (mt->pointers || mt->is_reference) {
-			if(regs.ints<8)regs.ints++;
-		}else{
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-				case COMPLEX_FLOAT_TYPE:
-					if(regs.floats<7)
-						regs.floats+=2;
-					else if(regs.floats==7)
-						regs.floats=8;
-					break;
-				case FLOAT_TYPE:
-				case DOUBLE_TYPE:
-					if(regs.floats<8) ++regs.floats;
-					break;
-				case STRUCT_TYPE:{
-                    int hfasize=hfa_size(L,-1,mt,NULL);
-                    if(hfasize>0){
-						regs.floats+=hfasize;
-						if(regs.floats>8)
-							regs.floats=8;
-						break;
-                    }
-                }
-				case UNION_TYPE:{
-					int size=mt->base_size;
-					if(size>16){//passed by address
-						if(regs.ints<8)++regs.ints;
-						break;
-					}
-					if(mt->is_empty){
-						break; //ignored empty struct
-					}
-					size=(size+7)>>3;
-					if(regs.ints+size<=8) regs.ints+=size;
-					break;
-				}
-				default:
-					if(regs.ints<8)++regs.ints;//no need to check type support here
-			}
-		}
-		lua_pop(L,1);
-	}
-	
-	return regs;
-}
-
-// arm store/load range for immediate value is only -256-255
-static ALWAYS_INLINE void load_int(struct jit* Dst,reg_info* regs){
-	if(regs->ints<8)
-		dasm_put(Dst, 0, 0x60+(regs->ints++<<3));
-	else
-		dasm_put(Dst, 3, (regs->ex++,8));
-}
-
-static void load_float(struct jit* Dst,reg_info* regs,int isfloat,int exSize){
-	if(regs->floats+exSize<8){
-		switch(exSize){
-			case 3:
-				dasm_put(Dst, 6, 0x30+(regs->floats<<3));
-				goto l_dual;
-			case 2:
-			    dasm_put(Dst, 9, 0x30+(regs->floats<<3));
-			case 1:
-			    l_dual:
-				dasm_put(Dst, 12, 0x20+(regs->floats<<3));
-				break;
-			case 0:
-			    dasm_put(Dst, 15, 0x20+(regs->floats<<3));
-				break;
-		}
-		regs->floats+=exSize+1;
-		
-	}else{
-		regs->floats=8;
-		regs->ex+=exSize+1;
-		switch(exSize){
-			case 3:
-				if(isfloat){
-					dasm_put(Dst, 18);
-				}else{
-					dasm_put(Dst, 21);
-				}
-			     break;
-			case 2:
-				if(isfloat){ //12 bytes rounded to 16
-					dasm_put(Dst, 24);
-					break;
-				}else {
-					dasm_put(Dst, 27);
-				}
-			     break;
-			case 1:
-				if(isfloat){
-					dasm_put(Dst, 30);
-				}else{
-					dasm_put(Dst, 32);
-				}
-				break;
-			case 0:
-				if(isfloat){
-					dasm_put(Dst, 34);
-				}else {
-					dasm_put(Dst, 36);
-				}
-				break;
-		}
-	
-	}
-}
-
-cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals, ref,ret_by_addr;
-    const struct ctype* mt;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    fidx = lua_absindex(L, fidx);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    dasm_setup(Dst, build_actionlist);
-
-    lua_newtable(L);
-    lua_pushvalue(L, -1);
-    ref = luaL_ref(L, LUA_REGISTRYINDEX);
-    num_upvals = 0;
-
-    if (ct->has_var_arg) {
-        luaL_error(L, "can't create callbacks with varargs");
-    }
-	
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
-				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
-	if(ret_by_addr){
-		dasm_put(Dst, 38);
-	}
-	lua_pop(L,1);	
-	reg_info regs=caculate_regs(L,ct_usr,nargs);
-	
-	if(regs.ints||regs.floats){
-		dasm_put(Dst, 40);
-	}else{
-		dasm_put(Dst, 42);
-	}
-	//8 integer reigsters and 8 floating registers
-	switch(regs.ints){
-		case 8:
-		case 7:
-			dasm_put(Dst, 44);
-		case 6:
-		case 5:
-			dasm_put(Dst, 46);
-		case 4:
-		case 3:
-			dasm_put(Dst, 48);
-		case 2:
-		case 1:
-			dasm_put(Dst, 50);
-	}	
-
-	switch(regs.floats){
-		case 8:
-		case 7:
-			dasm_put(Dst, 52);
-		case 6:
-		case 5:
-			dasm_put(Dst, 54);
-		case 4:
-		case 3:
-			dasm_put(Dst, 56);
-		case 2:
-		case 1:
-			dasm_put(Dst, 58);
-	} 
-	dasm_put(Dst, 60);
-	
-	if(regs.ints==8||regs.floats==8){ // may be overflowed if it's full
-		dasm_put(Dst, 63, 0xa0+ret_by_addr*0x10);
-	}
-	
-    /* get the lua function */
-    lua_pushvalue(L, fidx);
-    lua_rawseti(L, -2, ++num_upvals);
-	
-	dasm_put(Dst, 66, (unsigned short)(L), (((unsigned int)(L))>>16), (unsigned short)((unsigned long)(L)>>32), (unsigned short)((unsigned long)(L)>>48), (unsigned short)(ref), (((unsigned int)(ref))>>16), (unsigned short)(LUA_REGISTRYINDEX), (((unsigned int)(LUA_REGISTRYINDEX))>>16));
-	
-    dasm_put(Dst, 86, num_upvals);
-	
-
-    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; ++i) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-
-        if (mt->pointers || mt->is_reference) {
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-			
-            dasm_put(Dst, 93, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-			load_int(Dst,&regs);
-            dasm_put(Dst, 113);
-
-        } else {
-            switch (mt->type) {
-			case STRUCT_TYPE:
-			case UNION_TYPE:{
-				int isfloat,hfasize=0;
-				if(mt->type!=UNION_TYPE){
-					hfasize=hfa_size(L,-1,mt,&isfloat);
-				}
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-                dasm_put(Dst, 119, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-				
-				if(hfasize){
-					load_float(Dst,&regs,isfloat,hfasize-1);
-					switch(hfasize){
-						case 4:
-							if(isfloat){
-								dasm_put(Dst, 139);
-							}else{
-								dasm_put(Dst, 141);
-							}
-							goto hfa2;
-						case 3:
-							if(isfloat){
-								dasm_put(Dst, 143);
-							}else{
-								dasm_put(Dst, 145);
-							}
-						case 2:
-            			hfa2:
-							if(isfloat){
-								dasm_put(Dst, 147);
-							}else{
-								dasm_put(Dst, 149);
-							}
-							break;
-						case 1:
-							if(isfloat){
-								dasm_put(Dst, 151);
-							}else{
-								dasm_put(Dst, 153);
-							}
-							break;
-         							
-					}
-				}else if(!mt->is_empty){
-					size_t size=mt->base_size;
-					if(size>16){
-						load_int(Dst,&regs);
-						dasm_put(Dst, 155, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)((unsigned long)(mt->base_size)>>32), (unsigned short)((unsigned long)(mt->base_size)>>48), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16), (unsigned short)((unsigned long)(memcpy)>>32), (unsigned short)((unsigned long)(memcpy)>>48));
-					}else{
-						size=(size+7)>>3;
-						if(mt->align_mask>8){
-							if(regs.ints&1) regs.ints++;
-							else if(regs.ex&1) regs.ex++;
-						}
-						if(regs.ints+size<=8){
-							if(size>1){
-								dasm_put(Dst, 173, 0x60+(regs.ints<<3));
-							}else{
-								dasm_put(Dst, 177, 0x60+(regs.ints<<3));
-							}
-							regs.ints+=size;
-						}else{
-							regs.ints=8;
-							if(size>1){
-								dasm_put(Dst, 181);
-							}else{
-								dasm_put(Dst, 184);
-							}
-							
-						} 
-					}
-					
-					
-				}
-				
-                dasm_put(Dst, 187);
-			    break;
-			}
-			case COMPLEX_DOUBLE_TYPE:
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 192, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-				load_float(Dst,&regs,0,1);
-                dasm_put(Dst, 212);
-				
-				break;
-			case COMPLEX_FLOAT_TYPE:
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 218, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-				load_float(Dst,&regs,1,1);
-                dasm_put(Dst, 238);
-				
-				break;
-            case INT64_TYPE:
-			    #if LUA_VERSION_NUM>=503
-                lua_pop(L, 1);
-				load_int(Dst,&regs);
-                dasm_put(Dst, 244);
-				
-				#else
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 248, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-                load_int(Dst,&regs);
-                dasm_put(Dst, 261);
-				
-				#endif
-                break;
-
-            case INTPTR_TYPE:
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 267, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-                load_int(Dst,&regs);
-                dasm_put(Dst, 280);
-				
-                break;
-
-            case BOOL_TYPE:
-                lua_pop(L, 1);
-				
-				load_int(Dst,&regs);
-				dasm_put(Dst, 286);
-				
-                break;
-
-            case INT8_TYPE:// need to narrow for caller doesn't do it
-				lua_pop(L, 1);
-				if(regs.ints<8){
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 290, 0x60+(regs.ints++<<3));
-					} else {
-						dasm_put(Dst, 293, 0x60+(regs.ints++<<3));
-					}
-				}else {
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 296);
-					} else {
-						dasm_put(Dst, 298);
-					}
-				}
-				dasm_put(Dst, 300);
-				break;
-			
-            case INT16_TYPE:// need to narrow for caller doesn't do it
-				lua_pop(L, 1);
-				if(regs.ints<8){
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 304, 0x60+(regs.ints++<<3));
-					} else {
-						dasm_put(Dst, 307, 0x60+(regs.ints++<<3));
-					}
-				}else {
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 310);
-					} else {
-						dasm_put(Dst, 312);
-					}
-				}
-				dasm_put(Dst, 314);
-				break;
-				
-            case ENUM_TYPE:
-            case INT32_TYPE:
-                lua_pop(L, 1);
-				load_int(Dst,&regs);
-				
-                dasm_put(Dst, 318);
-                break;
-
-            case FLOAT_TYPE:
-                lua_pop(L, 1);
-				load_float(Dst,&regs,1,0);
-                dasm_put(Dst, 322);
-                break;
-
-            case DOUBLE_TYPE:
-                lua_pop(L, 1);
-				load_float(Dst,&regs,0,0);
-                dasm_put(Dst, 326);
-                break;
-            default:
-                luaL_error(L, "NYI: callback arg type");
-            }
-        }
-    }
-
-    lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-
-    dasm_put(Dst, 330, ((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0), nargs);
-    
-
-	
-    if (mt->pointers || mt->is_reference) {
-        lua_getuservalue(L, -1);
-        lua_rawseti(L, -3, ++num_upvals); /* usr value */
-        lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-        dasm_put(Dst, 338, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-        goto single_no_pop;
-    } else {
-        switch (mt->type) {
-		case STRUCT_TYPE:
-		case UNION_TYPE:{
-			int hfasize=0,isfloat;
-			if(mt->type!=UNION_TYPE){
-				hfasize=hfa_size(L,-1,mt,&isfloat);
-			}
-			lua_getuservalue(L, -1);
-			lua_rawseti(L, -3, ++num_upvals); /* usr value */
-			lua_rawseti(L, -2, ++num_upvals); /* mt */
-            dasm_put(Dst, 358, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-			if(hfasize){
-				switch(hfasize){
-					case 4:
-					    if(isfloat){
-							dasm_put(Dst, 383);
-						}else{
-							dasm_put(Dst, 385);
-						}
-						goto ld_hfa;
-					case 3:
-						if(isfloat){
-							dasm_put(Dst, 387);
-						}else{
-							dasm_put(Dst, 389);
-						}
-					case 2:
-						ld_hfa:
-					    if(isfloat){
-							dasm_put(Dst, 391);
-						}else{
-							dasm_put(Dst, 393);
-						}
-						break;
-					case 1:
-						if(isfloat){
-							dasm_put(Dst, 395);
-						}else{
-							dasm_put(Dst, 397);
-						}
-					    break;
-				}
-			}else{
-				if(mt->base_size>16){
-					dasm_put(Dst, 399, 0x20+((regs.ints||regs.floats)?0x80:0), (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)((unsigned long)(mt->base_size)>>32), (unsigned short)((unsigned long)(mt->base_size)>>48), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16), (unsigned short)((unsigned long)(memcpy)>>32), (unsigned short)((unsigned long)(memcpy)>>48));
-				}else{
-					if(mt->base_size>8){
-						dasm_put(Dst, 420);
-					}else{
-						dasm_put(Dst, 422);
-					}
-				}
-			}
-			break;
-		}
-        case ENUM_TYPE:
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-            dasm_put(Dst, 424, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-
-            goto single_no_pop;
-
-        case VOID_TYPE:
-            dasm_put(Dst, 444);
-            lua_pop(L, 1);
-            break;
-
-        case BOOL_TYPE:
-        case INT8_TYPE:
-        case INT16_TYPE:
-        case INT32_TYPE: //caller's responsiblity to narrow 
-		    dasm_put(Dst, 449);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 451);
-            } else {
-                dasm_put(Dst, 455);
-            }
-			
-            goto single;
-
-        case INT64_TYPE:
-            dasm_put(Dst, 459);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 461);
-            } else {
-                dasm_put(Dst, 465);
-            }
-			
-			goto single;
-
-        case INTPTR_TYPE:
-            dasm_put(Dst, 469);
-            goto single;
-
-        case FLOAT_TYPE:
-            dasm_put(Dst, 474);
-			
-            dasm_put(Dst, 479);
-            lua_pop(L, 1);
-			break;
-        case DOUBLE_TYPE:
-            dasm_put(Dst, 486);
-			
-            dasm_put(Dst, 491);
-			
-            lua_pop(L, 1);
-			break;
-			
-		case COMPLEX_DOUBLE_TYPE:
-
-			dasm_put(Dst, 498);
-		    
-			goto complex_ret;
-		case COMPLEX_FLOAT_TYPE:
-			dasm_put(Dst, 503);
-			
-		complex_ret:	
-			dasm_put(Dst, 508);
-
-            lua_pop(L, 1);			
-			break;
-        single:
-            lua_pop(L, 1);
-		single_no_pop:	
-            dasm_put(Dst, 517);
-            break;
-
-        
-        default:
-            luaL_error(L, "NYI: callback return type");
-        }
-    }
-	
-	dasm_put(Dst, 524,  (0x20 +ret_by_addr*0x10+ ((regs.floats!=0)||(regs.ints!=0)) * 0x80));
-	
-    lua_pop(L, 1); /* upval table - already in registry */
-    assert(lua_gettop(L) == top);
-
-    {
-        void* p;
-        struct ctype ft;
-        cfunction func;
-
-        func = compile(Dst, L, NULL, ref);
-
-        ft = *ct;
-        ft.is_jitted = 1;
-        p = push_cdata(L, ct_usr, &ft);
-        *(cfunction*) p = func;
-
-        assert(lua_gettop(L) == top + 1);
-
-        return func;
-    }
-}
-
-//arm64 argument can only be in stack or registers. An argument can't be splited between stack and register.
-static  void store_float(struct jit* Dst,reg_info* regs,int isfloat,int ex){
-	if(regs->floats+ex<8){
-		
-		switch(ex){
-			case 3:
-				dasm_put(Dst, 530, 0x10+(regs->floats<<3));
-			     goto sd_dual;
-			case 2:
-			    dasm_put(Dst, 533, 0x10+(regs->floats<<3));
-			case 1:
-			    sd_dual:
-				dasm_put(Dst, 536, (regs->floats<<3));
-				break;
-			case 0:
-				dasm_put(Dst, 539, (regs->floats<<3));
-				break;
-		}
-		regs->floats+=1+ex;
-	}else {
-		regs->floats=8;
-		switch(ex){
-			case 3:
-			    if(isfloat){
-					dasm_put(Dst, 542);
-				}else{
-					dasm_put(Dst, 545);
-				}				
-			    break;
-			case 2:
-			    if(isfloat){
-					dasm_put(Dst, 548);
-				}else{
-					dasm_put(Dst, 551);
-				}
-				break;
-			case 1:
-			    if(isfloat){
-					dasm_put(Dst, 554);
-				}else{
-					dasm_put(Dst, 556);
-				}
-				break;
-			case 0:
-				if(isfloat){
-					dasm_put(Dst, 558);
-				}else {
-					dasm_put(Dst, 560);
-				}
-				break;
-		}
-		//complex float is packed as one double on stack
-		regs->ex+=ex+1;
-	} 
-}
-
-static void store_int(struct jit* Dst,reg_info* regs,int intSize){
-	switch(intSize){
-		case 1:
-			if(regs->ints<8)
-				dasm_put(Dst, 562, 0x40+(regs->ints++<<3));
-			else
-				dasm_put(Dst, 565, (regs->ex++,8));
-            break;
-		case 2:
-			if(regs->ints<8)
-				dasm_put(Dst, 568, 0x40+(regs->ints++<<3));
-			else
-				dasm_put(Dst, 571, (regs->ex++,8));
-			break;
-		case 3:
-		case 4:
-			if(regs->ints<7){
-				dasm_put(Dst, 574, 0x40+(regs->ints<<3));
-				regs->ints+=2;
-			}
-			else{
-				if(regs->ints==7)
-					regs->ints=8;
-				dasm_put(Dst, 577);
-				regs->ex+=2;
-			}
-				
-			break;
-	}
-}
-
-static int caculate_stack(lua_State* L,int ct_usr,int nargs){
-    int i;reg_info regs={0,0,0};
-    const struct ctype* mt;int stack=0,extra=0;
-    for (i = 1; i <= nargs; ++i){
-		lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (mt->pointers || mt->is_reference) {
-			if(regs.ints<8)regs.ints++;
-			else stack++;
-		}else{
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-				case COMPLEX_FLOAT_TYPE:
-					if(regs.floats<7)
-						regs.floats+=2;
-					else if(regs.floats==7)
-						regs.floats=8;
-					else stack+=mt->base_size>>3;
-					break;
-				case FLOAT_TYPE:
-				case DOUBLE_TYPE:
-					if(regs.floats<8) ++regs.floats;
-					else stack++;
-					break;
-				case STRUCT_TYPE:{
-					int isfloat;
-                    int hfasize=hfa_size(L,-1,mt,&isfloat);
-                    if(hfasize>0){
-						if(regs.floats+hfasize<=8)
-							regs.floats +=hfasize;
-						else {
-						    regs.floats=8;
-							stack+=(hfasize*(2-isfloat)+1)>>1;	
-						}
-						break;
-                    }
-                }
-				case UNION_TYPE:{
-					int size=mt->base_size;
-					size=(size+7)>>3;
-					if(size>2){//passed by address
-						if(regs.ints<8)++regs.ints;
-						else stack++;
-					    extra+=size;//extra copy stack;
-						break;
-					}
-					if(mt->is_empty){
-						break; //ignored empty struct
-					}
-					if(mt->align_mask>8){
-						if(regs.ints&1) regs.ints++;
-						else if(stack&1) stack++;
-					}
-					if(regs.ints+size<=8) regs.ints+=size;
-					else{
-						regs.ints=8;
-						stack+=size;
-					} 
-					
-					break;
-				}
-				default:
-					if(regs.ints<8)++regs.ints;//no need to check type support here
-					else stack++;
-			}
-		}
-		lua_pop(L,1);
-	}
-	
-	return (regs.ints||regs.floats)?((stack+extra+17/*16 for regs, 1 for align*/)>>1)<<4:0;//2 eightbytes align
-}
-
-
-void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals,ret_by_addr;
-    const struct ctype* mt;
-	int stack_size,struct_offset;
-    void* p;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    p = push_cdata(L, ct_usr, ct);
-    *(cfunction*) p = func;
-    num_upvals = 1;
-
-    dasm_setup(Dst, build_actionlist);
-
-    reg_info regs={0,0};
-	
-	dasm_put(Dst, 579);
-	
-    /* reserve enough stack space for all of the arguments. */
-	stack_size=caculate_stack(L,ct_usr,nargs);
-	struct_offset=0;
-	if(stack_size>0){
-		if(stack_size>=1<<12){
-			dasm_put(Dst, 586, (unsigned short)(stack_size), (((unsigned int)(stack_size))>>16));
-		}
-		else{
-			dasm_put(Dst, 592, stack_size);
-		}
-		 if (ct->has_var_arg) {
-			dasm_put(Dst, 595, nargs, (unsigned short)("too few arguments"), (((unsigned int)("too few arguments"))>>16), (unsigned short)((unsigned long)("too few arguments")>>32), (unsigned short)((unsigned long)("too few arguments")>>48));
-		}
-		dasm_put(Dst, 618);
-    }
-	
-    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; i++) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		
-        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE||mt->type==STRUCT_TYPE||mt->type==UNION_TYPE) {
-            lua_getuservalue(L, -1);
-            num_upvals += 2;
-
-			
-			dasm_put(Dst, 620, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16), i);
-			
-            if (mt->pointers || mt->is_reference) {
-                dasm_put(Dst, 635);
-            } else{
-				switch (mt->type) {
-					case FUNCTION_PTR_TYPE: {
-						dasm_put(Dst, 639);
-						break;
-					}
-					case ENUM_TYPE:{
-						dasm_put(Dst, 643);
-						break;
-					} 
-					case STRUCT_TYPE:
-					case UNION_TYPE:{
-						if(mt->is_empty) continue;
-		
-						int isfloat;
-						int hfasize=hfa_size(L,-2,mt,&isfloat);
-						dasm_put(Dst, 647);
-                        if(hfasize>0){
-							switch(hfasize){
-								case 4:
-									if(isfloat){
-										dasm_put(Dst, 651);
-									}else{
-										dasm_put(Dst, 653);
-									}
-									goto ld_hfa;
-								case 3:
-									if(isfloat){
-										dasm_put(Dst, 655);
-									}else{
-										dasm_put(Dst, 657);
-									}
-								case 2:
-									ld_hfa:
-									if(isfloat){
-										dasm_put(Dst, 659);
-									}else{
-										dasm_put(Dst, 661);
-									}
-									break;
-								case 1:
-									if(isfloat){
-										dasm_put(Dst, 663);
-									}else{
-										dasm_put(Dst, 665);
-									}
-									break;
-									
-							}
-							store_float(Dst,&regs,isfloat,hfasize-1);
-							continue;
-						}
-						if(mt->base_size>16){
-							dasm_put(Dst, 667);
-							struct_offset+=(mt->base_size+7)&(~7);
-							if(struct_offset>=1<<12){
-								dasm_put(Dst, 669, (unsigned short)(struct_offset), (((unsigned int)(struct_offset))>>16));
-							}
-							else{
-								dasm_put(Dst, 675, struct_offset);
-							}
-							store_int(Dst,&regs,2);
-							dasm_put(Dst, 678, mt->base_size, (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16), (unsigned short)((unsigned long)(memcpy)>>32), (unsigned short)((unsigned long)(memcpy)>>48));
-						}else{
-							if(mt->align_mask>8){//==15
-								if(regs.ints&1) regs.ints++;
-								else if(regs.ex&1) regs.ex++;
-							}
-							int intSize=(mt->base_size+3)>>2;
-							switch(intSize){
-								case 1:
-									dasm_put(Dst, 690);
-									break;
-								case 2:
-									dasm_put(Dst, 692);
-									break;
-								case 3:
-								case 4:
-								    dasm_put(Dst, 694);
-									break;
-							}
-							store_int(Dst,&regs,intSize);
-						}
-						continue;
-					}	
-				}
-			}
-			goto longstore;
-
-        } else {
-            lua_pop(L, 1);
-            dasm_put(Dst, 696, i);
-
-            switch (mt->type) {
-            case BOOL_TYPE:
-                dasm_put(Dst, 699);
-                goto intstore;
-				
-            case INT8_TYPE:
-            case INT16_TYPE: //arm64 requires callee to narrow the type
-            case INT32_TYPE:
-                
-                dasm_put(Dst, 705);
-                
- 				goto intstore;
-
-            case INT64_TYPE:
-               
-                dasm_put(Dst, 709);
-               
-              	goto longstore;
-				
-            case INTPTR_TYPE:
-                dasm_put(Dst, 713);
-                
-                goto longstore;
-
-            case DOUBLE_TYPE:
-                dasm_put(Dst, 717);
-                store_float(Dst,&regs,0,0);
-                break;
-
-            case FLOAT_TYPE:
-                dasm_put(Dst, 721);
-                store_float(Dst,&regs,1,0);
-                break;
-			case COMPLEX_DOUBLE_TYPE:
-                dasm_put(Dst, 725);
-				store_float(Dst,&regs,0,1);
-                break;
-
-            case COMPLEX_FLOAT_TYPE:
-                dasm_put(Dst, 729);
-				store_float(Dst,&regs,1,1);
-                break;
-				
-			intstore:
-				store_int(Dst,&regs,1);
-                break;
-			longstore:
-				store_int(Dst,&regs,2);
-                break;
-				
-            default:
-                luaL_error(L, "NYI: call arg type");
-            }
-        }
-    }
-
-    if (ct->has_var_arg) {
-		if(regs.floats<8){
-			dasm_put(Dst, 733, regs.floats<<3, (8-regs.floats), nargs+1);
-		}
-		if(regs.ints<8){
-			dasm_put(Dst, 744, 0x40+(regs.ints<<3), (8-regs.ints), nargs+1);
-		}
-		dasm_put(Dst, 755, (nargs>8?nargs:8), (8-regs.floats), (8-regs.ints), nargs+1);
-		regs.floats=regs.ints=8;
-    }
-	
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
-				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
-	if(ret_by_addr){
-		dasm_put(Dst, 772, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-	}
-	
-	//pop all args in registers
-	switch(regs.ints){
-		case 8:
-		case 7:
-            dasm_put(Dst, 786);
-		case 6:
-		case 5:
-            dasm_put(Dst, 788);
-		case 4:
-		case 3:
-            dasm_put(Dst, 790);
-		case 2:
-		case 1:
-			dasm_put(Dst, 792);
-    }
-	
-	switch(regs.floats){
-		case 8:
-		case 7:
-            dasm_put(Dst, 794);
-		case 6:
-		case 5:
-            dasm_put(Dst, 796);
-		case 4:
-		case 3:
-            dasm_put(Dst, 798);
-		case 2:
-		case 1:
-			dasm_put(Dst, 800);
-    }
-	if(regs.ints==8|| regs.floats==8){// fix stack case registers is full
-		dasm_put(Dst, 802);
-	}
-	
-    dasm_put(Dst, 804, (unsigned short)(func), (((unsigned int)(func))>>16), (unsigned short)((unsigned long)(func)>>32), (unsigned short)((unsigned long)(func)>>48));
-
-
-    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
-        lua_getuservalue(L, -1);
-        num_upvals += 2;
-        dasm_put(Dst, 814, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-
-    } else {
-        switch (mt->type) {
-        case INT64_TYPE:
-		#if LUA_VERSION_NUM>=503
-			 lua_pop(L, 1);
-            dasm_put(Dst, 839);
-            break;
-		#endif
-
-        case INTPTR_TYPE:
-            num_upvals++;
-            dasm_put(Dst, 851, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
-			break;
-        case VOID_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 873);
-            break;
-
-        case BOOL_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 881);
-            break;
-
-        case INT8_TYPE:// we need to narrow the value before return
-			lua_pop(L, 1);
-            dasm_put(Dst, 893);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 895);
-            } else {
-                dasm_put(Dst, 900);
-            }
-            dasm_put(Dst, 905);
-			break;
-        case INT16_TYPE:// we need to narrow the value before return
-			lua_pop(L, 1);
-            dasm_put(Dst, 913);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 915);
-            } else {
-                dasm_put(Dst, 920);
-            }
-            dasm_put(Dst, 925);
-			break;
-        case INT32_TYPE:
-        case ENUM_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 933);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 935);
-            } else {
-                dasm_put(Dst, 939);
-            }
-            dasm_put(Dst, 943);
-            break;
-
-        case FLOAT_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 951);
-            break;
-
-        case DOUBLE_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 962);
-            break;
-		case COMPLEX_FLOAT_TYPE:
-            lua_getuservalue(L, -1);
-            num_upvals+=2;
-            dasm_put(Dst, 973, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-            break;
-
-        case COMPLEX_DOUBLE_TYPE:
-            lua_getuservalue(L, -1);
-            num_upvals+=2;
-            dasm_put(Dst, 1001, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-            break;
-		case STRUCT_TYPE:
-		case UNION_TYPE:
-			lua_getuservalue(L, -1);
-            num_upvals+=2;
-		    if(ret_by_addr){
-				if(!lua_isnil(L,-1)){
-					dasm_put(Dst, 1027, (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-				}
-				dasm_put(Dst, 1039);
-			}else if(mt->is_empty){
-				dasm_put(Dst, 1047);
-			}else{
-				int isfloat;
-				int hfasize=hfa_size(L,-2,mt,&isfloat);
-				if(hfasize){
-					switch(hfasize){
-						case 4:
-							dasm_put(Dst, 1055);
-							goto hfs_dual;
-						case 3:
-							dasm_put(Dst, 1057);
-						case 2:
-							hfs_dual:
-							dasm_put(Dst, 1059);
-						case 1:
-							dasm_put(Dst, 1061);
-							break;
-					}
-				}else{
-					if(mt->base_size>8){
-						dasm_put(Dst, 1063);
-					}
-					dasm_put(Dst, 1065);
-					
-				} 
-				dasm_put(Dst, 1067, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-				if(hfasize){
-					switch(hfasize){
-						case 4:
-							dasm_put(Dst, 1083);
-							if(isfloat){
-								dasm_put(Dst, 1085);
-							}else{
-								dasm_put(Dst, 1087);
-							} 
-							goto hfl_dual;
-						case 3:
-							dasm_put(Dst, 1089);
-							if(isfloat){
-								dasm_put(Dst, 1091);
-							}else{
-								dasm_put(Dst, 1093);
-							}
-						case 2:
-							hfl_dual:
-							if(isfloat){
-								dasm_put(Dst, 1095);
-							}else{
-								dasm_put(Dst, 1098);
-							}
-						case 1:
-							if(isfloat){
-								dasm_put(Dst, 1100);
-							}else{
-								dasm_put(Dst, 1103);
-							}
-							break;
-					}
-				}else{
-					if(mt->base_size>8){
-						dasm_put(Dst, 1105);
-					}
-					dasm_put(Dst, 1107);
-					
-				} 
-				dasm_put(Dst, 1109);
-			}
-			break;	
-		
-        default:
-            luaL_error(L, "NYI: call return type");
-        }
-    }
-
-    assert(lua_gettop(L) == top + num_upvals);
-	{
-        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
-        /* add a callback as an upval so that the jitted code gets cleaned up when
-         * the function gets gc'd */
-        push_callback(L, f, func);
-        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
-    }
-}
-
+/*
+** This file has been pre-processed with DynASM.
+** http://luajit.org/dynasm.html
+** DynASM version 1.4.0, DynASM arm version 1.4.0
+** DO NOT EDIT! The original file is in "call_arm64.dasc".
+*/
+
+/* vim: ts=4 sw=4 sts=4 et tw=78
+ * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+ * Portions copyright (c) 2011 James R. McKaskill.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+#if DASM_VERSION != 10400
+#error "Version mismatch between DynASM and included encoding engine"
+#endif
+
+static const unsigned int build_actionlist[1117] = {
+0xf84003e1,
+0x000f0000,
+0x00000000,
+0xf8400681,
+0x000a812c,
+0x00000000,
+0x6d400fe2,
+0x000a8cef,
+0x00000000,
+0xfc4003e2,
+0x000f0000,
+0x00000000,
+0x6d4007e0,
+0x000a8cef,
+0x00000000,
+0xfc4003e0,
+0x000f0000,
+0x00000000,
+0x2cc10680,
+0x2cc10e82,
+0x00000000,
+0x6cc10680,
+0x6cc10e82,
+0x00000000,
+0x2cc10680,
+0xbc408682,
+0x00000000,
+0x6cc10680,
+0xfc408682,
+0x00000000,
+0x2cc10680,
+0x00000000,
+0x6cc10680,
+0x00000000,
+0xbc408680,
+0x00000000,
+0xfc408680,
+0x00000000,
+0xf81f0fe8,
+0x00000000,
+0xd10283ff,
+0x00000000,
+0xd10083ff,
+0x00000000,
+0xa9091fe6,
+0x00000000,
+0xa90817e4,
+0x00000000,
+0xa9070fe2,
+0x00000000,
+0xa90607e0,
+0x00000000,
+0x6d051fe6,
+0x00000000,
+0x6d0417e4,
+0x00000000,
+0x6d030fe2,
+0x00000000,
+0x6d0207e0,
+0x00000000,
+0xa90157f4,
+0xa9007bfd,
+0x00000000,
+0x910003f4,
+0x000c0000,
+0x00000000,
+0x52800015,
+0x000a0205,
+0xf2a00015,
+0x000a0205,
+0xf2c00015,
+0x000a0205,
+0xf2e00015,
+0x000a0205,
+0x52800002,
+0x000a0205,
+0x72a00002,
+0x000a0205,
+0x52800001,
+0x000a0205,
+0x72a00001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800001,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0x00000000,
+0xf9000001,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x00030002,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0x00000000,
+0x2d010c02,
+0x00000000,
+0x6d010c02,
+0x00000000,
+0xbd000802,
+0x00000000,
+0xfd000802,
+0x00000000,
+0x2d000400,
+0x00000000,
+0x6d000400,
+0x00000000,
+0xbd000000,
+0x00000000,
+0xfd000000,
+0x00000000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x52800009,
+0x000a0205,
+0xf2a00009,
+0x000a0205,
+0xf2c00009,
+0x000a0205,
+0xf2e00009,
+0x000a0205,
+0xd63f0120,
+0x00000000,
+0xa9400be1,
+0x000a8cef,
+0xa9000801,
+0x00000000,
+0xf84003e1,
+0x000f0000,
+0xf9000001,
+0x00000000,
+0xa8c10a81,
+0xa9000801,
+0x00000000,
+0xf8408681,
+0xf9000001,
+0x00000000,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x00030002,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0x00000000,
+0x6d000400,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x00030002,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0x00000000,
+0x2d000400,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x00030002,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030003,
+0x00000000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x2a1f03e1,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0x00000000,
+0xf9000001,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x00030002,
+0x00000000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x2a1f03e1,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0x00000000,
+0xf9000001,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x00030002,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030004,
+0x00000000,
+0x384003e1,
+0x000f0000,
+0x00000000,
+0x38c003e1,
+0x000f0000,
+0x00000000,
+0x38408681,
+0x00000000,
+0x38c08681,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030005,
+0x00000000,
+0x784003e1,
+0x000f0000,
+0x00000000,
+0x78c003e1,
+0x000f0000,
+0x00000000,
+0x78408681,
+0x00000000,
+0x78c08681,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030005,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030005,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030006,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030007,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x52800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030008,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800021,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x52800003,
+0x000a0205,
+0xf2a00003,
+0x000a0205,
+0xf2c00003,
+0x000a0205,
+0xf2e00003,
+0x000a0205,
+0x92800002,
+0x92800021,
+0xaa1503e0,
+0x94000000,
+0x00030009,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800021,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x52800003,
+0x000a0205,
+0xf2a00003,
+0x000a0205,
+0xf2c00003,
+0x000a0205,
+0xf2e00003,
+0x000a0205,
+0x92800002,
+0x92800021,
+0xaa1503e0,
+0x94000000,
+0x0003000a,
+0xaa0003f4,
+0x12800041,
+0xaa1503e0,
+0x94000000,
+0x0003000b,
+0x00000000,
+0x2d410e82,
+0x00000000,
+0x6d410e82,
+0x00000000,
+0xbd400a82,
+0x00000000,
+0xfd400a82,
+0x00000000,
+0x2d400680,
+0x00000000,
+0x6d400680,
+0x00000000,
+0xbd400280,
+0x00000000,
+0xfd400280,
+0x00000000,
+0xf84003e0,
+0x000f0000,
+0xaa1403e1,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x52800009,
+0x000a0205,
+0xf2a00009,
+0x000a0205,
+0xf2c00009,
+0x000a0205,
+0xf2e00009,
+0x000a0205,
+0xd63f0120,
+0x00000000,
+0xa9400680,
+0x00000000,
+0xf9400280,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x92800021,
+0xaa1503e0,
+0x94000000,
+0x00030000,
+0x52800003,
+0x000a0205,
+0xf2a00003,
+0x000a0205,
+0xf2c00003,
+0x000a0205,
+0xf2e00003,
+0x000a0205,
+0x92800002,
+0x92800021,
+0xaa1503e0,
+0x94000000,
+0x0003000c,
+0x00000000,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x0003000b,
+0x00000000,
+0x12800001,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003000d,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003000e,
+0x00000000,
+0x12800001,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003000f,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030010,
+0x00000000,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030011,
+0x00000000,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030012,
+0x00000000,
+0x9e660014,
+0x12800041,
+0xaa1503e0,
+0x94000000,
+0x0003000b,
+0x9e670280,
+0x00000000,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030013,
+0x00000000,
+0x9e660014,
+0x12800041,
+0xaa1503e0,
+0x94000000,
+0x0003000b,
+0x9e670280,
+0x00000000,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030014,
+0x00000000,
+0x12800001,
+0xaa1503e0,
+0x94000000,
+0x00030015,
+0x00000000,
+0xaa1503e0,
+0x12800041,
+0x9e660014,
+0x9e660035,
+0x94000000,
+0x0003000b,
+0x9e670280,
+0x9e6702a1,
+0x00000000,
+0xaa0003f4,
+0x12800041,
+0xaa1503e0,
+0x94000000,
+0x0003000b,
+0xaa1403e0,
+0x00000000,
+0xa9407bfd,
+0xa94157f4,
+0x910003ff,
+0x000c0000,
+0xd65f03c0,
+0x00000000,
+0x6d000fe2,
+0x000a8cef,
+0x00000000,
+0xfc0003e2,
+0x000f0000,
+0x00000000,
+0x6d0007e0,
+0x000a8cef,
+0x00000000,
+0xfc0003e0,
+0x000f0000,
+0x00000000,
+0x2c810680,
+0x2c810e82,
+0x00000000,
+0x6c810680,
+0x6c810e82,
+0x00000000,
+0x2c810680,
+0xbc008682,
+0x00000000,
+0x6c810680,
+0xfc008682,
+0x00000000,
+0x2c810680,
+0x00000000,
+0x6c810680,
+0x00000000,
+0xbc008680,
+0x00000000,
+0xfc008680,
+0x00000000,
+0xb80003e0,
+0x000f0000,
+0x00000000,
+0xb8000680,
+0x000a812c,
+0x00000000,
+0xf80003e0,
+0x000f0000,
+0x00000000,
+0xf8000680,
+0x000a812c,
+0x00000000,
+0xa90007e0,
+0x000a8cef,
+0x00000000,
+0xa8810680,
+0x00000000,
+0xd100c3ff,
+0xf80143f5,
+0xa90153f3,
+0xa9007bfd,
+0x910003fd,
+0xaa0003f5,
+0x00000000,
+0x52800009,
+0x000a0205,
+0xf2a00009,
+0x000a0205,
+0xcb2963ff,
+0x00000000,
+0xd10003ff,
+0x000c0000,
+0x00000000,
+0x94000000,
+0x00030016,
+0x7100001f,
+0x000c0000,
+0x5400000a,
+0x00050801,
+0x52800001,
+0x000a0205,
+0xf2a00001,
+0x000a0205,
+0xf2c00001,
+0x000a0205,
+0xf2e00001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030017,
+0x0006000b,
+0xaa0003f3,
+0x91000400,
+0xb34003e0,
+0xcb206fff,
+0x00000000,
+0x910203f4,
+0x00000000,
+0x52800003,
+0x000a0205,
+0xf2a00003,
+0x000a0205,
+0xf2c00003,
+0x000a0205,
+0xf2e00003,
+0x000a0205,
+0x52800002,
+0x000a0205,
+0x72a00002,
+0x000a0205,
+0x52800001,
+0x000a0205,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030009,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030018,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003000c,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003000a,
+0x00000000,
+0x2d410c02,
+0x00000000,
+0x6d410c02,
+0x00000000,
+0xbd400802,
+0x00000000,
+0xfd400802,
+0x00000000,
+0x2d400400,
+0x00000000,
+0x6d400400,
+0x00000000,
+0xbd400000,
+0x00000000,
+0xfd400000,
+0x00000000,
+0xaa0003e1,
+0x00000000,
+0x52800000,
+0x000a0205,
+0xf2a00000,
+0x000a0205,
+0xcb0003a0,
+0x00000000,
+0xd10003a0,
+0x000c0000,
+0x00000000,
+0x52800002,
+0x000a0205,
+0x52800009,
+0x000a0205,
+0xf2a00009,
+0x000a0205,
+0xf2c00009,
+0x000a0205,
+0xf2e00009,
+0x000a0205,
+0xd63f0120,
+0x00000000,
+0xb9400000,
+0x00000000,
+0xf9400000,
+0x00000000,
+0xa9400400,
+0x00000000,
+0x52800001,
+0x000a0205,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003000d,
+0x6b1f001f,
+0x1a9f07e0,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003000e,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030010,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030011,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030013,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030012,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030014,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030015,
+0x00000000,
+0x910003e4,
+0x000c0000,
+0x52800003,
+0x000a0205,
+0xaa1303e2,
+0x52800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030019,
+0x00000000,
+0x910003e4,
+0x000c0000,
+0x52800003,
+0x000a0205,
+0xaa1303e2,
+0x52800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x0003001a,
+0x00000000,
+0xf100027f,
+0x000c0000,
+0x5400000d,
+0x00050801,
+0xaa1403e5,
+0x52800003,
+0x000a0205,
+0x52800003,
+0x000a0205,
+0xaa1303e2,
+0x52800001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x0003001b,
+0x0006000b,
+0x00000000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x52800001,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0xaa0003e8,
+0x00000000,
+0xa9471fe6,
+0x00000000,
+0xa94617e4,
+0x00000000,
+0xa9450fe2,
+0x00000000,
+0xa94407e0,
+0x00000000,
+0x6d431fe6,
+0x00000000,
+0x6d4217e4,
+0x00000000,
+0x6d410fe2,
+0x00000000,
+0x6d4007e0,
+0x00000000,
+0x910203ff,
+0x00000000,
+0x52800009,
+0x000a0205,
+0xf2a00009,
+0x000a0205,
+0xf2c00009,
+0x000a0205,
+0xf2e00009,
+0x000a0205,
+0xd63f0120,
+0x00000000,
+0xaa0003f4,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x52800001,
+0x000a0205,
+0x72a00001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0xf9000014,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0xaa0003e1,
+0xaa1503e0,
+0x94000000,
+0x00030003,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0xaa0003f4,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x2a1f03e1,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0xf9000014,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x2a1f03e0,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x2a0003e1,
+0xaa1503e0,
+0x94000000,
+0x00030004,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x2a0003e1,
+0x00000000,
+0x53001c21,
+0xaa1503e0,
+0x94000000,
+0x0003001c,
+0x00000000,
+0x13001c21,
+0xaa1503e0,
+0x94000000,
+0x00030005,
+0x00000000,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x2a0003e1,
+0x00000000,
+0x53003c21,
+0xaa1503e0,
+0x94000000,
+0x0003001c,
+0x00000000,
+0x13003c21,
+0xaa1503e0,
+0x94000000,
+0x00030005,
+0x00000000,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x2a0003e1,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x0003001c,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030005,
+0x00000000,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030006,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0xaa1503e0,
+0x94000000,
+0x00030007,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x1e260000,
+0x1e260021,
+0xaa018000,
+0xaa0003f4,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x52800001,
+0x000a0205,
+0x72a00001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0xf9000014,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x9e660013,
+0x9e660034,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x52800001,
+0x000a0205,
+0x72a00001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0xa9005013,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x52800001,
+0x000a0205,
+0x72a00001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x0003001d,
+0x12800021,
+0xaa1503e0,
+0x94000000,
+0x0003001e,
+0x00000000,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x52800000,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000,
+0x6dbf0fe2,
+0x00000000,
+0xfc1f0fe2,
+0x00000000,
+0x9e660033,
+0x00000000,
+0x9e660014,
+0x00000000,
+0xaa0103f3,
+0x00000000,
+0xaa0003f4,
+0x00000000,
+0x52800002,
+0x000a0205,
+0xf2a00002,
+0x000a0205,
+0xf2c00002,
+0x000a0205,
+0xf2e00002,
+0x000a0205,
+0x52800001,
+0x000a0205,
+0x72a00001,
+0x000a0205,
+0xaa1503e0,
+0x94000000,
+0x00030001,
+0x00000000,
+0x6cc107e0,
+0x00000000,
+0x2d010400,
+0x00000000,
+0x6d010400,
+0x00000000,
+0xfc4107e0,
+0x00000000,
+0xbd000800,
+0x00000000,
+0xfd000800,
+0x00000000,
+0x9e670260,
+0xbd000400,
+0x00000000,
+0xf9000413,
+0x00000000,
+0x9e670280,
+0xbd000000,
+0x00000000,
+0xf9000014,
+0x00000000,
+0xf9000413,
+0x00000000,
+0xf9000014,
+0x00000000,
+0x52800020,
+0x910003bf,
+0xa9407bfd,
+0xa94153f3,
+0xf94013f5,
+0x9100c3ff,
+0xd65f03c0,
+0x00000000
+};
+
+static const char *const globnames[] = {
+  (const char *)0
+};
+static const char *const extnames[] = {
+  "rawgeti",
+  "push_cdata",
+  "lua_remove",
+  "lua_pushinteger",
+  "lua_pushboolean",
+  "push_int",
+  "push_float",
+  "lua_pushnumber",
+  "lua_call",
+  "check_typed_pointer",
+  "check_struct",
+  "lua_settop",
+  "check_enum",
+  "check_uint32",
+  "check_int32",
+  "check_uint64",
+  "check_int64",
+  "check_uintptr",
+  "check_float",
+  "check_double",
+  "check_complex_double",
+  "check_complex_float",
+  "lua_gettop",
+  "luaL_error",
+  "check_typed_cfunction",
+  "unpack_varargs_float",
+  "unpack_varargs_int",
+  "unpack_varargs_stack_skip",
+  "push_uint",
+  "lua_pushvalue",
+  "lua_setuservalue",
+  (const char *)0
+};
+
+#define JUMP_SIZE 16
+
+//in aarch64 the pc is indicated the current 
+#define MIN_BRANCH ((INT32_MIN) >> 6)
+#define MAX_BRANCH ((INT32_MAX) >> 6)
+//arm64 pc has no offset so comparing with next instruction is -4 
+#define BRANCH_OFF -4
+#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
+
+static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
+{
+    /* The jump code is the function pointer followed by a stub to call the
+     * function pointer. The stub exists so we can jump to functions with an
+     * offset greater than 128MB.
+     *
+     * Note we have to manually set this up since there are commands buffered
+     * in the jit state.
+     */
+	 
+	 //l: ptr
+	 *(cfunction*) code = func;
+	 // ldr x9,#-8
+	  *(uint32_t*) &code[8] = 0x58FFFFC9;
+	 //br x9
+	 *(uint32_t*) &code[12] = 0xD61F0120;
+	
+}
+
+//| ldr reg, >5
+//| b >6
+//|5:
+//|.long64 val
+//|6:
+
+
+
+void compile_globals(struct jit* jit, lua_State* L)
+{
+    (void) jit;
+}
+typedef struct reg_info{
+	uint8_t ints;
+	uint8_t floats;
+	uint16_t ex;
+} reg_info;
+
+static ALWAYS_INLINE bool is_float_type(int t){
+    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
+}
+
+static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
+	struct ctype* mt;
+	int type,ele_count,i,ct_usr;
+	lua_getuservalue(L,idx);
+	ct_usr=lua_absindex(L,-1);
+    lua_rawgeti(L,ct_usr,1);
+    mt=(struct ctype*)lua_touserdata(L,-1);
+    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+        lua_pop(L,2);
+        return 0;
+    }
+	type=mt->type;
+    ele_count=(int)(ct->base_size/mt->base_size);
+    if(ele_count>4||ct->base_size%mt->base_size){
+        lua_pop(L,2);
+        return 0;
+    }
+	lua_pop(L,1);
+    for (i = 2;i<=4; ++i) {
+        lua_rawgeti(L,ct_usr,i);
+		if(lua_isnil(L,-1)){//case have array member;
+            lua_pop(L,1);
+            break;
+        }
+        mt=(struct ctype*)lua_touserdata(L,-1);
+        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+            lua_pop(L,2);
+            return 0;
+        }
+        lua_pop(L,1);
+    }
+	if(isfloat){
+		*isfloat=mt->type==FLOAT_TYPE;
+	}
+	lua_pop(L,1);
+    return ele_count;
+}
+
+static reg_info caculate_regs(lua_State* L,int ct_usr,int nargs){
+    int i;reg_info regs;
+    const struct ctype* mt;
+    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs&&(regs.floats<8||regs.ints<8); ++i){
+		lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (mt->pointers || mt->is_reference) {
+			if(regs.ints<8)regs.ints++;
+		}else{
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+				case COMPLEX_FLOAT_TYPE:
+					if(regs.floats<7)
+						regs.floats+=2;
+					else if(regs.floats==7)
+						regs.floats=8;
+					break;
+				case FLOAT_TYPE:
+				case DOUBLE_TYPE:
+					if(regs.floats<8) ++regs.floats;
+					break;
+				case STRUCT_TYPE:{
+                    int hfasize=hfa_size(L,-1,mt,NULL);
+                    if(hfasize>0){
+						regs.floats+=hfasize;
+						if(regs.floats>8)
+							regs.floats=8;
+						break;
+                    }
+                }
+				case UNION_TYPE:{
+					int size=mt->base_size;
+					if(size>16){//passed by address
+						if(regs.ints<8)++regs.ints;
+						break;
+					}
+					if(mt->is_empty){
+						break; //ignored empty struct
+					}
+					size=(size+7)>>3;
+					if(regs.ints+size<=8) regs.ints+=size;
+					break;
+				}
+				default:
+					if(regs.ints<8)++regs.ints;//no need to check type support here
+			}
+		}
+		lua_pop(L,1);
+	}
+	
+	return regs;
+}
+
+// arm store/load range for immediate value is only -256-255
+static ALWAYS_INLINE void load_int(struct jit* Dst,reg_info* regs){
+	if(regs->ints<8)
+		dasm_put(Dst, 0, 0x60+(regs->ints++<<3));
+	else
+		dasm_put(Dst, 3, (regs->ex++,8));
+}
+
+static void load_float(struct jit* Dst,reg_info* regs,int isfloat,int exSize){
+	if(regs->floats+exSize<8){
+		switch(exSize){
+			case 3:
+				dasm_put(Dst, 6, 0x30+(regs->floats<<3));
+				goto l_dual;
+			case 2:
+			    dasm_put(Dst, 9, 0x30+(regs->floats<<3));
+			case 1:
+			    l_dual:
+				dasm_put(Dst, 12, 0x20+(regs->floats<<3));
+				break;
+			case 0:
+			    dasm_put(Dst, 15, 0x20+(regs->floats<<3));
+				break;
+		}
+		regs->floats+=exSize+1;
+		
+	}else{
+		regs->floats=8;
+		regs->ex+=exSize+1;
+		switch(exSize){
+			case 3:
+				if(isfloat){
+					dasm_put(Dst, 18);
+				}else{
+					dasm_put(Dst, 21);
+				}
+			     break;
+			case 2:
+				if(isfloat){ //12 bytes rounded to 16
+					dasm_put(Dst, 24);
+					break;
+				}else {
+					dasm_put(Dst, 27);
+				}
+			     break;
+			case 1:
+				if(isfloat){
+					dasm_put(Dst, 30);
+				}else{
+					dasm_put(Dst, 32);
+				}
+				break;
+			case 0:
+				if(isfloat){
+					dasm_put(Dst, 34);
+				}else {
+					dasm_put(Dst, 36);
+				}
+				break;
+		}
+	
+	}
+}
+
+cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals, ref,ret_by_addr;
+    const struct ctype* mt;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    fidx = lua_absindex(L, fidx);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    dasm_setup(Dst, build_actionlist);
+
+    lua_newtable(L);
+    lua_pushvalue(L, -1);
+    ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    num_upvals = 0;
+
+    if (ct->has_var_arg) {
+        luaL_error(L, "can't create callbacks with varargs");
+    }
+	
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
+				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
+	if(ret_by_addr){
+		dasm_put(Dst, 38);
+	}
+	lua_pop(L,1);	
+	reg_info regs=caculate_regs(L,ct_usr,nargs);
+	
+	if(regs.ints||regs.floats){
+		dasm_put(Dst, 40);
+	}else{
+		dasm_put(Dst, 42);
+	}
+	//8 integer reigsters and 8 floating registers
+	switch(regs.ints){
+		case 8:
+		case 7:
+			dasm_put(Dst, 44);
+		case 6:
+		case 5:
+			dasm_put(Dst, 46);
+		case 4:
+		case 3:
+			dasm_put(Dst, 48);
+		case 2:
+		case 1:
+			dasm_put(Dst, 50);
+	}	
+
+	switch(regs.floats){
+		case 8:
+		case 7:
+			dasm_put(Dst, 52);
+		case 6:
+		case 5:
+			dasm_put(Dst, 54);
+		case 4:
+		case 3:
+			dasm_put(Dst, 56);
+		case 2:
+		case 1:
+			dasm_put(Dst, 58);
+	} 
+	dasm_put(Dst, 60);
+	
+	if(regs.ints==8||regs.floats==8){ // may be overflowed if it's full
+		dasm_put(Dst, 63, 0xa0+ret_by_addr*0x10);
+	}
+	
+    /* get the lua function */
+    lua_pushvalue(L, fidx);
+    lua_rawseti(L, -2, ++num_upvals);
+	
+	dasm_put(Dst, 66, (unsigned short)(L), (((unsigned int)(L))>>16), (unsigned short)((unsigned long)(L)>>32), (unsigned short)((unsigned long)(L)>>48), (unsigned short)(ref), (((unsigned int)(ref))>>16), (unsigned short)(LUA_REGISTRYINDEX), (((unsigned int)(LUA_REGISTRYINDEX))>>16));
+	
+    dasm_put(Dst, 86, num_upvals);
+	
+
+    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; ++i) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+
+        if (mt->pointers || mt->is_reference) {
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+			
+            dasm_put(Dst, 93, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+			load_int(Dst,&regs);
+            dasm_put(Dst, 113);
+
+        } else {
+            switch (mt->type) {
+			case STRUCT_TYPE:
+			case UNION_TYPE:{
+				int isfloat,hfasize=0;
+				if(mt->type!=UNION_TYPE){
+					hfasize=hfa_size(L,-1,mt,&isfloat);
+				}
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+                dasm_put(Dst, 119, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+				
+				if(hfasize){
+					load_float(Dst,&regs,isfloat,hfasize-1);
+					switch(hfasize){
+						case 4:
+							if(isfloat){
+								dasm_put(Dst, 139);
+							}else{
+								dasm_put(Dst, 141);
+							}
+							goto hfa2;
+						case 3:
+							if(isfloat){
+								dasm_put(Dst, 143);
+							}else{
+								dasm_put(Dst, 145);
+							}
+						case 2:
+            			hfa2:
+							if(isfloat){
+								dasm_put(Dst, 147);
+							}else{
+								dasm_put(Dst, 149);
+							}
+							break;
+						case 1:
+							if(isfloat){
+								dasm_put(Dst, 151);
+							}else{
+								dasm_put(Dst, 153);
+							}
+							break;
+         							
+					}
+				}else if(!mt->is_empty){
+					size_t size=mt->base_size;
+					if(size>16){
+						load_int(Dst,&regs);
+						dasm_put(Dst, 155, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)((unsigned long)(mt->base_size)>>32), (unsigned short)((unsigned long)(mt->base_size)>>48), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16), (unsigned short)((unsigned long)(memcpy)>>32), (unsigned short)((unsigned long)(memcpy)>>48));
+					}else{
+						size=(size+7)>>3;
+						if(mt->align_mask>8){
+							if(regs.ints&1) regs.ints++;
+							else if(regs.ex&1) regs.ex++;
+						}
+						if(regs.ints+size<=8){
+							if(size>1){
+								dasm_put(Dst, 173, 0x60+(regs.ints<<3));
+							}else{
+								dasm_put(Dst, 177, 0x60+(regs.ints<<3));
+							}
+							regs.ints+=size;
+						}else{
+							regs.ints=8;
+							if(size>1){
+								dasm_put(Dst, 181);
+							}else{
+								dasm_put(Dst, 184);
+							}
+							
+						} 
+					}
+					
+					
+				}
+				
+                dasm_put(Dst, 187);
+			    break;
+			}
+			case COMPLEX_DOUBLE_TYPE:
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 192, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+				load_float(Dst,&regs,0,1);
+                dasm_put(Dst, 212);
+				
+				break;
+			case COMPLEX_FLOAT_TYPE:
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 218, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+				load_float(Dst,&regs,1,1);
+                dasm_put(Dst, 238);
+				
+				break;
+            case INT64_TYPE:
+			    #if LUA_VERSION_NUM>=503
+                lua_pop(L, 1);
+				load_int(Dst,&regs);
+                dasm_put(Dst, 244);
+				
+				#else
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 248, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+                load_int(Dst,&regs);
+                dasm_put(Dst, 261);
+				
+				#endif
+                break;
+
+            case INTPTR_TYPE:
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 267, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+                load_int(Dst,&regs);
+                dasm_put(Dst, 280);
+				
+                break;
+
+            case BOOL_TYPE:
+                lua_pop(L, 1);
+				
+				load_int(Dst,&regs);
+				dasm_put(Dst, 286);
+				
+                break;
+
+            case INT8_TYPE:// need to narrow for caller doesn't do it
+				lua_pop(L, 1);
+				if(regs.ints<8){
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 290, 0x60+(regs.ints++<<3));
+					} else {
+						dasm_put(Dst, 293, 0x60+(regs.ints++<<3));
+					}
+				}else {
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 296);
+					} else {
+						dasm_put(Dst, 298);
+					}
+				}
+				dasm_put(Dst, 300);
+				break;
+			
+            case INT16_TYPE:// need to narrow for caller doesn't do it
+				lua_pop(L, 1);
+				if(regs.ints<8){
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 304, 0x60+(regs.ints++<<3));
+					} else {
+						dasm_put(Dst, 307, 0x60+(regs.ints++<<3));
+					}
+				}else {
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 310);
+					} else {
+						dasm_put(Dst, 312);
+					}
+				}
+				dasm_put(Dst, 314);
+				break;
+				
+            case ENUM_TYPE:
+            case INT32_TYPE:
+                lua_pop(L, 1);
+				load_int(Dst,&regs);
+				
+                dasm_put(Dst, 318);
+                break;
+
+            case FLOAT_TYPE:
+                lua_pop(L, 1);
+				load_float(Dst,&regs,1,0);
+                dasm_put(Dst, 322);
+                break;
+
+            case DOUBLE_TYPE:
+                lua_pop(L, 1);
+				load_float(Dst,&regs,0,0);
+                dasm_put(Dst, 326);
+                break;
+            default:
+                luaL_error(L, "NYI: callback arg type");
+            }
+        }
+    }
+
+    lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+
+    dasm_put(Dst, 330, ((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0), nargs);
+    
+
+	
+    if (mt->pointers || mt->is_reference) {
+        lua_getuservalue(L, -1);
+        lua_rawseti(L, -3, ++num_upvals); /* usr value */
+        lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+        dasm_put(Dst, 338, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+        goto single_no_pop;
+    } else {
+        switch (mt->type) {
+		case STRUCT_TYPE:
+		case UNION_TYPE:{
+			int hfasize=0,isfloat;
+			if(mt->type!=UNION_TYPE){
+				hfasize=hfa_size(L,-1,mt,&isfloat);
+			}
+			lua_getuservalue(L, -1);
+			lua_rawseti(L, -3, ++num_upvals); /* usr value */
+			lua_rawseti(L, -2, ++num_upvals); /* mt */
+            dasm_put(Dst, 358, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+			if(hfasize){
+				switch(hfasize){
+					case 4:
+					    if(isfloat){
+							dasm_put(Dst, 383);
+						}else{
+							dasm_put(Dst, 385);
+						}
+						goto ld_hfa;
+					case 3:
+						if(isfloat){
+							dasm_put(Dst, 387);
+						}else{
+							dasm_put(Dst, 389);
+						}
+					case 2:
+						ld_hfa:
+					    if(isfloat){
+							dasm_put(Dst, 391);
+						}else{
+							dasm_put(Dst, 393);
+						}
+						break;
+					case 1:
+						if(isfloat){
+							dasm_put(Dst, 395);
+						}else{
+							dasm_put(Dst, 397);
+						}
+					    break;
+				}
+			}else{
+				if(mt->base_size>16){
+					dasm_put(Dst, 399, 0x20+((regs.ints||regs.floats)?0x80:0), (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)((unsigned long)(mt->base_size)>>32), (unsigned short)((unsigned long)(mt->base_size)>>48), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16), (unsigned short)((unsigned long)(memcpy)>>32), (unsigned short)((unsigned long)(memcpy)>>48));
+				}else{
+					if(mt->base_size>8){
+						dasm_put(Dst, 420);
+					}else{
+						dasm_put(Dst, 422);
+					}
+				}
+			}
+			break;
+		}
+        case ENUM_TYPE:
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+            dasm_put(Dst, 424, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+
+            goto single_no_pop;
+
+        case VOID_TYPE:
+            dasm_put(Dst, 444);
+            lua_pop(L, 1);
+            break;
+
+        case BOOL_TYPE:
+        case INT8_TYPE:
+        case INT16_TYPE:
+        case INT32_TYPE: //caller's responsiblity to narrow 
+		    dasm_put(Dst, 449);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 451);
+            } else {
+                dasm_put(Dst, 455);
+            }
+			
+            goto single;
+
+        case INT64_TYPE:
+            dasm_put(Dst, 459);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 461);
+            } else {
+                dasm_put(Dst, 465);
+            }
+			
+			goto single;
+
+        case INTPTR_TYPE:
+            dasm_put(Dst, 469);
+            goto single;
+
+        case FLOAT_TYPE:
+            dasm_put(Dst, 474);
+			
+            dasm_put(Dst, 479);
+            lua_pop(L, 1);
+			break;
+        case DOUBLE_TYPE:
+            dasm_put(Dst, 486);
+			
+            dasm_put(Dst, 491);
+			
+            lua_pop(L, 1);
+			break;
+			
+		case COMPLEX_DOUBLE_TYPE:
+
+			dasm_put(Dst, 498);
+		    
+			goto complex_ret;
+		case COMPLEX_FLOAT_TYPE:
+			dasm_put(Dst, 503);
+			
+		complex_ret:	
+			dasm_put(Dst, 508);
+
+            lua_pop(L, 1);			
+			break;
+        single:
+            lua_pop(L, 1);
+		single_no_pop:	
+            dasm_put(Dst, 517);
+            break;
+
+        
+        default:
+            luaL_error(L, "NYI: callback return type");
+        }
+    }
+	
+	dasm_put(Dst, 524,  (0x20 +ret_by_addr*0x10+ ((regs.floats!=0)||(regs.ints!=0)) * 0x80));
+	
+    lua_pop(L, 1); /* upval table - already in registry */
+    assert(lua_gettop(L) == top);
+
+    {
+        void* p;
+        struct ctype ft;
+        cfunction func;
+
+        func = compile(Dst, L, NULL, ref);
+
+        ft = *ct;
+        ft.is_jitted = 1;
+        p = push_cdata(L, ct_usr, &ft);
+        *(cfunction*) p = func;
+
+        assert(lua_gettop(L) == top + 1);
+
+        return func;
+    }
+}
+
+//arm64 argument can only be in stack or registers. An argument can't be splited between stack and register.
+static  void store_float(struct jit* Dst,reg_info* regs,int isfloat,int ex){
+	if(regs->floats+ex<8){
+		
+		switch(ex){
+			case 3:
+				dasm_put(Dst, 530, 0x10+(regs->floats<<3));
+			     goto sd_dual;
+			case 2:
+			    dasm_put(Dst, 533, 0x10+(regs->floats<<3));
+			case 1:
+			    sd_dual:
+				dasm_put(Dst, 536, (regs->floats<<3));
+				break;
+			case 0:
+				dasm_put(Dst, 539, (regs->floats<<3));
+				break;
+		}
+		regs->floats+=1+ex;
+	}else {
+		regs->floats=8;
+		switch(ex){
+			case 3:
+			    if(isfloat){
+					dasm_put(Dst, 542);
+				}else{
+					dasm_put(Dst, 545);
+				}				
+			    break;
+			case 2:
+			    if(isfloat){
+					dasm_put(Dst, 548);
+				}else{
+					dasm_put(Dst, 551);
+				}
+				break;
+			case 1:
+			    if(isfloat){
+					dasm_put(Dst, 554);
+				}else{
+					dasm_put(Dst, 556);
+				}
+				break;
+			case 0:
+				if(isfloat){
+					dasm_put(Dst, 558);
+				}else {
+					dasm_put(Dst, 560);
+				}
+				break;
+		}
+		//complex float is packed as one double on stack
+		regs->ex+=ex+1;
+	} 
+}
+
+static void store_int(struct jit* Dst,reg_info* regs,int intSize){
+	switch(intSize){
+		case 1:
+			if(regs->ints<8)
+				dasm_put(Dst, 562, 0x40+(regs->ints++<<3));
+			else
+				dasm_put(Dst, 565, (regs->ex++,8));
+            break;
+		case 2:
+			if(regs->ints<8)
+				dasm_put(Dst, 568, 0x40+(regs->ints++<<3));
+			else
+				dasm_put(Dst, 571, (regs->ex++,8));
+			break;
+		case 3:
+		case 4:
+			if(regs->ints<7){
+				dasm_put(Dst, 574, 0x40+(regs->ints<<3));
+				regs->ints+=2;
+			}
+			else{
+				if(regs->ints==7)
+					regs->ints=8;
+				dasm_put(Dst, 577);
+				regs->ex+=2;
+			}
+				
+			break;
+	}
+}
+
+static int caculate_stack(lua_State* L,int ct_usr,int nargs){
+    int i;reg_info regs={0,0,0};
+    const struct ctype* mt;int stack=0,extra=0;
+    for (i = 1; i <= nargs; ++i){
+		lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (mt->pointers || mt->is_reference) {
+			if(regs.ints<8)regs.ints++;
+			else stack++;
+		}else{
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+				case COMPLEX_FLOAT_TYPE:
+					if(regs.floats<7)
+						regs.floats+=2;
+					else if(regs.floats==7)
+						regs.floats=8;
+					else stack+=mt->base_size>>3;
+					break;
+				case FLOAT_TYPE:
+				case DOUBLE_TYPE:
+					if(regs.floats<8) ++regs.floats;
+					else stack++;
+					break;
+				case STRUCT_TYPE:{
+					int isfloat;
+                    int hfasize=hfa_size(L,-1,mt,&isfloat);
+                    if(hfasize>0){
+						if(regs.floats+hfasize<=8)
+							regs.floats +=hfasize;
+						else {
+						    regs.floats=8;
+							stack+=(hfasize*(2-isfloat)+1)>>1;	
+						}
+						break;
+                    }
+                }
+				case UNION_TYPE:{
+					int size=mt->base_size;
+					size=(size+7)>>3;
+					if(size>2){//passed by address
+						if(regs.ints<8)++regs.ints;
+						else stack++;
+					    extra+=size;//extra copy stack;
+						break;
+					}
+					if(mt->is_empty){
+						break; //ignored empty struct
+					}
+					if(mt->align_mask>8){
+						if(regs.ints&1) regs.ints++;
+						else if(stack&1) stack++;
+					}
+					if(regs.ints+size<=8) regs.ints+=size;
+					else{
+						regs.ints=8;
+						stack+=size;
+					} 
+					
+					break;
+				}
+				default:
+					if(regs.ints<8)++regs.ints;//no need to check type support here
+					else stack++;
+			}
+		}
+		lua_pop(L,1);
+	}
+	
+	return (regs.ints||regs.floats)?((stack+extra+17/*16 for regs, 1 for align*/)>>1)<<4:0;//2 eightbytes align
+}
+
+
+void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals,ret_by_addr;
+    const struct ctype* mt;
+	int stack_size,struct_offset;
+    void* p;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    p = push_cdata(L, ct_usr, ct);
+    *(cfunction*) p = func;
+    num_upvals = 1;
+
+    dasm_setup(Dst, build_actionlist);
+
+    reg_info regs={0,0};
+	
+	dasm_put(Dst, 579);
+	
+    /* reserve enough stack space for all of the arguments. */
+	stack_size=caculate_stack(L,ct_usr,nargs);
+	struct_offset=0;
+	if(stack_size>0){
+		if(stack_size>=1<<12){
+			dasm_put(Dst, 586, (unsigned short)(stack_size), (((unsigned int)(stack_size))>>16));
+		}
+		else{
+			dasm_put(Dst, 592, stack_size);
+		}
+		 if (ct->has_var_arg) {
+			dasm_put(Dst, 595, nargs, (unsigned short)("too few arguments"), (((unsigned int)("too few arguments"))>>16), (unsigned short)((unsigned long)("too few arguments")>>32), (unsigned short)((unsigned long)("too few arguments")>>48));
+		}
+		dasm_put(Dst, 618);
+    }
+	
+    for (i = 1,regs.ints=0,regs.floats=0; i <= nargs; i++) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		
+        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE||mt->type==STRUCT_TYPE||mt->type==UNION_TYPE) {
+            lua_getuservalue(L, -1);
+            num_upvals += 2;
+
+			
+			dasm_put(Dst, 620, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16), i);
+			
+            if (mt->pointers || mt->is_reference) {
+                dasm_put(Dst, 635);
+            } else{
+				switch (mt->type) {
+					case FUNCTION_PTR_TYPE: {
+						dasm_put(Dst, 639);
+						break;
+					}
+					case ENUM_TYPE:{
+						dasm_put(Dst, 643);
+						break;
+					} 
+					case STRUCT_TYPE:
+					case UNION_TYPE:{
+						if(mt->is_empty) continue;
+		
+						int isfloat;
+						int hfasize=hfa_size(L,-2,mt,&isfloat);
+						dasm_put(Dst, 647);
+                        if(hfasize>0){
+							switch(hfasize){
+								case 4:
+									if(isfloat){
+										dasm_put(Dst, 651);
+									}else{
+										dasm_put(Dst, 653);
+									}
+									goto ld_hfa;
+								case 3:
+									if(isfloat){
+										dasm_put(Dst, 655);
+									}else{
+										dasm_put(Dst, 657);
+									}
+								case 2:
+									ld_hfa:
+									if(isfloat){
+										dasm_put(Dst, 659);
+									}else{
+										dasm_put(Dst, 661);
+									}
+									break;
+								case 1:
+									if(isfloat){
+										dasm_put(Dst, 663);
+									}else{
+										dasm_put(Dst, 665);
+									}
+									break;
+									
+							}
+							store_float(Dst,&regs,isfloat,hfasize-1);
+							continue;
+						}
+						if(mt->base_size>16){
+							dasm_put(Dst, 667);
+							struct_offset+=(mt->base_size+7)&(~7);
+							if(struct_offset>=1<<12){
+								dasm_put(Dst, 669, (unsigned short)(struct_offset), (((unsigned int)(struct_offset))>>16));
+							}
+							else{
+								dasm_put(Dst, 675, struct_offset);
+							}
+							store_int(Dst,&regs,2);
+							dasm_put(Dst, 678, mt->base_size, (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16), (unsigned short)((unsigned long)(memcpy)>>32), (unsigned short)((unsigned long)(memcpy)>>48));
+						}else{
+							if(mt->align_mask>8){//==15
+								if(regs.ints&1) regs.ints++;
+								else if(regs.ex&1) regs.ex++;
+							}
+							int intSize=(mt->base_size+3)>>2;
+							switch(intSize){
+								case 1:
+									dasm_put(Dst, 690);
+									break;
+								case 2:
+									dasm_put(Dst, 692);
+									break;
+								case 3:
+								case 4:
+								    dasm_put(Dst, 694);
+									break;
+							}
+							store_int(Dst,&regs,intSize);
+						}
+						continue;
+					}	
+				}
+			}
+			goto longstore;
+
+        } else {
+            lua_pop(L, 1);
+            dasm_put(Dst, 696, i);
+
+            switch (mt->type) {
+            case BOOL_TYPE:
+                dasm_put(Dst, 699);
+                goto intstore;
+				
+            case INT8_TYPE:
+            case INT16_TYPE: //arm64 requires callee to narrow the type
+            case INT32_TYPE:
+                
+                dasm_put(Dst, 705);
+                
+ 				goto intstore;
+
+            case INT64_TYPE:
+               
+                dasm_put(Dst, 709);
+               
+              	goto longstore;
+				
+            case INTPTR_TYPE:
+                dasm_put(Dst, 713);
+                
+                goto longstore;
+
+            case DOUBLE_TYPE:
+                dasm_put(Dst, 717);
+                store_float(Dst,&regs,0,0);
+                break;
+
+            case FLOAT_TYPE:
+                dasm_put(Dst, 721);
+                store_float(Dst,&regs,1,0);
+                break;
+			case COMPLEX_DOUBLE_TYPE:
+                dasm_put(Dst, 725);
+				store_float(Dst,&regs,0,1);
+                break;
+
+            case COMPLEX_FLOAT_TYPE:
+                dasm_put(Dst, 729);
+				store_float(Dst,&regs,1,1);
+                break;
+				
+			intstore:
+				store_int(Dst,&regs,1);
+                break;
+			longstore:
+				store_int(Dst,&regs,2);
+                break;
+				
+            default:
+                luaL_error(L, "NYI: call arg type");
+            }
+        }
+    }
+
+    if (ct->has_var_arg) {
+		if(regs.floats<8){
+			dasm_put(Dst, 733, regs.floats<<3, (8-regs.floats), nargs+1);
+		}
+		if(regs.ints<8){
+			dasm_put(Dst, 744, 0x40+(regs.ints<<3), (8-regs.ints), nargs+1);
+		}
+		dasm_put(Dst, 755, (nargs>8?nargs:8), (8-regs.floats), (8-regs.ints), nargs+1);
+		regs.floats=regs.ints=8;
+    }
+	
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE||mt->type==UNION_TYPE)
+				&& mt->base_size>16&& !(mt->type==STRUCT_TYPE&&hfa_size(L,-1,mt,NULL)!=0);
+	if(ret_by_addr){
+		dasm_put(Dst, 772, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+	}
+	
+	//pop all args in registers
+	switch(regs.ints){
+		case 8:
+		case 7:
+            dasm_put(Dst, 786);
+		case 6:
+		case 5:
+            dasm_put(Dst, 788);
+		case 4:
+		case 3:
+            dasm_put(Dst, 790);
+		case 2:
+		case 1:
+			dasm_put(Dst, 792);
+    }
+	
+	switch(regs.floats){
+		case 8:
+		case 7:
+            dasm_put(Dst, 794);
+		case 6:
+		case 5:
+            dasm_put(Dst, 796);
+		case 4:
+		case 3:
+            dasm_put(Dst, 798);
+		case 2:
+		case 1:
+			dasm_put(Dst, 800);
+    }
+	if(regs.ints==8|| regs.floats==8){// fix stack case registers is full
+		dasm_put(Dst, 802);
+	}
+	
+    dasm_put(Dst, 804, (unsigned short)(func), (((unsigned int)(func))>>16), (unsigned short)((unsigned long)(func)>>32), (unsigned short)((unsigned long)(func)>>48));
+
+
+    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
+        lua_getuservalue(L, -1);
+        num_upvals += 2;
+        dasm_put(Dst, 814, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+
+    } else {
+        switch (mt->type) {
+        case INT64_TYPE:
+		#if LUA_VERSION_NUM>=503
+			 lua_pop(L, 1);
+            dasm_put(Dst, 839);
+            break;
+		#endif
+
+        case INTPTR_TYPE:
+            num_upvals++;
+            dasm_put(Dst, 851, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48));
+			break;
+        case VOID_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 873);
+            break;
+
+        case BOOL_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 881);
+            break;
+
+        case INT8_TYPE:// we need to narrow the value before return
+			lua_pop(L, 1);
+            dasm_put(Dst, 893);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 895);
+            } else {
+                dasm_put(Dst, 900);
+            }
+            dasm_put(Dst, 905);
+			break;
+        case INT16_TYPE:// we need to narrow the value before return
+			lua_pop(L, 1);
+            dasm_put(Dst, 913);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 915);
+            } else {
+                dasm_put(Dst, 920);
+            }
+            dasm_put(Dst, 925);
+			break;
+        case INT32_TYPE:
+        case ENUM_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 933);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 935);
+            } else {
+                dasm_put(Dst, 939);
+            }
+            dasm_put(Dst, 943);
+            break;
+
+        case FLOAT_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 951);
+            break;
+
+        case DOUBLE_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 962);
+            break;
+		case COMPLEX_FLOAT_TYPE:
+            lua_getuservalue(L, -1);
+            num_upvals+=2;
+            dasm_put(Dst, 973, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+            break;
+
+        case COMPLEX_DOUBLE_TYPE:
+            lua_getuservalue(L, -1);
+            num_upvals+=2;
+            dasm_put(Dst, 1001, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+            break;
+		case STRUCT_TYPE:
+		case UNION_TYPE:
+			lua_getuservalue(L, -1);
+            num_upvals+=2;
+		    if(ret_by_addr){
+				if(!lua_isnil(L,-1)){
+					dasm_put(Dst, 1027, (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+				}
+				dasm_put(Dst, 1039);
+			}else if(mt->is_empty){
+				dasm_put(Dst, 1047);
+			}else{
+				int isfloat;
+				int hfasize=hfa_size(L,-2,mt,&isfloat);
+				if(hfasize){
+					switch(hfasize){
+						case 4:
+							dasm_put(Dst, 1055);
+							goto hfs_dual;
+						case 3:
+							dasm_put(Dst, 1057);
+						case 2:
+							hfs_dual:
+							dasm_put(Dst, 1059);
+						case 1:
+							dasm_put(Dst, 1061);
+							break;
+					}
+				}else{
+					if(mt->base_size>8){
+						dasm_put(Dst, 1063);
+					}
+					dasm_put(Dst, 1065);
+					
+				} 
+				dasm_put(Dst, 1067, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)((unsigned long)(mt)>>32), (unsigned short)((unsigned long)(mt)>>48), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+				if(hfasize){
+					switch(hfasize){
+						case 4:
+							dasm_put(Dst, 1083);
+							if(isfloat){
+								dasm_put(Dst, 1085);
+							}else{
+								dasm_put(Dst, 1087);
+							} 
+							goto hfl_dual;
+						case 3:
+							dasm_put(Dst, 1089);
+							if(isfloat){
+								dasm_put(Dst, 1091);
+							}else{
+								dasm_put(Dst, 1093);
+							}
+						case 2:
+							hfl_dual:
+							if(isfloat){
+								dasm_put(Dst, 1095);
+							}else{
+								dasm_put(Dst, 1098);
+							}
+						case 1:
+							if(isfloat){
+								dasm_put(Dst, 1100);
+							}else{
+								dasm_put(Dst, 1103);
+							}
+							break;
+					}
+				}else{
+					if(mt->base_size>8){
+						dasm_put(Dst, 1105);
+					}
+					dasm_put(Dst, 1107);
+					
+				} 
+				dasm_put(Dst, 1109);
+			}
+			break;	
+		
+        default:
+            luaL_error(L, "NYI: call return type");
+        }
+    }
+
+    assert(lua_gettop(L) == top + num_upvals);
+	{
+        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
+        /* add a callback as an upval so that the jitted code gets cleaned up when
+         * the function gets gc'd */
+        push_callback(L, f, func);
+        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
+    }
+}
+
diff --git a/source/texk/web2c/luatexdir/luaffi/call_arm_hf.h b/source/texk/web2c/luatexdir/luaffi/call_arm_hf.h
index 00c2c09a7..b9fec4d53 100644
--- a/source/texk/web2c/luatexdir/luaffi/call_arm_hf.h
+++ b/source/texk/web2c/luatexdir/luaffi/call_arm_hf.h
@@ -1,2530 +1,2530 @@
-/*
-** This file has been pre-processed with DynASM.
-** http://luajit.org/dynasm.html
-** DynASM version 1.4.0, DynASM arm version 1.4.0
-** DO NOT EDIT! The original file is in "call_arm.dasc".
-*/
-
-/* vim: ts=4 sw=4 sts=4 et tw=78
- * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
- * Portions copyright (c) 2011 James R. McKaskill.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
- 
-//The generate code is for arm not for thumb
-#if DASM_VERSION != 10400
-#error "Version mismatch between DynASM and included encoding engine"
-#endif
-
-static const unsigned int build_actionlist[951] = {
-0xed0d0a00,
-0x000f8100,
-0x00000000,
-0xed4d0a00,
-0x000f8100,
-0x00000000,
-0xed0d1a00,
-0x000f8100,
-0x00000000,
-0xed4d1a00,
-0x000f8100,
-0x00000000,
-0xed0d2a00,
-0x000f8100,
-0x00000000,
-0xed4d2a00,
-0x000f8100,
-0x00000000,
-0xed0d3a00,
-0x000f8100,
-0x00000000,
-0xed4d3a00,
-0x000f8100,
-0x00000000,
-0xed0d4a00,
-0x000f8100,
-0x00000000,
-0xed4d4a00,
-0x000f8100,
-0x00000000,
-0xed0d5a00,
-0x000f8100,
-0x00000000,
-0xed4d5a00,
-0x000f8100,
-0x00000000,
-0xed0d6a00,
-0x000f8100,
-0x00000000,
-0xed4d6a00,
-0x000f8100,
-0x00000000,
-0xed0d7a00,
-0x000f8100,
-0x00000000,
-0xed4d7a00,
-0x000f8100,
-0x00000000,
-0xed0d0b00,
-0x000f8100,
-0x00000000,
-0xed0d1b00,
-0x000f8100,
-0x00000000,
-0xed0d2b00,
-0x000f8100,
-0x00000000,
-0xed0d3b00,
-0x000f8100,
-0x00000000,
-0xed0d4b00,
-0x000f8100,
-0x00000000,
-0xed0d5b00,
-0x000f8100,
-0x00000000,
-0xed0d6b00,
-0x000f8100,
-0x00000000,
-0xed0d7b00,
-0x000f8100,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c100e,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c100e,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c0006,
-0x00000000,
-0xe51d1000,
-0x000e8180,
-0x00000000,
-0xe2866000,
-0x000b0000,
-0x00000000,
-0xe8b6100e,
-0x00000000,
-0xe8b60006,
-0x00000000,
-0xe4961004,
-0x00000000,
-0xed1d0a00,
-0x000f8100,
-0x00000000,
-0xed1d0b00,
-0x000f8100,
-0x00000000,
-0xed160a00,
-0xe2866004,
-0x00000000,
-0xe2866000,
-0x000b0000,
-0x00000000,
-0xed160b00,
-0xe2866008,
-0x00000000,
-0xe1a0c00d,
-0xe92d000f,
-0x00000000,
-0xe24dd040,
-0x00000000,
-0xe92d5050,
-0xe1a0600c,
-0xe3004000,
-0x000c0200,
-0xe3404000,
-0x000c0200,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe5801000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe8a0100e,
-0x00000000,
-0xe880100e,
-0x00000000,
-0xe8a0100e,
-0x00000000,
-0xe8800006,
-0x00000000,
-0xe880100e,
-0x00000000,
-0xe880000e,
-0x00000000,
-0xe8800006,
-0x00000000,
-0xe5801000,
-0x00000000,
-0xe5801000,
-0x00000000,
-0xe28d1000,
-0x000b0000,
-0x00000000,
-0xe1a01006,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe12fff3c,
-0x00000000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe880100e,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe8800006,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c000c,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe8b6000c,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030003,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe8800006,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xe5801000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030002,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030004,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030005,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030006,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe89c000c,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe8b6000c,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030007,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3a01000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030008,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3e02000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030009,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3e02000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003000a,
-0xe1a06000,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0x00000000,
-0xec960b08,
-0x00000000,
-0xec960b06,
-0x00000000,
-0xec960b04,
-0x00000000,
-0xec960a04,
-0x00000000,
-0xed160b00,
-0x00000000,
-0xed160a00,
-0x00000000,
-0xe5960000,
-0x00000000,
-0xe51d0000,
-0x000e8180,
-0xe1a01006,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe12fff3c,
-0x00000000,
-0xe3a02000,
-0x000b0000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x00030000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3e02000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003000c,
-0x00000000,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0x00000000,
-0xe3e01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000d,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe3500000,
-0x13a00001,
-0x00000000,
-0xe6ef0070,
-0x00000000,
-0xe6af0070,
-0x00000000,
-0xe6ff0070,
-0x00000000,
-0xe6bf0070,
-0x00000000,
-0xe3e01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000f,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030010,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030011,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030012,
-0x00000000,
-0xee106a10,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0xee006a10,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030013,
-0x00000000,
-0xe1a00004,
-0xec564b10,
-0xe3e01002,
-0xeb000000,
-0x0003000b,
-0xec464b10,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030014,
-0xed2d0b04,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0xecbd0b04,
-0x00000000,
-0xe3e01000,
-0xe1a00004,
-0xeb000000,
-0x00030015,
-0xed2d0a02,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0xecbd0a02,
-0x00000000,
-0xe1a06000,
-0xe3e01002,
-0xe1a00004,
-0xeb000000,
-0x0003000b,
-0xe1a00006,
-0x00000000,
-0xe1a06000,
-0xe1a00004,
-0xe1a04001,
-0xe3e01002,
-0xeb000000,
-0x0003000b,
-0xe1a00006,
-0xe1a01004,
-0x00000000,
-0xe89da050,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe8a60003,
-0x00000000,
-0xe28dc000,
-0x000b0000,
-0xe88c0003,
-0x00000000,
-0xe4860004,
-0x00000000,
-0xe50d0000,
-0x000e8180,
-0x00000000,
-0xed0d3b00,
-0x000f8100,
-0x00000000,
-0xed0d2b00,
-0x000f8100,
-0x00000000,
-0xed0d1b00,
-0x000f8100,
-0x00000000,
-0xed4d1a00,
-0x000f8100,
-0x00000000,
-0xed0d0b00,
-0x000f8100,
-0x00000000,
-0xed0d0a00,
-0x000f8100,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xeca60a01,
-0x00000000,
-0xeca60b02,
-0x00000000,
-0xeca60a04,
-0x00000000,
-0xeca60b04,
-0x00000000,
-0xeca60b06,
-0x00000000,
-0xeca60b08,
-0x00000000,
-0xe92d40f0,
-0xe28d700c,
-0x00000000,
-0xe92d4870,
-0xe28db00c,
-0x00000000,
-0xe24dd004,
-0x00000000,
-0xe1a04000,
-0x00000000,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe04dd00c,
-0x00000000,
-0xe24dd000,
-0x000b0000,
-0x00000000,
-0xeb000000,
-0x00030016,
-0xe3500000,
-0x000b0000,
-0xaa000000,
-0x00050001,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030017,
-0x0006000b,
-0xe1a05000,
-0xe04dd185,
-0x00000000,
-0xe28d6000,
-0x000b0000,
-0x00000000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe50d0000,
-0x000e8180,
-0x00000000,
-0xe3003000,
-0x000c0200,
-0xe3403000,
-0x000c0200,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0x000b0000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030009,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030018,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000c,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000a,
-0x00000000,
-0xec900b0a,
-0x00000000,
-0xec900b0a,
-0x00000000,
-0xec900b06,
-0x00000000,
-0xec900a04,
-0x00000000,
-0xed100b00,
-0x00000000,
-0xed100a00,
-0x00000000,
-0xe2866004,
-0x00000000,
-0xe1a01000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0x00000000,
-0xe28d0000,
-0x000b0000,
-0x00000000,
-0xe1a00006,
-0x00000000,
-0xe12fff3c,
-0x00000000,
-0xe2866000,
-0x000b0000,
-0x00000000,
-0xe3a01000,
-0x000b0000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0xe3500000,
-0x13a00001,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe6ef0070,
-0x00000000,
-0xe6af0070,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe6ff0070,
-0x00000000,
-0xe6bf0070,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000d,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000e,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030011,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003000f,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030010,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030013,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030012,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030014,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030015,
-0x00000000,
-0xe3a01000,
-0x000b0000,
-0x00000000,
-0xe28d2000,
-0x000b0000,
-0xe28d3000,
-0x000b0000,
-0xe1a00004,
-0xeb000000,
-0x00030019,
-0xe2801000,
-0x000b0000,
-0x00000000,
-0xe1a03006,
-0x00000000,
-0xe28d3000,
-0x000b0000,
-0x00000000,
-0xe1a02005,
-0xe1a00004,
-0xeb000000,
-0x0003001a,
-0x00000000,
-0xec9d0b10,
-0x00000000,
-0xec9d0b0e,
-0x00000000,
-0xec9d0b0c,
-0x00000000,
-0xec9d0b0a,
-0x00000000,
-0xec9d0b08,
-0x00000000,
-0xec9d0b06,
-0x00000000,
-0xec9d0b04,
-0x00000000,
-0xed1d0b00,
-0x00000000,
-0xe28dd040,
-0x00000000,
-0xe8bd000f,
-0x00000000,
-0xe8bd0003,
-0x00000000,
-0xe28dd008,
-0x00000000,
-0xe28dd010,
-0x00000000,
-0xe300c000,
-0x000c0200,
-0xe340c000,
-0x000c0200,
-0xe12fff3c,
-0x00000000,
-0xe1a06000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0xe3a00001,
-0x00000000,
-0xe1a03001,
-0xe1a02000,
-0x00000000,
-0xe1a02001,
-0xe1a01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030003,
-0xe3a00001,
-0x00000000,
-0xe1a06000,
-0xe1a05001,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0xe5805004,
-0xe3a00001,
-0x00000000,
-0xe1a06000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3a01000,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0xe3a00001,
-0x00000000,
-0xe3a00000,
-0x00000000,
-0xe1a01000,
-0xe1a00004,
-0xeb000000,
-0x00030004,
-0xe3a00001,
-0x00000000,
-0xe1a01000,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x0003001b,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030005,
-0x00000000,
-0xe3a00001,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030006,
-0xe3a00001,
-0x00000000,
-0xe1a00004,
-0xeb000000,
-0x00030007,
-0xe3a00001,
-0x00000000,
-0xed2d0b08,
-0x00000000,
-0xed2d0b06,
-0x00000000,
-0xed2d0b04,
-0x00000000,
-0xed2d0b02,
-0x00000000,
-0xe1a06000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0x00000000,
-0xecbd0b08,
-0xec800b08,
-0x00000000,
-0xecbd0b06,
-0xec800b06,
-0x00000000,
-0xecbd0b04,
-0xec800b04,
-0x00000000,
-0xecbd0b04,
-0xec800a04,
-0x00000000,
-0xecbd0b02,
-0xed000b00,
-0x00000000,
-0xecbd0b02,
-0xed000a00,
-0x00000000,
-0xe3a00001,
-0x00000000,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x0003001c,
-0xe3e01001,
-0xe1a00004,
-0xeb000000,
-0x0003001d,
-0x00000000,
-0xe3a00000,
-0x00000000,
-0xe1a06000,
-0xe3002000,
-0x000c0200,
-0xe3402000,
-0x000c0200,
-0xe3001000,
-0x000c0200,
-0xe3401000,
-0x000c0200,
-0xe1a00004,
-0xeb000000,
-0x00030001,
-0xe5806000,
-0x00000000,
-0xe3a00001,
-0x00000000,
-0xe247d00c,
-0xe8bd80f0,
-0x00000000,
-0xe24bd00c,
-0xe8bd8870,
-0x00000000
-};
-
-static const char *const globnames[] = {
-  (const char *)0
-};
-static const char *const extnames[] = {
-  "rawgeti",
-  "push_cdata",
-  "lua_remove",
-  "lua_pushinteger",
-  "lua_pushboolean",
-  "push_int",
-  "push_float",
-  "lua_pushnumber",
-  "lua_call",
-  "check_typed_pointer",
-  "check_struct",
-  "lua_settop",
-  "check_enum",
-  "check_uint32",
-  "check_int32",
-  "check_uint64",
-  "check_int64",
-  "check_uintptr",
-  "check_float",
-  "check_double",
-  "check_complex_double",
-  "check_complex_float",
-  "lua_gettop",
-  "luaL_error",
-  "check_typed_cfunction",
-  "unpack_varargs_bound",
-  "unpack_varargs_stack",
-  "push_uint",
-  "lua_pushvalue",
-  "lua_setuservalue",
-  (const char *)0
-};
-
-#define JUMP_SIZE 8
-
-#define MIN_BRANCH ((INT32_MIN) >> 8)
-#define MAX_BRANCH ((INT32_MAX) >> 8)
-//arm pc offset 8 so comparing with next instruction is 4,
-//unlike x86 which pass in the current instruction address+1 rather than the next instruction 
-#define BRANCH_OFF 4	
-
-
-#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
-#ifdef TARGET_OS_IPHONE
-#define  CK_ALGIN  0
-#else
-#define  CK_ALGIN  1
-#endif
-#define ALIGNED(x, align) (!CK_ALGIN||((int)(x) & (align - 1)) == 0)
-#if defined(__ARM_PCS_VFP) || (GCC_VERSION==40500||defined(__clang__))&&!defined(__ARM_PCS) && !defined(__SOFTFP__) && !defined(__SOFTFP) && \
-    defined(__VFP_FP__)
-#define ARM_HF 1
-#else
-#define ARM_HF 0
-#endif
-#if ARM_HF&&!CK_ALGIN
-#error "Unsupported unaligned stack for hard floating point"
-#endif	
-
-static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
-{
-    /* The jump code is the function pointer followed by a stub to call the
-     * function pointer. The stub exists so we can jump to functions with an
-     * offset greater than 32MB.
-     *
-     * Note we have to manually set this up since there are commands buffered
-     * in the jit state.
-     */
-	
-    *(cfunction*) code = func;
-     //ldr pc, [pc - 12]
-    *(uint32_t*) &code[4] = 0xE51FF00CU; 
-	
-}
-
-
-
-
-void compile_globals(struct jit* jit, lua_State* L)
-{
-    (void) jit;
-}
-
-typedef struct stack_info{
-	int extra;
-	int int_off;
-	int stack_off;
-	int float_size;
-#if ARM_HF
-	int float_off; 
-#endif	
-} stack_info;
-//vfp use back-filling rule for registers until a float value on stack
-typedef struct reg_info{
-	uint16_t exs;	
-	union{
-		uint8_t ints;
-		uint8_t regs;
-	};
-#if ARM_HF
-	uint8_t float_sealed;
-	short floats;//each bit is a float: s0-s15 or v0-v7 or q0-q3
-	uint8_t left_single;
-	uint8_t highest_bit;
-#endif
-} reg_info;
-
-#define MAX_REGS 4
-#define MAX_FLOAT_REGS 16
-#ifndef bool
-#define bool uint8_t
-#endif
-
-#define has_bit(x,b) (((x)&(1<<(b)))!=0)
-#define set_bit(x,b) (x=((x)|(1<<(b)))) 
-#define FIX_ALIGN(x,al) \
-	if(!ALIGNED((x),al)){\
-		x=ROUND_UP(x,al);\
-	}
-static ALWAYS_INLINE bool is_float_sealed(reg_info* regs){
-#if ARM_HF
-return regs->float_sealed;
-#else
-return regs->regs>=MAX_REGS;
-#endif
-}
-//return size need to put on stack
-static ALWAYS_INLINE int add_int_reg(reg_info* regs){
-	if(regs->regs<MAX_REGS){
-		regs->regs++;
-		return 0;
-	}
-	return 1;
-		
-}
-//return size need to put on stack
-static ALWAYS_INLINE int add_int64_reg(reg_info* regs){
-	if(regs->regs<MAX_REGS-1){
-		regs->regs=ROUND_UP(regs->regs,2)+2;
-		return 0;
-	}else if(regs->regs==MAX_REGS-1){
-		regs->regs=MAX_REGS;
-	}
-		
-	return 2;
-}
-static ALWAYS_INLINE bool is_float_type(int t){
-    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
-}
-static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
-	struct ctype* mt;
-	int type,ele_count,i,ct_usr;
-	lua_getuservalue(L,idx);
-	ct_usr=lua_absindex(L,-1);
-    lua_rawgeti(L,ct_usr,1);
-    mt=(struct ctype*)lua_touserdata(L,-1);
-    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-        lua_pop(L,2);
-		if(ct->type==COMPLEX_DOUBLE_TYPE){
-			if(isfloat) *isfloat=0;
-			return 4;
-		}else if(ct->type==COMPLEX_FLOAT_TYPE){
-			if(isfloat) *isfloat=1;
-			return 2;
-		}
-        return 0;
-    }
-	type=mt->type;
-    ele_count=(int)(ct->base_size/mt->base_size);
-    if(ele_count>4||ct->base_size%mt->base_size){
-        lua_pop(L,2);
-        return 0;
-    }
-	lua_pop(L,1);
-    for (i = 2; i <=4 ; ++i) {
-        lua_rawgeti(L,ct_usr,i);
-		if(lua_isnil(L,-1)){//case have array member;
-            lua_pop(L,1);
-            break;
-        }
-        mt=(struct ctype*)lua_touserdata(L,-1);
-        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
-            lua_pop(L,2);
-            return 0;
-        }
-        lua_pop(L,1);
-    }
-	if(isfloat){
-		*isfloat=mt->type==FLOAT_TYPE;
-	}
-	lua_pop(L,1);
-    return ele_count*(mt->type==FLOAT_TYPE?1:2);
-}
-#if ARM_HF
-static void save_float_reg(struct jit* Dst,int reg,int size,stack_info* st){
-	int sz;
-	if(reg==-1) return;
-	for(;size>0;size-=8){
-		sz=size>8?8:size;
-		switch(sz){
-		case 4:
-			switch(reg){
-				case 0:
-					dasm_put(Dst, 0, st->float_size);
-					break;
-				case 1:
-					dasm_put(Dst, 3, st->float_size);
-					break;
-				case 2:
-					dasm_put(Dst, 6, st->float_size);
-					break;
-				case 3:
-					dasm_put(Dst, 9, st->float_size);
-					break;
-				case 4:
-					dasm_put(Dst, 12, st->float_size);
-					break;
-				case 5:
-					dasm_put(Dst, 15, st->float_size);
-					break;
-				case 6:
-					dasm_put(Dst, 18, st->float_size);
-					break;
-				case 7:
-					dasm_put(Dst, 21, st->float_size);
-					break;
-				case 8:
-					dasm_put(Dst, 24, st->float_size);
-					break;
-				case 9:
-					dasm_put(Dst, 27, st->float_size);
-					break;
-				case 10:
-					dasm_put(Dst, 30, st->float_size);
-					break;
-				case 11:
-					dasm_put(Dst, 33, st->float_size);
-					break;
-				case 12:
-					dasm_put(Dst, 36, st->float_size);
-					break;
-				case 13:
-					dasm_put(Dst, 39, st->float_size);
-					break;
-				case 14:
-					dasm_put(Dst, 42, st->float_size);
-					break;
-				case 15:
-					dasm_put(Dst, 45, st->float_size);
-					break;
-			}
-			break;
-		case 8:
-			switch(reg>>1){
-				case 0:
-					dasm_put(Dst, 48, st->float_size);
-					break;
-				case 1:
-					dasm_put(Dst, 51, st->float_size);
-					break;
-				case 2:
-					dasm_put(Dst, 54, st->float_size);
-					break;
-				case 3:
-					dasm_put(Dst, 57, st->float_size);
-					break;
-				case 4:
-					dasm_put(Dst, 60, st->float_size);
-					break;
-				case 5:
-					dasm_put(Dst, 63, st->float_size);
-					break;
-				case 6:
-					dasm_put(Dst, 66, st->float_size);
-					break;
-				case 7:
-					dasm_put(Dst, 69, st->float_size);
-					break;
-			}
-			reg+=2;
-			break;
-		}
-		st->float_size+=sz;
-	}
-}
-
-//128 bit vector type is not supported by this
-static int add_float_reg(reg_info* regs,int sz,int isfloat){
-
-	if(is_float_sealed(regs)) return -1;
-	int i,ret=-1;
-	if(sz==1){
-		if(regs->left_single){
-			int n=regs->highest_bit;
-			for(i=0;i<n;++i){
-				if(!has_bit(regs->floats,i)){
-					regs->left_single--;
-					set_bit(regs->floats,i);
-					ret=i;
-				}
-			}
-		}else{
-			ret=regs->highest_bit;
-			set_bit(regs->floats,regs->highest_bit);
-			++regs->highest_bit;
-		}
-	}else{
-		if(regs->highest_bit>MAX_FLOAT_REGS-sz){
-			regs->highest_bit=MAX_FLOAT_REGS;
-		}else{
-			if(!isfloat&&!ALIGNED(regs->highest_bit, 2)){
-				regs->highest_bit++;
-				regs->left_single++;
-			}
-			ret=regs->highest_bit;
-			for(i=0;i<sz;++i){
-				set_bit(regs->floats,regs->highest_bit++);
-			}
-		}
-	}
-	if(regs->highest_bit==MAX_FLOAT_REGS){
-		regs->float_sealed=true;		
-	}
-	return ret;
-}
-#endif
-static void load_reg(struct jit* Dst,int off,int size){
-	if(size==16){
-		dasm_put(Dst, 72, off);
-	}else if(size==12){
-		dasm_put(Dst, 76, off);
-	}else if(size==8){
-		dasm_put(Dst, 80, off);
-	}else{
-		dasm_put(Dst, 84, off);
-	}
-}
-// arm store/load range for immediate value is only -256-255
-static void load_stack(struct jit* Dst,stack_info* st,int size,int align){
-	int off=st->stack_off;
-	FIX_ALIGN(st->stack_off,align);
-	if((off=st->stack_off-off)){
-		dasm_put(Dst, 87, off);
-	}
-	if(size==16){
-		dasm_put(Dst, 90);
-	}else if(size==8){
-		dasm_put(Dst, 92);
-	}else{
-		dasm_put(Dst, 94);
-	}
-	st->stack_off+=size;
-}
-
-static void load_int(struct jit* Dst,stack_info* st,int size,int align){
-	FIX_ALIGN(st->int_off,align);
-	if(st->int_off<0x40*ARM_HF+MAX_REGS*4&&(!st->stack_off||MAX_REGS*4+size<=0x40*ARM_HF+MAX_REGS*4)){
-		load_reg(Dst,st->int_off+st->extra,size);
-		st->int_off+=size;
-	}else{
-		st->int_off=0x40*ARM_HF+MAX_REGS*4;
-		load_stack(Dst,st,size,align);
-	}
-	
-}
-
-static void load_float(struct jit* Dst,stack_info* st,int size,int vfp,int align){
-	#if ARM_HF
-	if(st->float_off<st->float_size){
-		if(vfp){
-			if(size==4){//float
-				dasm_put(Dst, 96, st->float_off+st->extra);
-			}else if(size==8){//double
-				dasm_put(Dst, 99, st->float_off+st->extra);
-			}
-		}else load_reg(Dst,st->float_off+st->extra,size);
-		st->float_off+=size;
-	}else if(vfp){
-		if(size==4){//float
-			dasm_put(Dst, 102);
-		}else if(size==8){//double
-			int off=st->stack_off;
-			FIX_ALIGN(st->stack_off,align);
-			if((off=st->stack_off-off)){
-				dasm_put(Dst, 105, off);
-			}
-			dasm_put(Dst, 108);
-		}
-	}else{
-		load_stack(Dst,st,size,align);
-	}
-	#else	
-		load_int(Dst,st,size,align);
-	#endif
-}
-#if ARM_HF
-static void push_regs(lua_State* L,struct jit* Dst,int ct_usr,int nargs,stack_info* st){
-	const struct ctype* mt;
-	reg_info regs;int i;
-	memset(&regs,0,sizeof(reg_info));
-    for (i = 1; i <= nargs&&!is_float_sealed(&regs); ++i){
-		lua_rawgeti(L, ct_usr, i);
-		mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (!mt->pointers &&! mt->is_reference) {
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,4,0),16,st);
-					break;
-				case DOUBLE_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,2,0),8,st);
-					break;
-				case COMPLEX_FLOAT_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,2,1),8,st);
-					break;
-				case FLOAT_TYPE:
-					save_float_reg(Dst,add_float_reg(&regs,1,1),4,st);
-					break;
-				case STRUCT_TYPE:
-					{
-						int isfloat,hfasize=hfa_size(L,-1,mt,&isfloat);
-						if(hfasize){
-							save_float_reg(Dst,add_float_reg(&regs,hfasize,isfloat),4*hfasize,st);
-							break;
-						}
-					}
-				case UNION_TYPE:
-					break;
-				case INT64_TYPE:
-					//add_int64_reg(&regs);
-					break;
-				default:
-					//add_int_reg(&regs);//no need to check type support here
-					break;
-			}
-		}
-		lua_pop(L,1);
-	}
-	st->float_off+=st->int_off;
-	st->int_off+=0x40;
-}
-#endif
-cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals, ref;
-    const struct ctype* mt;
-	stack_info st;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    fidx = lua_absindex(L, fidx);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    dasm_setup(Dst, build_actionlist);
-
-    lua_newtable(L);
-    lua_pushvalue(L, -1);
-    ref = luaL_ref(L, LUA_REGISTRYINDEX);
-    num_upvals = 0;
-
-    if (ct->has_var_arg) {
-        luaL_error(L, "can't create callbacks with varargs");
-    }
-	memset(&st,0,sizeof(stack_info));
-	st.extra=0x10;
-    /* prolog and get the upval table */
-	dasm_put(Dst, 111);
-#if ARM_HF
-	dasm_put(Dst, 114);
-	push_regs(L,Dst,ct_usr,nargs,&st);
-#endif	
-    
-    dasm_put(Dst, 116, (unsigned short)(L), (((unsigned int)(L))>>16), (unsigned short)(ref), (((unsigned int)(ref))>>16), (unsigned short)(LUA_REGISTRYINDEX), (((unsigned int)(LUA_REGISTRYINDEX))>>16));
-	
-    /* get the lua function */
-    lua_pushvalue(L, fidx);
-    lua_rawseti(L, -2, ++num_upvals);
-	
-	
-    dasm_put(Dst, 134, num_upvals);
-
-	// Complex type is return in the address stored in r0 for softfp
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	if(!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
-	(!1&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(1&&hfa_size(L,-1,mt,NULL))){
-		st.int_off+=4;
-	} 
-	lua_pop(L,1);
-
-	//whether 64 bit type requires 8 bytes alignment in stack is defined by compiler.android compiler reqiures only 4 byte alignment;
-	//actually the stack it self may reqiures 8 bytes alignment
-    for (i = 1; i <= nargs; i++) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-
-        if (mt->pointers || mt->is_reference) {
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-			
-            dasm_put(Dst, 141, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-            load_int(Dst,&st,4,4);
-            dasm_put(Dst, 157);
-        } else {
-            switch (mt->type) {
-			case STRUCT_TYPE:
-			case UNION_TYPE:{
-				#if ARM_HF
-				int isfloat,hfasize=0;
-				if(mt->type!=UNION_TYPE){
-					hfasize=hfa_size(L,-1,mt,&isfloat);
-				}
-				#endif
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-                dasm_put(Dst, 163, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-				#if ARM_HF
-				if(hfasize){
-					if(hfasize<=4)load_float(Dst,&st,4*hfasize,0,4*(2-isfloat));
-					switch(hfasize){
-						case 8:
-							load_float(Dst,&st,16,0,8);
-							dasm_put(Dst, 179);
-							load_float(Dst,&st,16,0,8);
-							dasm_put(Dst, 181);
-							break;
-						case 6:
-							load_float(Dst,&st,16,0,8);
-							dasm_put(Dst, 183);
-							load_float(Dst,&st,8,0,8);
-							dasm_put(Dst, 185);
-							break;
-						case 4:
-							dasm_put(Dst, 187);
-							break;
-						case 3:
-							dasm_put(Dst, 189);
-							break;
-						case 2:
-							dasm_put(Dst, 191);
-							break;
-						case 1:
-							dasm_put(Dst, 193);
-							break;
-					}
-				}else
-				#endif
-				if(!mt->is_empty){
-					int size=mt->base_size;
-					if(size<=4){
-						load_int(Dst,&st,4,4);
-						dasm_put(Dst, 195);
-					}else{
-						size=ROUND_UP(size,4);
-						if(mt->align_mask>4){//8 byte max alignment
-							if(st.int_off<0x40*ARM_HF+MAX_REGS*4){FIX_ALIGN(st.int_off,8);} 
-							else {FIX_ALIGN(st.stack_off,8);}
-						}
-						
-						if(st.int_off<0x40*ARM_HF+MAX_REGS*4&&(!st.stack_off||st.int_off+size<=0x40*ARM_HF+MAX_REGS*4)){//to ensure consective memory for the struct
-							dasm_put(Dst, 197, st.int_off+st.extra);
-							st.int_off+=size;
-						}else{
-							st.int_off=0x40*ARM_HF+MAX_REGS*4;
-							dasm_put(Dst, 200);
-							st.stack_off+=size;
-						}
-						dasm_put(Dst, 202, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
-					}
-				}
-                dasm_put(Dst, 212);
-				break;
-			}
-				
-			case COMPLEX_DOUBLE_TYPE:
-				
-				lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-                dasm_put(Dst, 217, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-                load_float(Dst,&st,16,0,8);
-                dasm_put(Dst, 233);
-				break;
-			case COMPLEX_FLOAT_TYPE:
-                lua_getuservalue(L, -1);
-				lua_rawseti(L, -3, ++num_upvals); /* usr value */
-				lua_rawseti(L, -2, ++num_upvals); /* mt */
-                dasm_put(Dst, 239, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-				load_float(Dst,&st,8,0,4);
-                dasm_put(Dst, 255);
-				break;
-            case INT64_TYPE:
-				
-			#if LUA_VERSION_NUM>=503
-                lua_pop(L, 1);
-				
-            #if CK_ALGIN
-				FIX_ALIGN(st.int_off,8);
-				if(st.int_off<16){
-					dasm_put(Dst, 261, st.int_off+st.extra);
-					st.int_off+=8;
-				}else{
-					if(!ALIGNED(st.stack_off,8)){
-						st.stack_off+=4;
-						dasm_put(Dst, 265);
-					}
-					dasm_put(Dst, 267);
-					st.stack_off+=8;
-				}
-			#else
-				load_int(Dst,st,8,8);
-			#endif
-                dasm_put(Dst, 269);
-			#else
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 273, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-                load_int(Dst,&st,8,8);
-                dasm_put(Dst, 282);
-			#endif
-                break;
-
-            case INTPTR_TYPE:
-                lua_rawseti(L, -2, ++num_upvals); /* mt */
-				
-                dasm_put(Dst, 288, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-                load_int(Dst,&st,4,4);
-                dasm_put(Dst, 297);
-				
-                break;
-
-            case BOOL_TYPE:
-                lua_pop(L, 1);
-				
-                load_int(Dst,&st,4,4);
-                dasm_put(Dst, 303);
-                break;
-
-            case INT8_TYPE: // no need to narrow cause narrowed by caller
-            case INT16_TYPE: // no need to narrow cause narrowed by caller
-            case ENUM_TYPE:
-            case INT32_TYPE:
-                lua_pop(L, 1);
-				
-                load_int(Dst,&st,4,4);
-                dasm_put(Dst, 307);
-                break;
-
-            case FLOAT_TYPE:
-                lua_pop(L, 1);
-                
-                load_float(Dst,&st,4,ARM_HF,4);
-                dasm_put(Dst, 311);
-                break;
-
-            case DOUBLE_TYPE:
-                lua_pop(L, 1);
-				
-				#if ARM_HF
-				load_float(Dst,&st,8,ARM_HF,8);
-				#elif CK_ALGIN
-				FIX_ALIGN(st.int_off,8);
-				if(st.int_off<16){
-					dasm_put(Dst, 315, st.int_off+st.extra);
-					st.int_off+=8;
-				}else{
-					if(!ALIGNED(st.stack_off,8)){
-						st.stack_off+=4;
-						dasm_put(Dst, 319);
-					}
-					dasm_put(Dst, 321);
-					st.stack_off+=8;
-				}
-				#else
-				load_float(Dst,&st,8,ARM_HF,8);
-				#endif	
-                dasm_put(Dst, 323);
-                break;
-				
-            default:
-                luaL_error(L, "NYI: callback arg type");
-            }
-        }
-    }
-
-    lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-
-    dasm_put(Dst, 327, ((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0), nargs);
-    
-
-    if (mt->pointers || mt->is_reference) {
-        lua_getuservalue(L, -1);
-        lua_rawseti(L, -3, ++num_upvals); /* usr value */
-        lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-        dasm_put(Dst, 335, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-        goto single_no_pop;
-    } else {
-        switch (mt->type) {
-		case STRUCT_TYPE:
-		case UNION_TYPE:{
-			int isfloat,hfasize=0;
-			if(mt->type!=UNION_TYPE){
-				hfasize=hfa_size(L,-1,mt,&isfloat);
-			}
-			lua_getuservalue(L, -1);
-			lua_rawseti(L, -3, ++num_upvals); /* usr value */
-			lua_rawseti(L, -2, ++num_upvals); /* mt */
-            dasm_put(Dst, 351, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-			#if ARM_HF
-			if(hfasize>0){
-				switch(hfasize){
-					case 8:
-						dasm_put(Dst, 372);
-						break;
-					case 6:
-						dasm_put(Dst, 374);
-						break;
-					case 4:
-						dasm_put(Dst, 376);
-						break;
-					case 3:
-						dasm_put(Dst, 378);
-						break;
-					case 2:
-						dasm_put(Dst, 380);
-						break;
-					case 1:
-						dasm_put(Dst, 382);
-						break;	
-				}
-			}else
-			#endif
-			if(!mt->is_empty){
-				if(mt->base_size<=4){
-					dasm_put(Dst, 384);
-				}else{
-					dasm_put(Dst, 386, st.extra+0x40*1, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
-				}
-			}
-			break;
-		}	
-        case ENUM_TYPE:
-            lua_getuservalue(L, -1);
-            lua_rawseti(L, -3, ++num_upvals); /* usr value */
-            lua_rawseti(L, -2, ++num_upvals); /* mt */
-
-            dasm_put(Dst, 399, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-
-            goto single_no_pop;
-
-        case VOID_TYPE:
-            dasm_put(Dst, 415);
-            lua_pop(L, 1);
-            break;
-
-        case BOOL_TYPE:
-        case INT8_TYPE:// narrow it 
-        case INT16_TYPE:// narrow it 
-        case INT32_TYPE:
-		    dasm_put(Dst, 420);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 422);
-            } else {
-                dasm_put(Dst, 426);
-            }
-			switch(mt->type){
-				case BOOL_TYPE:
-					dasm_put(Dst, 430);
-					break;
-				case INT8_TYPE:
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 433);
-					} else {
-						dasm_put(Dst, 435);
-					}
-					break;
-				case INT16_TYPE:
-					if (mt->is_unsigned) {
-						dasm_put(Dst, 437);
-					} else {
-						dasm_put(Dst, 439);
-					}
-					break;
-			}
-            goto single;
-
-        case INT64_TYPE:
-            dasm_put(Dst, 441);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 443);
-            } else {
-                dasm_put(Dst, 447);
-            }
-            goto dual;
-
-        case INTPTR_TYPE:
-            dasm_put(Dst, 451);
-            goto single;
-
-        case FLOAT_TYPE:
-            dasm_put(Dst, 456);
-			#if ARM_HF
-			dasm_put(Dst, 461);
-			lua_pop(L, 1);
-			#else
-            goto single;
-			#endif
-			break;
-        case DOUBLE_TYPE:
-            dasm_put(Dst, 468);
-			#if ARM_HF
-			dasm_put(Dst, 473);
-			lua_pop(L, 1);
-            #else
-			goto dual;
-			#endif
-			break;
-		case COMPLEX_DOUBLE_TYPE:
-            lua_pop(L, 1);
-			dasm_put(Dst, 480);
-			break;
-		case COMPLEX_FLOAT_TYPE:
-            lua_pop(L, 1);
-			dasm_put(Dst, 491);
-			break;
-			
-        single:
-            lua_pop(L, 1);
-		single_no_pop:	
-            dasm_put(Dst, 502);
-			
-            break;
-		dual:
-			dasm_put(Dst, 509);
-			
-            lua_pop(L, 1);
-			break;
-       
-
-        
-        default:
-            luaL_error(L, "NYI: callback return type");
-        }
-    }
-	
-    dasm_put(Dst, 518);
-	
-    lua_pop(L, 1); /* upval table - already in registry */
-    assert(lua_gettop(L) == top);
-
-    {
-        void* p;
-        struct ctype ft;
-        cfunction func;
-
-        func = compile(Dst, L, NULL, ref);
-
-        ft = *ct;
-        ft.is_jitted = 1;
-        p = push_cdata(L, ct_usr, &ft);
-        *(cfunction*) p = func;
-
-        assert(lua_gettop(L) == top + 1);
-
-        return func;
-    }
-}
-
-static ALWAYS_INLINE void save_int64_stack_align(struct jit* Dst,reg_info* regs,int align){
-	if(align&&!ALIGNED(regs->exs,2)){
-		regs->exs++;
-		dasm_put(Dst, 520);
-	}
-	dasm_put(Dst, 522);
-	regs->exs+=2;
-}
-
-static ALWAYS_INLINE void save_int64_align(struct jit* Dst,reg_info* regs,int align){
-	if((align&&!ALIGNED(regs->ints,2))||(regs->ints==MAX_REGS-1&&regs->exs/*to ensure consective memory*/)){
-		regs->ints++;
-	}
-	if(regs->ints<MAX_REGS){
-		dasm_put(Dst, 524, ((regs->ints<<2)+0x40*1));
-		regs->ints+=2;
-	}else{
-		save_int64_stack_align(Dst,regs,align);
-	}
-	
-}
-
-static ALWAYS_INLINE  void save_int64(struct jit* Dst,reg_info* regs){
-	save_int64_align(Dst,regs,1);
-}
-
-static ALWAYS_INLINE void save_int_stack_align(struct jit* Dst,reg_info* regs){
-	dasm_put(Dst, 528);
-	regs->exs++;
-}
-
-static ALWAYS_INLINE void save_int(struct jit* Dst,reg_info* regs){
-	if(regs->ints<MAX_REGS){
-		dasm_put(Dst, 530, ((regs->ints++<<2)+0x40*1));
-	}else{
-		save_int_stack_align(Dst,regs);
-	}
-}
-
-static void save_float(struct jit* Dst,reg_info* regs,int size,int isfloat){
-#if ARM_HF
-	if(!regs->float_sealed){
-		int reg=add_float_reg(regs,size,isfloat);
-		if(reg<0) goto SAVE_STACK;
-		switch(size){
-		case 8:
-			dasm_put(Dst, 533, (reg<<2)+24);
-		case 6:
-			dasm_put(Dst, 536, (reg<<2)+16);
-		case 4:
-			dasm_put(Dst, 539, (reg<<2)+8);
-			goto sf_2;
-		case 3:
-			dasm_put(Dst, 542, (reg<<2)+8);
-		case 2:
-			sf_2:
-			dasm_put(Dst, 545, (reg<<2));
-			break;
-		case 1:
-			dasm_put(Dst, 548, (reg<<2));
-			break;
-		}
-		return;
-	}
-	SAVE_STACK:
-	
-	if(!isfloat&&!ALIGNED(regs->exs,2)){
-		regs->exs++;
-		dasm_put(Dst, 551);
-	}
-	switch(size){
-		case 1:
-			dasm_put(Dst, 553);
-			break;
-		case 2:
-			dasm_put(Dst, 555);
-			break;
-		case 3:
-			dasm_put(Dst, 557);
-			break;
-		case 4:
-			dasm_put(Dst, 559);
-			break;
-		case 6:
-			dasm_put(Dst, 561);
-			break;
-		case 8:
-			dasm_put(Dst, 563);
-			break;	
-		
-	}
-	regs->exs+=size;
-	
-#else
-	if(size==1){
-		save_int(Dst,regs);
-	}else if(size==2){
-		save_int64_align(Dst,regs,!isfloat);
-	}
-#endif
-}
-
-static int calculate_stack(lua_State* L,int ct_usr,int nargs){
-	const struct ctype* mt;
-	reg_info regs;int i,stack=0;
-	memset(&regs,0,sizeof(reg_info));
-    for (i = 1; i <= nargs;++i){
-		lua_rawgeti(L, ct_usr, i);
-		mt = (const struct ctype*) lua_touserdata(L, -1);
-		if (mt->pointers || mt->is_reference) {
-			stack+=add_int_reg(&regs);
-		}else{
-			switch(mt->type){
-				case COMPLEX_DOUBLE_TYPE:
-					#if ARM_HF
-					stack+=add_float_reg(&regs,4,0)<0?4:0;
-					#else
-					stack+=add_int64_reg(&regs);
-					stack+=add_int64_reg(&regs);
-					#endif
-					FIX_ALIGN(stack,2);
-					break;
-				case DOUBLE_TYPE:
-					#if ARM_HF
-					stack+=add_float_reg(&regs,2,0)<0?2:0;
-					#else
-					stack+=add_int64_reg(&regs);
-					#endif
-					FIX_ALIGN(stack,2);
-					break;
-				case COMPLEX_FLOAT_TYPE:// Though complex alignment is 4, but vfp requires a sequence of regsiters
-					#if ARM_HF
-					stack+=add_float_reg(&regs,2,1)<0?2:0;
-					#else
-					stack+=add_int_reg(&regs);
-					stack+=add_int_reg(&regs);
-					#endif
-					break;
-				case FLOAT_TYPE:
-					#if ARM_HF
-					stack+=add_float_reg(&regs,1,1)<0?1:0;
-					#else
-					stack+=add_int_reg(&regs);
-					#endif
-					break;
-				case INT64_TYPE:
-					stack+=add_int64_reg(&regs);
-					FIX_ALIGN(stack,2);
-					break;
-				case STRUCT_TYPE:{
-					#if ARM_HF
-					int isfloat;
-					int hfasize=hfa_size(L,-1,mt,&isfloat);
-                    if(hfasize>0){
-						stack+=add_float_reg(&regs,2,0)<0?hfasize:0;
-						if(!isfloat){
-							FIX_ALIGN(stack,2);
-						}
-						break;
-                    }
-					#endif
-				}
-				case UNION_TYPE:{
-					int intsize=(mt->base_size+3)>>2;
-					if(mt->align_mask>4){//8-byte max alignment
-						if(regs.ints<MAX_REGS){
-							FIX_ALIGN(regs.ints,2);
-						}else{
-							FIX_ALIGN(stack,2);
-						}
-					}
-					
-					if(regs.ints+intsize<=MAX_REGS){
-						regs.ints+=intsize;
-					}else{
-						stack+=regs.ints+intsize-MAX_REGS;
-						regs.ints=MAX_REGS;
-					}
-					break;
-				}
-				default:
-					stack+=add_int_reg(&regs);//no need to check type support here
-			}
-		}
-		lua_pop(L,1);
-	}
-	FIX_ALIGN(stack,2);
-	return (regs.ints
-	#if ARM_HF
-	/**/||regs.floats
-	#endif
-	)?0x40*ARM_HF+0x10+stack*4:0;
-}
-
-void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
-{
-    struct jit* Dst = get_jit(L);;
-    int i, nargs, num_upvals,ret_by_addr, stack_size;
-    const struct ctype* mt;
-    void* p; reg_info regs;
-
-    int top = lua_gettop(L);
-
-    ct_usr = lua_absindex(L, ct_usr);
-    nargs = (int) lua_rawlen(L, ct_usr);
-
-    p = push_cdata(L, ct_usr, ct);
-    *(cfunction*) p = func;
-    num_upvals = 1;
-
-    dasm_setup(Dst, build_actionlist);
-#if defined __thumb__ //keep frame pointer
-    dasm_put(Dst, 565);
-#else
-    dasm_put(Dst, 568);
-#endif
-#if CK_ALGIN
-	dasm_put(Dst, 571);
-#endif	
-    dasm_put(Dst, 573);
-    
-    /* Reserve enough stack space for all of the arguments. For hard floating point,
-	 * leave extra 64 bytes
-	 */
-	stack_size=calculate_stack(L,ct_usr,nargs);
-	lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-	
-	// Complex types in softfp and structs/unions larger than 4-bytes are return in the address stored in r0
-	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
-	(!ARM_HF&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(ARM_HF&&hfa_size(L,-1,mt,NULL));
-	lua_pop(L,1);
-	if(ret_by_addr){
-		if(stack_size==0)
-			stack_size=0x40*ARM_HF+0x10;
-		stack_size+=8;
-	}
-	if(stack_size>0){
-		if(stack_size>=1<<12){
-			dasm_put(Dst, 575, (unsigned short)(stack_size), (((unsigned int)(stack_size))>>16));
-		}else{
-			dasm_put(Dst, 581, stack_size);
-		}
-		if (ct->has_var_arg){
-			dasm_put(Dst, 584, nargs, (unsigned short)("too few arguments"), (((unsigned int)("too few arguments"))>>16));
-		}
-		dasm_put(Dst, 601, 0x40*1+0x10);
-	} 
-	
-	memset(&regs,0,sizeof(reg_info));
-	
-    if (ret_by_addr) {	
-		regs.ints++;
-		dasm_put(Dst, 604, (unsigned short)(mt), (((unsigned int)(mt))>>16), 0x40*1);
-	}
-	
-	
-    for (i = 1; i <= nargs; i++) {
-        lua_rawgeti(L, ct_usr, i);
-        mt = (const struct ctype*) lua_touserdata(L, -1);
-		
-        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE|| mt->type==STRUCT_TYPE || mt->type==UNION_TYPE) {
-            lua_getuservalue(L, -1);
-            num_upvals += 2;
-
-            dasm_put(Dst, 615, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16), i);
-			
-            if (mt->pointers || mt->is_reference) {
-                dasm_put(Dst, 626);
-            } else if (mt->type == FUNCTION_PTR_TYPE) {
-                dasm_put(Dst, 630);
-            } else if (mt->type == ENUM_TYPE) {
-                dasm_put(Dst, 634);
-            }else if(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE){
-				if(mt->is_empty) continue;
-				dasm_put(Dst, 638);
-				#if ARM_HF
-				{
-					int hfasize,isfloat;
-					hfasize=hfa_size(L,-2,mt,&isfloat);
-					if(hfasize){
-						switch(hfasize){
-							case 8:
-								dasm_put(Dst, 642);
-								break;
-							case 6:
-								dasm_put(Dst, 644);
-								break;
-							case 4:
-								dasm_put(Dst, 646);
-								break;
-							case 3:
-								dasm_put(Dst, 648);
-								break;
-							case 2:
-								dasm_put(Dst, 650);
-								break;
-							case 1:
-								dasm_put(Dst, 652);
-								break;
-								
-						}
-						save_float(Dst,&regs,hfasize,isfloat);
-						continue;
-					}
-				}
-				#endif
-				
-				if(mt->align_mask>4){//8 byte max alignment 
-					if(regs.ints<4){
-						FIX_ALIGN(regs.ints,2)
-					}else if(!ALIGNED(regs.exs,2)){
-						int diff=regs.exs;
-						regs.exs+=4;
-						dasm_put(Dst, 654);
-					}
-				}
-				int size=ROUND_UP(mt->base_size,4)>>2;
-				dasm_put(Dst, 656, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
-				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+size<=MAX_REGS)){//to ensure consective memory for the struct
-					dasm_put(Dst, 666, ((regs.ints<<2)+0x40*1));
-				}else{
-					regs.ints=MAX_REGS;
-					dasm_put(Dst, 669);
-				}
-				dasm_put(Dst, 671);
-				if(regs.ints+size<=MAX_REGS){
-					regs.ints+=size;
-				}else{
-					int ex=regs.ints+size-MAX_REGS;
-					dasm_put(Dst, 673, (ex)<<2);
-					regs.exs+=ex;
-					regs.ints=MAX_REGS;
-				}
-				continue;
-			}
-
-            save_int(Dst,&regs);
-        } else {
-            lua_pop(L, 1);
-            dasm_put(Dst, 676, i);
-
-            switch (mt->type) {
-			case BOOL_TYPE:
-				dasm_put(Dst, 679);
-                save_int(Dst,&regs);
-                break;
-            case INT8_TYPE:
-                dasm_put(Dst, 685);
-                if (mt->is_unsigned) {
-                     dasm_put(Dst, 689);
-                } else {
-                     dasm_put(Dst, 691);
-                }
-                save_int(Dst,&regs);
-                break;
-
-            case INT16_TYPE:
-                dasm_put(Dst, 693);
-                if (mt->is_unsigned) {
-                    dasm_put(Dst, 697);
-                } else {
-                    dasm_put(Dst, 699);
-                }
-                save_int(Dst,&regs);
-                break;
-
-            case INT32_TYPE:
-                if (mt->is_unsigned) {
-                    dasm_put(Dst, 701);
-                } else {
-                    dasm_put(Dst, 705);
-                }
-                save_int(Dst,&regs);
-                break;
-            case INTPTR_TYPE:
-                dasm_put(Dst, 709);
-                save_int(Dst,&regs);
-				break;
-
-            case INT64_TYPE:
-                if (mt->is_unsigned) {
-                    dasm_put(Dst, 713);
-                } else {
-                    dasm_put(Dst, 717);
-                }
-				save_int64(Dst,&regs);
-                break;
-
-            case DOUBLE_TYPE:
-				dasm_put(Dst, 721);
-				save_float(Dst,&regs,2,0);
-                break;
-
-            case FLOAT_TYPE:
-				dasm_put(Dst, 725);
-                save_float(Dst,&regs,1,1);
-                break;
-				
-			case COMPLEX_DOUBLE_TYPE:
-				#if ARM_HF
-				dasm_put(Dst, 729);
-				save_float(Dst,&regs,4,0);
-				#else
-				FIX_ALIGN(regs.ints,2);
-				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+4<=MAX_REGS)){
-				}else{
-					regs.ints=MAX_REGS;
-					if(!ALIGNED(regs.exs,2)){
-						++regs.exs;
-					}
-				}
-				regs.ints+=4;
-				goto FIX_REG;
-				#endif
-				break;
-			case COMPLEX_FLOAT_TYPE:
-				#if ARM_HF
-				dasm_put(Dst, 733);
-				save_float(Dst,&regs,2,1);
-				#else
-				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+2<=MAX_REGS)){
-				}else{
-					regs.ints=MAX_REGS;
-				}
-				regs.ints+=2;
-				FIX_REG:
-				if(regs.ints>MAX_REGS){
-					regs.exs+=regs.ints-MAX_REGS;
-					regs.ints=MAX_REGS;
-				}
-				#endif
-                break;
-            default:
-                luaL_error(L, "NYI: call arg type");
-            }
-        }
-    }
-
-    if (ct->has_var_arg) {
-		int offset=nargs+1;
-        dasm_put(Dst, 737, offset);
-		#if ARM_HF
-		    if(regs.ints==4||regs.float_sealed){
-				if(regs.ints<4&&regs.float_sealed){//some arg must be loaded to core registers.
-					dasm_put(Dst, 740, ((regs.ints<<2)+0x40), (0x10+0x40), offset);
-				}
-				dasm_put(Dst, 750);
-			} 
-		#else
-			if(regs.ints==4){
-			}
-		#endif
-		else{//no hard floating point in variadic procedure
-			dasm_put(Dst, 752, ((regs.ints<<2)+1*0x40));
-		}
-        
-        dasm_put(Dst, 755);
-		regs.ints=4;
-    } 
-	
-	#if ARM_HF
-	switch(ROUND_UP(regs.highest_bit,4)>>1){
-		case 8 :
-			dasm_put(Dst, 760);
-			break;
-		case 7 :
-			dasm_put(Dst, 762);
-			break;
-		case 6 :
-			dasm_put(Dst, 764);
-			break;
-		case 5:
-			dasm_put(Dst, 766);
-			break;
-		case 4 :
-			dasm_put(Dst, 768);
-			break;
-		case 3 :
-			dasm_put(Dst, 770);
-			break;
-		case 2 :
-			dasm_put(Dst, 772);
-			break;
-		case 1 :
-			dasm_put(Dst, 774);
-			break;
-	}
-	if(stack_size>0){
-		dasm_put(Dst, 776);
-	}
-	#endif
-	
-	//pop registers from stack,align 8 for some compiler
-	assert(regs.ints<=4);
-	switch(regs.ints){
-	case 4:
-	case 3:
-		dasm_put(Dst, 778);
-		break;
-	case 2:
-	case 1:
-		dasm_put(Dst, 780);
-		#if ARM_HF
-		if(regs.float_sealed){
-			dasm_put(Dst, 782);
-		}
-		#endif
-		break;
-	default:
-		#if ARM_HF
-		if(regs.float_sealed){
-			dasm_put(Dst, 784);
-		}
-		#endif
-		break;
-	}
-	
-	dasm_put(Dst, 786, (unsigned short)(func), (((unsigned int)(func))>>16));
-
-    lua_rawgeti(L, ct_usr, 0);
-    mt = (const struct ctype*) lua_touserdata(L, -1);
-
-    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
-        lua_getuservalue(L, -1);
-        num_upvals += 2;
-        dasm_put(Dst, 792, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-
-    } else {
-        switch (mt->type) {
-        case INT64_TYPE:
-        #if LUA_VERSION_NUM>=503
-             lua_pop(L, 1);
-	    #if CK_ALGIN
-            dasm_put(Dst, 807);
-		#else
-            dasm_put(Dst, 810);
-		#endif		
-            dasm_put(Dst, 813);
-            break;
-		#else
-			num_upvals++;
-            dasm_put(Dst, 818, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-            break;
-        #endif
-		
-        case INTPTR_TYPE:
-            num_upvals++;
-            dasm_put(Dst, 832, (unsigned short)(mt), (((unsigned int)(mt))>>16));
-            break;
-
-        case VOID_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 844);
-            break;
-
-        case BOOL_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 846);
-            break;
-
-        case INT8_TYPE:
-        case INT16_TYPE:
-        case INT32_TYPE:
-        case ENUM_TYPE:// value must be narrowed before callee return
-            lua_pop(L, 1);
-			
-            dasm_put(Dst, 852);
-            if (mt->is_unsigned) {
-                dasm_put(Dst, 854);
-            } else {
-                dasm_put(Dst, 858);
-            }
-			
-            dasm_put(Dst, 862);
-            break;
-
-        case FLOAT_TYPE:
-            lua_pop(L, 1);
-            dasm_put(Dst, 864);
-            break;
-
-        case DOUBLE_TYPE:
-            lua_pop(L, 1);
-        #if CK_ALGIN
-		#else
-		#endif	
-            dasm_put(Dst, 869);
-            break;
-		case COMPLEX_DOUBLE_TYPE:
-		case COMPLEX_FLOAT_TYPE:
-		case STRUCT_TYPE:
-		case UNION_TYPE:{
-			lua_getuservalue(L,-1);
-            num_upvals += 2;
-			#if ARM_HF
-			{
-				int isfloat,hfasize=hfa_size(L,-2,mt,&isfloat);
-				if(hfasize>0){
-					switch(hfasize){
-						case 8:
-							dasm_put(Dst, 874);
-							break;
-						case 6:
-							dasm_put(Dst, 876);
-							break;
-						case 4:
-						case 3:
-							dasm_put(Dst, 878);
-							break;
-						case 2:
-						case 1:
-							dasm_put(Dst, 880);
-							break;
-							
-					}
-					dasm_put(Dst, 882, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-					switch(hfasize){
-						case 8:
-							dasm_put(Dst, 895);
-							break;
-						case 6:
-							dasm_put(Dst, 898);
-							break;
-						case 4:
-							dasm_put(Dst, 901);
-							break;
-						case 3:
-							dasm_put(Dst, 904);
-							break;
-						case 2:
-							dasm_put(Dst, 907);
-							break;
-						case 1:
-							dasm_put(Dst, 910);
-							break;
-							
-					}
-					dasm_put(Dst, 913);
-					break;
-				}
-			}
-			
-			#endif
-			if(mt->base_size>4){
-				// value are stored in return storage in r0 for softfp, set usr value here
-				if(!lua_isnil(L,-1)){
-					dasm_put(Dst, 915, (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-				}
-			}else if(mt->is_empty){
-				dasm_put(Dst, 927);
-				break;
-			}else{
-				dasm_put(Dst, 929, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
-			}
-            dasm_put(Dst, 943);
-			break;
-		}	
-        default:
-            luaL_error(L, "NYI: call return type");
-        }
-    }
-
-#ifdef __thumb__
-    dasm_put(Dst, 945);
-#else	
-    dasm_put(Dst, 948);
-#endif	
-    assert(lua_gettop(L) == top + num_upvals);
-    {
-        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
-        /* add a callback as an upval so that the jitted code gets cleaned up when
-         * the function gets gc'd */
-        push_callback(L, f, func);
-        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
-    }
-}
-
+/*
+** This file has been pre-processed with DynASM.
+** http://luajit.org/dynasm.html
+** DynASM version 1.4.0, DynASM arm version 1.4.0
+** DO NOT EDIT! The original file is in "call_arm.dasc".
+*/
+
+/* vim: ts=4 sw=4 sts=4 et tw=78
+ * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+ * Portions copyright (c) 2011 James R. McKaskill.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+ 
+//The generate code is for arm not for thumb
+#if DASM_VERSION != 10400
+#error "Version mismatch between DynASM and included encoding engine"
+#endif
+
+static const unsigned int build_actionlist[951] = {
+0xed0d0a00,
+0x000f8100,
+0x00000000,
+0xed4d0a00,
+0x000f8100,
+0x00000000,
+0xed0d1a00,
+0x000f8100,
+0x00000000,
+0xed4d1a00,
+0x000f8100,
+0x00000000,
+0xed0d2a00,
+0x000f8100,
+0x00000000,
+0xed4d2a00,
+0x000f8100,
+0x00000000,
+0xed0d3a00,
+0x000f8100,
+0x00000000,
+0xed4d3a00,
+0x000f8100,
+0x00000000,
+0xed0d4a00,
+0x000f8100,
+0x00000000,
+0xed4d4a00,
+0x000f8100,
+0x00000000,
+0xed0d5a00,
+0x000f8100,
+0x00000000,
+0xed4d5a00,
+0x000f8100,
+0x00000000,
+0xed0d6a00,
+0x000f8100,
+0x00000000,
+0xed4d6a00,
+0x000f8100,
+0x00000000,
+0xed0d7a00,
+0x000f8100,
+0x00000000,
+0xed4d7a00,
+0x000f8100,
+0x00000000,
+0xed0d0b00,
+0x000f8100,
+0x00000000,
+0xed0d1b00,
+0x000f8100,
+0x00000000,
+0xed0d2b00,
+0x000f8100,
+0x00000000,
+0xed0d3b00,
+0x000f8100,
+0x00000000,
+0xed0d4b00,
+0x000f8100,
+0x00000000,
+0xed0d5b00,
+0x000f8100,
+0x00000000,
+0xed0d6b00,
+0x000f8100,
+0x00000000,
+0xed0d7b00,
+0x000f8100,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c100e,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c100e,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c0006,
+0x00000000,
+0xe51d1000,
+0x000e8180,
+0x00000000,
+0xe2866000,
+0x000b0000,
+0x00000000,
+0xe8b6100e,
+0x00000000,
+0xe8b60006,
+0x00000000,
+0xe4961004,
+0x00000000,
+0xed1d0a00,
+0x000f8100,
+0x00000000,
+0xed1d0b00,
+0x000f8100,
+0x00000000,
+0xed160a00,
+0xe2866004,
+0x00000000,
+0xe2866000,
+0x000b0000,
+0x00000000,
+0xed160b00,
+0xe2866008,
+0x00000000,
+0xe1a0c00d,
+0xe92d000f,
+0x00000000,
+0xe24dd040,
+0x00000000,
+0xe92d5050,
+0xe1a0600c,
+0xe3004000,
+0x000c0200,
+0xe3404000,
+0x000c0200,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe5801000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe8a0100e,
+0x00000000,
+0xe880100e,
+0x00000000,
+0xe8a0100e,
+0x00000000,
+0xe8800006,
+0x00000000,
+0xe880100e,
+0x00000000,
+0xe880000e,
+0x00000000,
+0xe8800006,
+0x00000000,
+0xe5801000,
+0x00000000,
+0xe5801000,
+0x00000000,
+0xe28d1000,
+0x000b0000,
+0x00000000,
+0xe1a01006,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe12fff3c,
+0x00000000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe880100e,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe8800006,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c000c,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe8b6000c,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030003,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe8800006,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xe5801000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030002,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030004,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030006,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe89c000c,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe8b6000c,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030007,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3a01000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030008,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3e02000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030009,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3e02000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003000a,
+0xe1a06000,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0x00000000,
+0xec960b08,
+0x00000000,
+0xec960b06,
+0x00000000,
+0xec960b04,
+0x00000000,
+0xec960a04,
+0x00000000,
+0xed160b00,
+0x00000000,
+0xed160a00,
+0x00000000,
+0xe5960000,
+0x00000000,
+0xe51d0000,
+0x000e8180,
+0xe1a01006,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe12fff3c,
+0x00000000,
+0xe3a02000,
+0x000b0000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x00030000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3e02000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003000c,
+0x00000000,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0x00000000,
+0xe3e01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe3500000,
+0x13a00001,
+0x00000000,
+0xe6ef0070,
+0x00000000,
+0xe6af0070,
+0x00000000,
+0xe6ff0070,
+0x00000000,
+0xe6bf0070,
+0x00000000,
+0xe3e01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000f,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030010,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030011,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030012,
+0x00000000,
+0xee106a10,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0xee006a10,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030013,
+0x00000000,
+0xe1a00004,
+0xec564b10,
+0xe3e01002,
+0xeb000000,
+0x0003000b,
+0xec464b10,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030014,
+0xed2d0b04,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0xecbd0b04,
+0x00000000,
+0xe3e01000,
+0xe1a00004,
+0xeb000000,
+0x00030015,
+0xed2d0a02,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0xecbd0a02,
+0x00000000,
+0xe1a06000,
+0xe3e01002,
+0xe1a00004,
+0xeb000000,
+0x0003000b,
+0xe1a00006,
+0x00000000,
+0xe1a06000,
+0xe1a00004,
+0xe1a04001,
+0xe3e01002,
+0xeb000000,
+0x0003000b,
+0xe1a00006,
+0xe1a01004,
+0x00000000,
+0xe89da050,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe8a60003,
+0x00000000,
+0xe28dc000,
+0x000b0000,
+0xe88c0003,
+0x00000000,
+0xe4860004,
+0x00000000,
+0xe50d0000,
+0x000e8180,
+0x00000000,
+0xed0d3b00,
+0x000f8100,
+0x00000000,
+0xed0d2b00,
+0x000f8100,
+0x00000000,
+0xed0d1b00,
+0x000f8100,
+0x00000000,
+0xed4d1a00,
+0x000f8100,
+0x00000000,
+0xed0d0b00,
+0x000f8100,
+0x00000000,
+0xed0d0a00,
+0x000f8100,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xeca60a01,
+0x00000000,
+0xeca60b02,
+0x00000000,
+0xeca60a04,
+0x00000000,
+0xeca60b04,
+0x00000000,
+0xeca60b06,
+0x00000000,
+0xeca60b08,
+0x00000000,
+0xe92d40f0,
+0xe28d700c,
+0x00000000,
+0xe92d4870,
+0xe28db00c,
+0x00000000,
+0xe24dd004,
+0x00000000,
+0xe1a04000,
+0x00000000,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe04dd00c,
+0x00000000,
+0xe24dd000,
+0x000b0000,
+0x00000000,
+0xeb000000,
+0x00030016,
+0xe3500000,
+0x000b0000,
+0xaa000000,
+0x00050001,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030017,
+0x0006000b,
+0xe1a05000,
+0xe04dd185,
+0x00000000,
+0xe28d6000,
+0x000b0000,
+0x00000000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe50d0000,
+0x000e8180,
+0x00000000,
+0xe3003000,
+0x000c0200,
+0xe3403000,
+0x000c0200,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0x000b0000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030009,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030018,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000c,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000a,
+0x00000000,
+0xec900b0a,
+0x00000000,
+0xec900b0a,
+0x00000000,
+0xec900b06,
+0x00000000,
+0xec900a04,
+0x00000000,
+0xed100b00,
+0x00000000,
+0xed100a00,
+0x00000000,
+0xe2866004,
+0x00000000,
+0xe1a01000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0x00000000,
+0xe28d0000,
+0x000b0000,
+0x00000000,
+0xe1a00006,
+0x00000000,
+0xe12fff3c,
+0x00000000,
+0xe2866000,
+0x000b0000,
+0x00000000,
+0xe3a01000,
+0x000b0000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0xe3500000,
+0x13a00001,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe6ef0070,
+0x00000000,
+0xe6af0070,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe6ff0070,
+0x00000000,
+0xe6bf0070,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000d,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000e,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030011,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003000f,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030010,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030013,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030012,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030014,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030015,
+0x00000000,
+0xe3a01000,
+0x000b0000,
+0x00000000,
+0xe28d2000,
+0x000b0000,
+0xe28d3000,
+0x000b0000,
+0xe1a00004,
+0xeb000000,
+0x00030019,
+0xe2801000,
+0x000b0000,
+0x00000000,
+0xe1a03006,
+0x00000000,
+0xe28d3000,
+0x000b0000,
+0x00000000,
+0xe1a02005,
+0xe1a00004,
+0xeb000000,
+0x0003001a,
+0x00000000,
+0xec9d0b10,
+0x00000000,
+0xec9d0b0e,
+0x00000000,
+0xec9d0b0c,
+0x00000000,
+0xec9d0b0a,
+0x00000000,
+0xec9d0b08,
+0x00000000,
+0xec9d0b06,
+0x00000000,
+0xec9d0b04,
+0x00000000,
+0xed1d0b00,
+0x00000000,
+0xe28dd040,
+0x00000000,
+0xe8bd000f,
+0x00000000,
+0xe8bd0003,
+0x00000000,
+0xe28dd008,
+0x00000000,
+0xe28dd010,
+0x00000000,
+0xe300c000,
+0x000c0200,
+0xe340c000,
+0x000c0200,
+0xe12fff3c,
+0x00000000,
+0xe1a06000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe3a00001,
+0x00000000,
+0xe1a03001,
+0xe1a02000,
+0x00000000,
+0xe1a02001,
+0xe1a01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030003,
+0xe3a00001,
+0x00000000,
+0xe1a06000,
+0xe1a05001,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe5805004,
+0xe3a00001,
+0x00000000,
+0xe1a06000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3a01000,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0xe3a00001,
+0x00000000,
+0xe3a00000,
+0x00000000,
+0xe1a01000,
+0xe1a00004,
+0xeb000000,
+0x00030004,
+0xe3a00001,
+0x00000000,
+0xe1a01000,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x0003001b,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030005,
+0x00000000,
+0xe3a00001,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030006,
+0xe3a00001,
+0x00000000,
+0xe1a00004,
+0xeb000000,
+0x00030007,
+0xe3a00001,
+0x00000000,
+0xed2d0b08,
+0x00000000,
+0xed2d0b06,
+0x00000000,
+0xed2d0b04,
+0x00000000,
+0xed2d0b02,
+0x00000000,
+0xe1a06000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0x00000000,
+0xecbd0b08,
+0xec800b08,
+0x00000000,
+0xecbd0b06,
+0xec800b06,
+0x00000000,
+0xecbd0b04,
+0xec800b04,
+0x00000000,
+0xecbd0b04,
+0xec800a04,
+0x00000000,
+0xecbd0b02,
+0xed000b00,
+0x00000000,
+0xecbd0b02,
+0xed000a00,
+0x00000000,
+0xe3a00001,
+0x00000000,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x0003001c,
+0xe3e01001,
+0xe1a00004,
+0xeb000000,
+0x0003001d,
+0x00000000,
+0xe3a00000,
+0x00000000,
+0xe1a06000,
+0xe3002000,
+0x000c0200,
+0xe3402000,
+0x000c0200,
+0xe3001000,
+0x000c0200,
+0xe3401000,
+0x000c0200,
+0xe1a00004,
+0xeb000000,
+0x00030001,
+0xe5806000,
+0x00000000,
+0xe3a00001,
+0x00000000,
+0xe247d00c,
+0xe8bd80f0,
+0x00000000,
+0xe24bd00c,
+0xe8bd8870,
+0x00000000
+};
+
+static const char *const globnames[] = {
+  (const char *)0
+};
+static const char *const extnames[] = {
+  "rawgeti",
+  "push_cdata",
+  "lua_remove",
+  "lua_pushinteger",
+  "lua_pushboolean",
+  "push_int",
+  "push_float",
+  "lua_pushnumber",
+  "lua_call",
+  "check_typed_pointer",
+  "check_struct",
+  "lua_settop",
+  "check_enum",
+  "check_uint32",
+  "check_int32",
+  "check_uint64",
+  "check_int64",
+  "check_uintptr",
+  "check_float",
+  "check_double",
+  "check_complex_double",
+  "check_complex_float",
+  "lua_gettop",
+  "luaL_error",
+  "check_typed_cfunction",
+  "unpack_varargs_bound",
+  "unpack_varargs_stack",
+  "push_uint",
+  "lua_pushvalue",
+  "lua_setuservalue",
+  (const char *)0
+};
+
+#define JUMP_SIZE 8
+
+#define MIN_BRANCH ((INT32_MIN) >> 8)
+#define MAX_BRANCH ((INT32_MAX) >> 8)
+//arm pc offset 8 so comparing with next instruction is 4,
+//unlike x86 which pass in the current instruction address+1 rather than the next instruction 
+#define BRANCH_OFF 4	
+
+
+#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
+#ifdef TARGET_OS_IPHONE
+#define  CK_ALGIN  0
+#else
+#define  CK_ALGIN  1
+#endif
+#define ALIGNED(x, align) (!CK_ALGIN||((int)(x) & (align - 1)) == 0)
+#if defined(__ARM_PCS_VFP) || (GCC_VERSION==40500||defined(__clang__))&&!defined(__ARM_PCS) && !defined(__SOFTFP__) && !defined(__SOFTFP) && \
+    defined(__VFP_FP__)
+#define ARM_HF 1
+#else
+#define ARM_HF 0
+#endif
+#if ARM_HF&&!CK_ALGIN
+#error "Unsupported unaligned stack for hard floating point"
+#endif	
+
+static void compile_extern_jump(struct jit* jit, lua_State* L, cfunction func, uint8_t* code)
+{
+    /* The jump code is the function pointer followed by a stub to call the
+     * function pointer. The stub exists so we can jump to functions with an
+     * offset greater than 32MB.
+     *
+     * Note we have to manually set this up since there are commands buffered
+     * in the jit state.
+     */
+	
+    *(cfunction*) code = func;
+     //ldr pc, [pc - 12]
+    *(uint32_t*) &code[4] = 0xE51FF00CU; 
+	
+}
+
+
+
+
+void compile_globals(struct jit* jit, lua_State* L)
+{
+    (void) jit;
+}
+
+typedef struct stack_info{
+	int extra;
+	int int_off;
+	int stack_off;
+	int float_size;
+#if ARM_HF
+	int float_off; 
+#endif	
+} stack_info;
+//vfp use back-filling rule for registers until a float value on stack
+typedef struct reg_info{
+	uint16_t exs;	
+	union{
+		uint8_t ints;
+		uint8_t regs;
+	};
+#if ARM_HF
+	uint8_t float_sealed;
+	short floats;//each bit is a float: s0-s15 or v0-v7 or q0-q3
+	uint8_t left_single;
+	uint8_t highest_bit;
+#endif
+} reg_info;
+
+#define MAX_REGS 4
+#define MAX_FLOAT_REGS 16
+#ifndef bool
+#define bool uint8_t
+#endif
+
+#define has_bit(x,b) (((x)&(1<<(b)))!=0)
+#define set_bit(x,b) (x=((x)|(1<<(b)))) 
+#define FIX_ALIGN(x,al) \
+	if(!ALIGNED((x),al)){\
+		x=ROUND_UP(x,al);\
+	}
+static ALWAYS_INLINE bool is_float_sealed(reg_info* regs){
+#if ARM_HF
+return regs->float_sealed;
+#else
+return regs->regs>=MAX_REGS;
+#endif
+}
+//return size need to put on stack
+static ALWAYS_INLINE int add_int_reg(reg_info* regs){
+	if(regs->regs<MAX_REGS){
+		regs->regs++;
+		return 0;
+	}
+	return 1;
+		
+}
+//return size need to put on stack
+static ALWAYS_INLINE int add_int64_reg(reg_info* regs){
+	if(regs->regs<MAX_REGS-1){
+		regs->regs=ROUND_UP(regs->regs,2)+2;
+		return 0;
+	}else if(regs->regs==MAX_REGS-1){
+		regs->regs=MAX_REGS;
+	}
+		
+	return 2;
+}
+static ALWAYS_INLINE bool is_float_type(int t){
+    return t==FLOAT_TYPE||t==DOUBLE_TYPE;
+}
+static int hfa_size(lua_State* L,int idx, const struct ctype* ct,int* isfloat){
+	struct ctype* mt;
+	int type,ele_count,i,ct_usr;
+	lua_getuservalue(L,idx);
+	ct_usr=lua_absindex(L,-1);
+    lua_rawgeti(L,ct_usr,1);
+    mt=(struct ctype*)lua_touserdata(L,-1);
+    if(mt==NULL||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+        lua_pop(L,2);
+		if(ct->type==COMPLEX_DOUBLE_TYPE){
+			if(isfloat) *isfloat=0;
+			return 4;
+		}else if(ct->type==COMPLEX_FLOAT_TYPE){
+			if(isfloat) *isfloat=1;
+			return 2;
+		}
+        return 0;
+    }
+	type=mt->type;
+    ele_count=(int)(ct->base_size/mt->base_size);
+    if(ele_count>4||ct->base_size%mt->base_size){
+        lua_pop(L,2);
+        return 0;
+    }
+	lua_pop(L,1);
+    for (i = 2; i <=4 ; ++i) {
+        lua_rawgeti(L,ct_usr,i);
+		if(lua_isnil(L,-1)){//case have array member;
+            lua_pop(L,1);
+            break;
+        }
+        mt=(struct ctype*)lua_touserdata(L,-1);
+        if(mt->type!=type||(mt->pointers&&!mt->is_array)||mt->is_reference||!is_float_type(mt->type)){
+            lua_pop(L,2);
+            return 0;
+        }
+        lua_pop(L,1);
+    }
+	if(isfloat){
+		*isfloat=mt->type==FLOAT_TYPE;
+	}
+	lua_pop(L,1);
+    return ele_count*(mt->type==FLOAT_TYPE?1:2);
+}
+#if ARM_HF
+static void save_float_reg(struct jit* Dst,int reg,int size,stack_info* st){
+	int sz;
+	if(reg==-1) return;
+	for(;size>0;size-=8){
+		sz=size>8?8:size;
+		switch(sz){
+		case 4:
+			switch(reg){
+				case 0:
+					dasm_put(Dst, 0, st->float_size);
+					break;
+				case 1:
+					dasm_put(Dst, 3, st->float_size);
+					break;
+				case 2:
+					dasm_put(Dst, 6, st->float_size);
+					break;
+				case 3:
+					dasm_put(Dst, 9, st->float_size);
+					break;
+				case 4:
+					dasm_put(Dst, 12, st->float_size);
+					break;
+				case 5:
+					dasm_put(Dst, 15, st->float_size);
+					break;
+				case 6:
+					dasm_put(Dst, 18, st->float_size);
+					break;
+				case 7:
+					dasm_put(Dst, 21, st->float_size);
+					break;
+				case 8:
+					dasm_put(Dst, 24, st->float_size);
+					break;
+				case 9:
+					dasm_put(Dst, 27, st->float_size);
+					break;
+				case 10:
+					dasm_put(Dst, 30, st->float_size);
+					break;
+				case 11:
+					dasm_put(Dst, 33, st->float_size);
+					break;
+				case 12:
+					dasm_put(Dst, 36, st->float_size);
+					break;
+				case 13:
+					dasm_put(Dst, 39, st->float_size);
+					break;
+				case 14:
+					dasm_put(Dst, 42, st->float_size);
+					break;
+				case 15:
+					dasm_put(Dst, 45, st->float_size);
+					break;
+			}
+			break;
+		case 8:
+			switch(reg>>1){
+				case 0:
+					dasm_put(Dst, 48, st->float_size);
+					break;
+				case 1:
+					dasm_put(Dst, 51, st->float_size);
+					break;
+				case 2:
+					dasm_put(Dst, 54, st->float_size);
+					break;
+				case 3:
+					dasm_put(Dst, 57, st->float_size);
+					break;
+				case 4:
+					dasm_put(Dst, 60, st->float_size);
+					break;
+				case 5:
+					dasm_put(Dst, 63, st->float_size);
+					break;
+				case 6:
+					dasm_put(Dst, 66, st->float_size);
+					break;
+				case 7:
+					dasm_put(Dst, 69, st->float_size);
+					break;
+			}
+			reg+=2;
+			break;
+		}
+		st->float_size+=sz;
+	}
+}
+
+//128 bit vector type is not supported by this
+static int add_float_reg(reg_info* regs,int sz,int isfloat){
+
+	if(is_float_sealed(regs)) return -1;
+	int i,ret=-1;
+	if(sz==1){
+		if(regs->left_single){
+			int n=regs->highest_bit;
+			for(i=0;i<n;++i){
+				if(!has_bit(regs->floats,i)){
+					regs->left_single--;
+					set_bit(regs->floats,i);
+					ret=i;
+				}
+			}
+		}else{
+			ret=regs->highest_bit;
+			set_bit(regs->floats,regs->highest_bit);
+			++regs->highest_bit;
+		}
+	}else{
+		if(regs->highest_bit>MAX_FLOAT_REGS-sz){
+			regs->highest_bit=MAX_FLOAT_REGS;
+		}else{
+			if(!isfloat&&!ALIGNED(regs->highest_bit, 2)){
+				regs->highest_bit++;
+				regs->left_single++;
+			}
+			ret=regs->highest_bit;
+			for(i=0;i<sz;++i){
+				set_bit(regs->floats,regs->highest_bit++);
+			}
+		}
+	}
+	if(regs->highest_bit==MAX_FLOAT_REGS){
+		regs->float_sealed=true;		
+	}
+	return ret;
+}
+#endif
+static void load_reg(struct jit* Dst,int off,int size){
+	if(size==16){
+		dasm_put(Dst, 72, off);
+	}else if(size==12){
+		dasm_put(Dst, 76, off);
+	}else if(size==8){
+		dasm_put(Dst, 80, off);
+	}else{
+		dasm_put(Dst, 84, off);
+	}
+}
+// arm store/load range for immediate value is only -256-255
+static void load_stack(struct jit* Dst,stack_info* st,int size,int align){
+	int off=st->stack_off;
+	FIX_ALIGN(st->stack_off,align);
+	if((off=st->stack_off-off)){
+		dasm_put(Dst, 87, off);
+	}
+	if(size==16){
+		dasm_put(Dst, 90);
+	}else if(size==8){
+		dasm_put(Dst, 92);
+	}else{
+		dasm_put(Dst, 94);
+	}
+	st->stack_off+=size;
+}
+
+static void load_int(struct jit* Dst,stack_info* st,int size,int align){
+	FIX_ALIGN(st->int_off,align);
+	if(st->int_off<0x40*ARM_HF+MAX_REGS*4&&(!st->stack_off||MAX_REGS*4+size<=0x40*ARM_HF+MAX_REGS*4)){
+		load_reg(Dst,st->int_off+st->extra,size);
+		st->int_off+=size;
+	}else{
+		st->int_off=0x40*ARM_HF+MAX_REGS*4;
+		load_stack(Dst,st,size,align);
+	}
+	
+}
+
+static void load_float(struct jit* Dst,stack_info* st,int size,int vfp,int align){
+	#if ARM_HF
+	if(st->float_off<st->float_size){
+		if(vfp){
+			if(size==4){//float
+				dasm_put(Dst, 96, st->float_off+st->extra);
+			}else if(size==8){//double
+				dasm_put(Dst, 99, st->float_off+st->extra);
+			}
+		}else load_reg(Dst,st->float_off+st->extra,size);
+		st->float_off+=size;
+	}else if(vfp){
+		if(size==4){//float
+			dasm_put(Dst, 102);
+		}else if(size==8){//double
+			int off=st->stack_off;
+			FIX_ALIGN(st->stack_off,align);
+			if((off=st->stack_off-off)){
+				dasm_put(Dst, 105, off);
+			}
+			dasm_put(Dst, 108);
+		}
+	}else{
+		load_stack(Dst,st,size,align);
+	}
+	#else	
+		load_int(Dst,st,size,align);
+	#endif
+}
+#if ARM_HF
+static void push_regs(lua_State* L,struct jit* Dst,int ct_usr,int nargs,stack_info* st){
+	const struct ctype* mt;
+	reg_info regs;int i;
+	memset(&regs,0,sizeof(reg_info));
+    for (i = 1; i <= nargs&&!is_float_sealed(&regs); ++i){
+		lua_rawgeti(L, ct_usr, i);
+		mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (!mt->pointers &&! mt->is_reference) {
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,4,0),16,st);
+					break;
+				case DOUBLE_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,2,0),8,st);
+					break;
+				case COMPLEX_FLOAT_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,2,1),8,st);
+					break;
+				case FLOAT_TYPE:
+					save_float_reg(Dst,add_float_reg(&regs,1,1),4,st);
+					break;
+				case STRUCT_TYPE:
+					{
+						int isfloat,hfasize=hfa_size(L,-1,mt,&isfloat);
+						if(hfasize){
+							save_float_reg(Dst,add_float_reg(&regs,hfasize,isfloat),4*hfasize,st);
+							break;
+						}
+					}
+				case UNION_TYPE:
+					break;
+				case INT64_TYPE:
+					//add_int64_reg(&regs);
+					break;
+				default:
+					//add_int_reg(&regs);//no need to check type support here
+					break;
+			}
+		}
+		lua_pop(L,1);
+	}
+	st->float_off+=st->int_off;
+	st->int_off+=0x40;
+}
+#endif
+cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals, ref;
+    const struct ctype* mt;
+	stack_info st;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    fidx = lua_absindex(L, fidx);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    dasm_setup(Dst, build_actionlist);
+
+    lua_newtable(L);
+    lua_pushvalue(L, -1);
+    ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    num_upvals = 0;
+
+    if (ct->has_var_arg) {
+        luaL_error(L, "can't create callbacks with varargs");
+    }
+	memset(&st,0,sizeof(stack_info));
+	st.extra=0x10;
+    /* prolog and get the upval table */
+	dasm_put(Dst, 111);
+#if ARM_HF
+	dasm_put(Dst, 114);
+	push_regs(L,Dst,ct_usr,nargs,&st);
+#endif	
+    
+    dasm_put(Dst, 116, (unsigned short)(L), (((unsigned int)(L))>>16), (unsigned short)(ref), (((unsigned int)(ref))>>16), (unsigned short)(LUA_REGISTRYINDEX), (((unsigned int)(LUA_REGISTRYINDEX))>>16));
+	
+    /* get the lua function */
+    lua_pushvalue(L, fidx);
+    lua_rawseti(L, -2, ++num_upvals);
+	
+	
+    dasm_put(Dst, 134, num_upvals);
+
+	// Complex type is return in the address stored in r0 for softfp
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	if(!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
+	(!1&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(1&&hfa_size(L,-1,mt,NULL))){
+		st.int_off+=4;
+	} 
+	lua_pop(L,1);
+
+	//whether 64 bit type requires 8 bytes alignment in stack is defined by compiler.android compiler reqiures only 4 byte alignment;
+	//actually the stack it self may reqiures 8 bytes alignment
+    for (i = 1; i <= nargs; i++) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+
+        if (mt->pointers || mt->is_reference) {
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+			
+            dasm_put(Dst, 141, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+            load_int(Dst,&st,4,4);
+            dasm_put(Dst, 157);
+        } else {
+            switch (mt->type) {
+			case STRUCT_TYPE:
+			case UNION_TYPE:{
+				#if ARM_HF
+				int isfloat,hfasize=0;
+				if(mt->type!=UNION_TYPE){
+					hfasize=hfa_size(L,-1,mt,&isfloat);
+				}
+				#endif
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+                dasm_put(Dst, 163, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+				#if ARM_HF
+				if(hfasize){
+					if(hfasize<=4)load_float(Dst,&st,4*hfasize,0,4*(2-isfloat));
+					switch(hfasize){
+						case 8:
+							load_float(Dst,&st,16,0,8);
+							dasm_put(Dst, 179);
+							load_float(Dst,&st,16,0,8);
+							dasm_put(Dst, 181);
+							break;
+						case 6:
+							load_float(Dst,&st,16,0,8);
+							dasm_put(Dst, 183);
+							load_float(Dst,&st,8,0,8);
+							dasm_put(Dst, 185);
+							break;
+						case 4:
+							dasm_put(Dst, 187);
+							break;
+						case 3:
+							dasm_put(Dst, 189);
+							break;
+						case 2:
+							dasm_put(Dst, 191);
+							break;
+						case 1:
+							dasm_put(Dst, 193);
+							break;
+					}
+				}else
+				#endif
+				if(!mt->is_empty){
+					int size=mt->base_size;
+					if(size<=4){
+						load_int(Dst,&st,4,4);
+						dasm_put(Dst, 195);
+					}else{
+						size=ROUND_UP(size,4);
+						if(mt->align_mask>4){//8 byte max alignment
+							if(st.int_off<0x40*ARM_HF+MAX_REGS*4){FIX_ALIGN(st.int_off,8);} 
+							else {FIX_ALIGN(st.stack_off,8);}
+						}
+						
+						if(st.int_off<0x40*ARM_HF+MAX_REGS*4&&(!st.stack_off||st.int_off+size<=0x40*ARM_HF+MAX_REGS*4)){//to ensure consective memory for the struct
+							dasm_put(Dst, 197, st.int_off+st.extra);
+							st.int_off+=size;
+						}else{
+							st.int_off=0x40*ARM_HF+MAX_REGS*4;
+							dasm_put(Dst, 200);
+							st.stack_off+=size;
+						}
+						dasm_put(Dst, 202, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
+					}
+				}
+                dasm_put(Dst, 212);
+				break;
+			}
+				
+			case COMPLEX_DOUBLE_TYPE:
+				
+				lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+                dasm_put(Dst, 217, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+                load_float(Dst,&st,16,0,8);
+                dasm_put(Dst, 233);
+				break;
+			case COMPLEX_FLOAT_TYPE:
+                lua_getuservalue(L, -1);
+				lua_rawseti(L, -3, ++num_upvals); /* usr value */
+				lua_rawseti(L, -2, ++num_upvals); /* mt */
+                dasm_put(Dst, 239, num_upvals-1, i, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+				load_float(Dst,&st,8,0,4);
+                dasm_put(Dst, 255);
+				break;
+            case INT64_TYPE:
+				
+			#if LUA_VERSION_NUM>=503
+                lua_pop(L, 1);
+				
+            #if CK_ALGIN
+				FIX_ALIGN(st.int_off,8);
+				if(st.int_off<16){
+					dasm_put(Dst, 261, st.int_off+st.extra);
+					st.int_off+=8;
+				}else{
+					if(!ALIGNED(st.stack_off,8)){
+						st.stack_off+=4;
+						dasm_put(Dst, 265);
+					}
+					dasm_put(Dst, 267);
+					st.stack_off+=8;
+				}
+			#else
+				load_int(Dst,st,8,8);
+			#endif
+                dasm_put(Dst, 269);
+			#else
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 273, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+                load_int(Dst,&st,8,8);
+                dasm_put(Dst, 282);
+			#endif
+                break;
+
+            case INTPTR_TYPE:
+                lua_rawseti(L, -2, ++num_upvals); /* mt */
+				
+                dasm_put(Dst, 288, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+                load_int(Dst,&st,4,4);
+                dasm_put(Dst, 297);
+				
+                break;
+
+            case BOOL_TYPE:
+                lua_pop(L, 1);
+				
+                load_int(Dst,&st,4,4);
+                dasm_put(Dst, 303);
+                break;
+
+            case INT8_TYPE: // no need to narrow cause narrowed by caller
+            case INT16_TYPE: // no need to narrow cause narrowed by caller
+            case ENUM_TYPE:
+            case INT32_TYPE:
+                lua_pop(L, 1);
+				
+                load_int(Dst,&st,4,4);
+                dasm_put(Dst, 307);
+                break;
+
+            case FLOAT_TYPE:
+                lua_pop(L, 1);
+                
+                load_float(Dst,&st,4,ARM_HF,4);
+                dasm_put(Dst, 311);
+                break;
+
+            case DOUBLE_TYPE:
+                lua_pop(L, 1);
+				
+				#if ARM_HF
+				load_float(Dst,&st,8,ARM_HF,8);
+				#elif CK_ALGIN
+				FIX_ALIGN(st.int_off,8);
+				if(st.int_off<16){
+					dasm_put(Dst, 315, st.int_off+st.extra);
+					st.int_off+=8;
+				}else{
+					if(!ALIGNED(st.stack_off,8)){
+						st.stack_off+=4;
+						dasm_put(Dst, 319);
+					}
+					dasm_put(Dst, 321);
+					st.stack_off+=8;
+				}
+				#else
+				load_float(Dst,&st,8,ARM_HF,8);
+				#endif	
+                dasm_put(Dst, 323);
+                break;
+				
+            default:
+                luaL_error(L, "NYI: callback arg type");
+            }
+        }
+    }
+
+    lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+
+    dasm_put(Dst, 327, ((mt->pointers || mt->is_reference || mt->type != VOID_TYPE) ? 1 : 0), nargs);
+    
+
+    if (mt->pointers || mt->is_reference) {
+        lua_getuservalue(L, -1);
+        lua_rawseti(L, -3, ++num_upvals); /* usr value */
+        lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+        dasm_put(Dst, 335, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+        goto single_no_pop;
+    } else {
+        switch (mt->type) {
+		case STRUCT_TYPE:
+		case UNION_TYPE:{
+			int isfloat,hfasize=0;
+			if(mt->type!=UNION_TYPE){
+				hfasize=hfa_size(L,-1,mt,&isfloat);
+			}
+			lua_getuservalue(L, -1);
+			lua_rawseti(L, -3, ++num_upvals); /* usr value */
+			lua_rawseti(L, -2, ++num_upvals); /* mt */
+            dasm_put(Dst, 351, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+			#if ARM_HF
+			if(hfasize>0){
+				switch(hfasize){
+					case 8:
+						dasm_put(Dst, 372);
+						break;
+					case 6:
+						dasm_put(Dst, 374);
+						break;
+					case 4:
+						dasm_put(Dst, 376);
+						break;
+					case 3:
+						dasm_put(Dst, 378);
+						break;
+					case 2:
+						dasm_put(Dst, 380);
+						break;
+					case 1:
+						dasm_put(Dst, 382);
+						break;	
+				}
+			}else
+			#endif
+			if(!mt->is_empty){
+				if(mt->base_size<=4){
+					dasm_put(Dst, 384);
+				}else{
+					dasm_put(Dst, 386, st.extra+0x40*1, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
+				}
+			}
+			break;
+		}	
+        case ENUM_TYPE:
+            lua_getuservalue(L, -1);
+            lua_rawseti(L, -3, ++num_upvals); /* usr value */
+            lua_rawseti(L, -2, ++num_upvals); /* mt */
+
+            dasm_put(Dst, 399, num_upvals-1, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+
+            goto single_no_pop;
+
+        case VOID_TYPE:
+            dasm_put(Dst, 415);
+            lua_pop(L, 1);
+            break;
+
+        case BOOL_TYPE:
+        case INT8_TYPE:// narrow it 
+        case INT16_TYPE:// narrow it 
+        case INT32_TYPE:
+		    dasm_put(Dst, 420);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 422);
+            } else {
+                dasm_put(Dst, 426);
+            }
+			switch(mt->type){
+				case BOOL_TYPE:
+					dasm_put(Dst, 430);
+					break;
+				case INT8_TYPE:
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 433);
+					} else {
+						dasm_put(Dst, 435);
+					}
+					break;
+				case INT16_TYPE:
+					if (mt->is_unsigned) {
+						dasm_put(Dst, 437);
+					} else {
+						dasm_put(Dst, 439);
+					}
+					break;
+			}
+            goto single;
+
+        case INT64_TYPE:
+            dasm_put(Dst, 441);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 443);
+            } else {
+                dasm_put(Dst, 447);
+            }
+            goto dual;
+
+        case INTPTR_TYPE:
+            dasm_put(Dst, 451);
+            goto single;
+
+        case FLOAT_TYPE:
+            dasm_put(Dst, 456);
+			#if ARM_HF
+			dasm_put(Dst, 461);
+			lua_pop(L, 1);
+			#else
+            goto single;
+			#endif
+			break;
+        case DOUBLE_TYPE:
+            dasm_put(Dst, 468);
+			#if ARM_HF
+			dasm_put(Dst, 473);
+			lua_pop(L, 1);
+            #else
+			goto dual;
+			#endif
+			break;
+		case COMPLEX_DOUBLE_TYPE:
+            lua_pop(L, 1);
+			dasm_put(Dst, 480);
+			break;
+		case COMPLEX_FLOAT_TYPE:
+            lua_pop(L, 1);
+			dasm_put(Dst, 491);
+			break;
+			
+        single:
+            lua_pop(L, 1);
+		single_no_pop:	
+            dasm_put(Dst, 502);
+			
+            break;
+		dual:
+			dasm_put(Dst, 509);
+			
+            lua_pop(L, 1);
+			break;
+       
+
+        
+        default:
+            luaL_error(L, "NYI: callback return type");
+        }
+    }
+	
+    dasm_put(Dst, 518);
+	
+    lua_pop(L, 1); /* upval table - already in registry */
+    assert(lua_gettop(L) == top);
+
+    {
+        void* p;
+        struct ctype ft;
+        cfunction func;
+
+        func = compile(Dst, L, NULL, ref);
+
+        ft = *ct;
+        ft.is_jitted = 1;
+        p = push_cdata(L, ct_usr, &ft);
+        *(cfunction*) p = func;
+
+        assert(lua_gettop(L) == top + 1);
+
+        return func;
+    }
+}
+
+static ALWAYS_INLINE void save_int64_stack_align(struct jit* Dst,reg_info* regs,int align){
+	if(align&&!ALIGNED(regs->exs,2)){
+		regs->exs++;
+		dasm_put(Dst, 520);
+	}
+	dasm_put(Dst, 522);
+	regs->exs+=2;
+}
+
+static ALWAYS_INLINE void save_int64_align(struct jit* Dst,reg_info* regs,int align){
+	if((align&&!ALIGNED(regs->ints,2))||(regs->ints==MAX_REGS-1&&regs->exs/*to ensure consective memory*/)){
+		regs->ints++;
+	}
+	if(regs->ints<MAX_REGS){
+		dasm_put(Dst, 524, ((regs->ints<<2)+0x40*1));
+		regs->ints+=2;
+	}else{
+		save_int64_stack_align(Dst,regs,align);
+	}
+	
+}
+
+static ALWAYS_INLINE  void save_int64(struct jit* Dst,reg_info* regs){
+	save_int64_align(Dst,regs,1);
+}
+
+static ALWAYS_INLINE void save_int_stack_align(struct jit* Dst,reg_info* regs){
+	dasm_put(Dst, 528);
+	regs->exs++;
+}
+
+static ALWAYS_INLINE void save_int(struct jit* Dst,reg_info* regs){
+	if(regs->ints<MAX_REGS){
+		dasm_put(Dst, 530, ((regs->ints++<<2)+0x40*1));
+	}else{
+		save_int_stack_align(Dst,regs);
+	}
+}
+
+static void save_float(struct jit* Dst,reg_info* regs,int size,int isfloat){
+#if ARM_HF
+	if(!regs->float_sealed){
+		int reg=add_float_reg(regs,size,isfloat);
+		if(reg<0) goto SAVE_STACK;
+		switch(size){
+		case 8:
+			dasm_put(Dst, 533, (reg<<2)+24);
+		case 6:
+			dasm_put(Dst, 536, (reg<<2)+16);
+		case 4:
+			dasm_put(Dst, 539, (reg<<2)+8);
+			goto sf_2;
+		case 3:
+			dasm_put(Dst, 542, (reg<<2)+8);
+		case 2:
+			sf_2:
+			dasm_put(Dst, 545, (reg<<2));
+			break;
+		case 1:
+			dasm_put(Dst, 548, (reg<<2));
+			break;
+		}
+		return;
+	}
+	SAVE_STACK:
+	
+	if(!isfloat&&!ALIGNED(regs->exs,2)){
+		regs->exs++;
+		dasm_put(Dst, 551);
+	}
+	switch(size){
+		case 1:
+			dasm_put(Dst, 553);
+			break;
+		case 2:
+			dasm_put(Dst, 555);
+			break;
+		case 3:
+			dasm_put(Dst, 557);
+			break;
+		case 4:
+			dasm_put(Dst, 559);
+			break;
+		case 6:
+			dasm_put(Dst, 561);
+			break;
+		case 8:
+			dasm_put(Dst, 563);
+			break;	
+		
+	}
+	regs->exs+=size;
+	
+#else
+	if(size==1){
+		save_int(Dst,regs);
+	}else if(size==2){
+		save_int64_align(Dst,regs,!isfloat);
+	}
+#endif
+}
+
+static int calculate_stack(lua_State* L,int ct_usr,int nargs){
+	const struct ctype* mt;
+	reg_info regs;int i,stack=0;
+	memset(&regs,0,sizeof(reg_info));
+    for (i = 1; i <= nargs;++i){
+		lua_rawgeti(L, ct_usr, i);
+		mt = (const struct ctype*) lua_touserdata(L, -1);
+		if (mt->pointers || mt->is_reference) {
+			stack+=add_int_reg(&regs);
+		}else{
+			switch(mt->type){
+				case COMPLEX_DOUBLE_TYPE:
+					#if ARM_HF
+					stack+=add_float_reg(&regs,4,0)<0?4:0;
+					#else
+					stack+=add_int64_reg(&regs);
+					stack+=add_int64_reg(&regs);
+					#endif
+					FIX_ALIGN(stack,2);
+					break;
+				case DOUBLE_TYPE:
+					#if ARM_HF
+					stack+=add_float_reg(&regs,2,0)<0?2:0;
+					#else
+					stack+=add_int64_reg(&regs);
+					#endif
+					FIX_ALIGN(stack,2);
+					break;
+				case COMPLEX_FLOAT_TYPE:// Though complex alignment is 4, but vfp requires a sequence of regsiters
+					#if ARM_HF
+					stack+=add_float_reg(&regs,2,1)<0?2:0;
+					#else
+					stack+=add_int_reg(&regs);
+					stack+=add_int_reg(&regs);
+					#endif
+					break;
+				case FLOAT_TYPE:
+					#if ARM_HF
+					stack+=add_float_reg(&regs,1,1)<0?1:0;
+					#else
+					stack+=add_int_reg(&regs);
+					#endif
+					break;
+				case INT64_TYPE:
+					stack+=add_int64_reg(&regs);
+					FIX_ALIGN(stack,2);
+					break;
+				case STRUCT_TYPE:{
+					#if ARM_HF
+					int isfloat;
+					int hfasize=hfa_size(L,-1,mt,&isfloat);
+                    if(hfasize>0){
+						stack+=add_float_reg(&regs,2,0)<0?hfasize:0;
+						if(!isfloat){
+							FIX_ALIGN(stack,2);
+						}
+						break;
+                    }
+					#endif
+				}
+				case UNION_TYPE:{
+					int intsize=(mt->base_size+3)>>2;
+					if(mt->align_mask>4){//8-byte max alignment
+						if(regs.ints<MAX_REGS){
+							FIX_ALIGN(regs.ints,2);
+						}else{
+							FIX_ALIGN(stack,2);
+						}
+					}
+					
+					if(regs.ints+intsize<=MAX_REGS){
+						regs.ints+=intsize;
+					}else{
+						stack+=regs.ints+intsize-MAX_REGS;
+						regs.ints=MAX_REGS;
+					}
+					break;
+				}
+				default:
+					stack+=add_int_reg(&regs);//no need to check type support here
+			}
+		}
+		lua_pop(L,1);
+	}
+	FIX_ALIGN(stack,2);
+	return (regs.ints
+	#if ARM_HF
+	/**/||regs.floats
+	#endif
+	)?0x40*ARM_HF+0x10+stack*4:0;
+}
+
+void compile_function(lua_State* L, cfunction func, int ct_usr, const struct ctype* ct)
+{
+    struct jit* Dst = get_jit(L);;
+    int i, nargs, num_upvals,ret_by_addr, stack_size;
+    const struct ctype* mt;
+    void* p; reg_info regs;
+
+    int top = lua_gettop(L);
+
+    ct_usr = lua_absindex(L, ct_usr);
+    nargs = (int) lua_rawlen(L, ct_usr);
+
+    p = push_cdata(L, ct_usr, ct);
+    *(cfunction*) p = func;
+    num_upvals = 1;
+
+    dasm_setup(Dst, build_actionlist);
+#if defined __thumb__ //keep frame pointer
+    dasm_put(Dst, 565);
+#else
+    dasm_put(Dst, 568);
+#endif
+#if CK_ALGIN
+	dasm_put(Dst, 571);
+#endif	
+    dasm_put(Dst, 573);
+    
+    /* Reserve enough stack space for all of the arguments. For hard floating point,
+	 * leave extra 64 bytes
+	 */
+	stack_size=calculate_stack(L,ct_usr,nargs);
+	lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+	
+	// Complex types in softfp and structs/unions larger than 4-bytes are return in the address stored in r0
+	ret_by_addr=!mt->pointers && !mt->is_reference &&(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE||
+	(!ARM_HF&&(mt->type==COMPLEX_DOUBLE_TYPE||mt->type==COMPLEX_FLOAT_TYPE)))&&mt->base_size>4&&!(ARM_HF&&hfa_size(L,-1,mt,NULL));
+	lua_pop(L,1);
+	if(ret_by_addr){
+		if(stack_size==0)
+			stack_size=0x40*ARM_HF+0x10;
+		stack_size+=8;
+	}
+	if(stack_size>0){
+		if(stack_size>=1<<12){
+			dasm_put(Dst, 575, (unsigned short)(stack_size), (((unsigned int)(stack_size))>>16));
+		}else{
+			dasm_put(Dst, 581, stack_size);
+		}
+		if (ct->has_var_arg){
+			dasm_put(Dst, 584, nargs, (unsigned short)("too few arguments"), (((unsigned int)("too few arguments"))>>16));
+		}
+		dasm_put(Dst, 601, 0x40*1+0x10);
+	} 
+	
+	memset(&regs,0,sizeof(reg_info));
+	
+    if (ret_by_addr) {	
+		regs.ints++;
+		dasm_put(Dst, 604, (unsigned short)(mt), (((unsigned int)(mt))>>16), 0x40*1);
+	}
+	
+	
+    for (i = 1; i <= nargs; i++) {
+        lua_rawgeti(L, ct_usr, i);
+        mt = (const struct ctype*) lua_touserdata(L, -1);
+		
+        if (mt->pointers || mt->is_reference || mt->type == FUNCTION_PTR_TYPE || mt->type == ENUM_TYPE|| mt->type==STRUCT_TYPE || mt->type==UNION_TYPE) {
+            lua_getuservalue(L, -1);
+            num_upvals += 2;
+
+            dasm_put(Dst, 615, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16), i);
+			
+            if (mt->pointers || mt->is_reference) {
+                dasm_put(Dst, 626);
+            } else if (mt->type == FUNCTION_PTR_TYPE) {
+                dasm_put(Dst, 630);
+            } else if (mt->type == ENUM_TYPE) {
+                dasm_put(Dst, 634);
+            }else if(mt->type==STRUCT_TYPE || mt->type==UNION_TYPE){
+				if(mt->is_empty) continue;
+				dasm_put(Dst, 638);
+				#if ARM_HF
+				{
+					int hfasize,isfloat;
+					hfasize=hfa_size(L,-2,mt,&isfloat);
+					if(hfasize){
+						switch(hfasize){
+							case 8:
+								dasm_put(Dst, 642);
+								break;
+							case 6:
+								dasm_put(Dst, 644);
+								break;
+							case 4:
+								dasm_put(Dst, 646);
+								break;
+							case 3:
+								dasm_put(Dst, 648);
+								break;
+							case 2:
+								dasm_put(Dst, 650);
+								break;
+							case 1:
+								dasm_put(Dst, 652);
+								break;
+								
+						}
+						save_float(Dst,&regs,hfasize,isfloat);
+						continue;
+					}
+				}
+				#endif
+				
+				if(mt->align_mask>4){//8 byte max alignment 
+					if(regs.ints<4){
+						FIX_ALIGN(regs.ints,2)
+					}else if(!ALIGNED(regs.exs,2)){
+						int diff=regs.exs;
+						regs.exs+=4;
+						dasm_put(Dst, 654);
+					}
+				}
+				int size=ROUND_UP(mt->base_size,4)>>2;
+				dasm_put(Dst, 656, (unsigned short)(mt->base_size), (((unsigned int)(mt->base_size))>>16), (unsigned short)(memcpy), (((unsigned int)(memcpy))>>16));
+				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+size<=MAX_REGS)){//to ensure consective memory for the struct
+					dasm_put(Dst, 666, ((regs.ints<<2)+0x40*1));
+				}else{
+					regs.ints=MAX_REGS;
+					dasm_put(Dst, 669);
+				}
+				dasm_put(Dst, 671);
+				if(regs.ints+size<=MAX_REGS){
+					regs.ints+=size;
+				}else{
+					int ex=regs.ints+size-MAX_REGS;
+					dasm_put(Dst, 673, (ex)<<2);
+					regs.exs+=ex;
+					regs.ints=MAX_REGS;
+				}
+				continue;
+			}
+
+            save_int(Dst,&regs);
+        } else {
+            lua_pop(L, 1);
+            dasm_put(Dst, 676, i);
+
+            switch (mt->type) {
+			case BOOL_TYPE:
+				dasm_put(Dst, 679);
+                save_int(Dst,&regs);
+                break;
+            case INT8_TYPE:
+                dasm_put(Dst, 685);
+                if (mt->is_unsigned) {
+                     dasm_put(Dst, 689);
+                } else {
+                     dasm_put(Dst, 691);
+                }
+                save_int(Dst,&regs);
+                break;
+
+            case INT16_TYPE:
+                dasm_put(Dst, 693);
+                if (mt->is_unsigned) {
+                    dasm_put(Dst, 697);
+                } else {
+                    dasm_put(Dst, 699);
+                }
+                save_int(Dst,&regs);
+                break;
+
+            case INT32_TYPE:
+                if (mt->is_unsigned) {
+                    dasm_put(Dst, 701);
+                } else {
+                    dasm_put(Dst, 705);
+                }
+                save_int(Dst,&regs);
+                break;
+            case INTPTR_TYPE:
+                dasm_put(Dst, 709);
+                save_int(Dst,&regs);
+				break;
+
+            case INT64_TYPE:
+                if (mt->is_unsigned) {
+                    dasm_put(Dst, 713);
+                } else {
+                    dasm_put(Dst, 717);
+                }
+				save_int64(Dst,&regs);
+                break;
+
+            case DOUBLE_TYPE:
+				dasm_put(Dst, 721);
+				save_float(Dst,&regs,2,0);
+                break;
+
+            case FLOAT_TYPE:
+				dasm_put(Dst, 725);
+                save_float(Dst,&regs,1,1);
+                break;
+				
+			case COMPLEX_DOUBLE_TYPE:
+				#if ARM_HF
+				dasm_put(Dst, 729);
+				save_float(Dst,&regs,4,0);
+				#else
+				FIX_ALIGN(regs.ints,2);
+				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+4<=MAX_REGS)){
+				}else{
+					regs.ints=MAX_REGS;
+					if(!ALIGNED(regs.exs,2)){
+						++regs.exs;
+					}
+				}
+				regs.ints+=4;
+				goto FIX_REG;
+				#endif
+				break;
+			case COMPLEX_FLOAT_TYPE:
+				#if ARM_HF
+				dasm_put(Dst, 733);
+				save_float(Dst,&regs,2,1);
+				#else
+				if(regs.ints<MAX_REGS&&(!regs.exs||regs.ints+2<=MAX_REGS)){
+				}else{
+					regs.ints=MAX_REGS;
+				}
+				regs.ints+=2;
+				FIX_REG:
+				if(regs.ints>MAX_REGS){
+					regs.exs+=regs.ints-MAX_REGS;
+					regs.ints=MAX_REGS;
+				}
+				#endif
+                break;
+            default:
+                luaL_error(L, "NYI: call arg type");
+            }
+        }
+    }
+
+    if (ct->has_var_arg) {
+		int offset=nargs+1;
+        dasm_put(Dst, 737, offset);
+		#if ARM_HF
+		    if(regs.ints==4||regs.float_sealed){
+				if(regs.ints<4&&regs.float_sealed){//some arg must be loaded to core registers.
+					dasm_put(Dst, 740, ((regs.ints<<2)+0x40), (0x10+0x40), offset);
+				}
+				dasm_put(Dst, 750);
+			} 
+		#else
+			if(regs.ints==4){
+			}
+		#endif
+		else{//no hard floating point in variadic procedure
+			dasm_put(Dst, 752, ((regs.ints<<2)+1*0x40));
+		}
+        
+        dasm_put(Dst, 755);
+		regs.ints=4;
+    } 
+	
+	#if ARM_HF
+	switch(ROUND_UP(regs.highest_bit,4)>>1){
+		case 8 :
+			dasm_put(Dst, 760);
+			break;
+		case 7 :
+			dasm_put(Dst, 762);
+			break;
+		case 6 :
+			dasm_put(Dst, 764);
+			break;
+		case 5:
+			dasm_put(Dst, 766);
+			break;
+		case 4 :
+			dasm_put(Dst, 768);
+			break;
+		case 3 :
+			dasm_put(Dst, 770);
+			break;
+		case 2 :
+			dasm_put(Dst, 772);
+			break;
+		case 1 :
+			dasm_put(Dst, 774);
+			break;
+	}
+	if(stack_size>0){
+		dasm_put(Dst, 776);
+	}
+	#endif
+	
+	//pop registers from stack,align 8 for some compiler
+	assert(regs.ints<=4);
+	switch(regs.ints){
+	case 4:
+	case 3:
+		dasm_put(Dst, 778);
+		break;
+	case 2:
+	case 1:
+		dasm_put(Dst, 780);
+		#if ARM_HF
+		if(regs.float_sealed){
+			dasm_put(Dst, 782);
+		}
+		#endif
+		break;
+	default:
+		#if ARM_HF
+		if(regs.float_sealed){
+			dasm_put(Dst, 784);
+		}
+		#endif
+		break;
+	}
+	
+	dasm_put(Dst, 786, (unsigned short)(func), (((unsigned int)(func))>>16));
+
+    lua_rawgeti(L, ct_usr, 0);
+    mt = (const struct ctype*) lua_touserdata(L, -1);
+
+    if (mt->pointers || mt->is_reference || mt->type==FUNCTION_PTR_TYPE) {
+        lua_getuservalue(L, -1);
+        num_upvals += 2;
+        dasm_put(Dst, 792, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+
+    } else {
+        switch (mt->type) {
+        case INT64_TYPE:
+        #if LUA_VERSION_NUM>=503
+             lua_pop(L, 1);
+	    #if CK_ALGIN
+            dasm_put(Dst, 807);
+		#else
+            dasm_put(Dst, 810);
+		#endif		
+            dasm_put(Dst, 813);
+            break;
+		#else
+			num_upvals++;
+            dasm_put(Dst, 818, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+            break;
+        #endif
+		
+        case INTPTR_TYPE:
+            num_upvals++;
+            dasm_put(Dst, 832, (unsigned short)(mt), (((unsigned int)(mt))>>16));
+            break;
+
+        case VOID_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 844);
+            break;
+
+        case BOOL_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 846);
+            break;
+
+        case INT8_TYPE:
+        case INT16_TYPE:
+        case INT32_TYPE:
+        case ENUM_TYPE:// value must be narrowed before callee return
+            lua_pop(L, 1);
+			
+            dasm_put(Dst, 852);
+            if (mt->is_unsigned) {
+                dasm_put(Dst, 854);
+            } else {
+                dasm_put(Dst, 858);
+            }
+			
+            dasm_put(Dst, 862);
+            break;
+
+        case FLOAT_TYPE:
+            lua_pop(L, 1);
+            dasm_put(Dst, 864);
+            break;
+
+        case DOUBLE_TYPE:
+            lua_pop(L, 1);
+        #if CK_ALGIN
+		#else
+		#endif	
+            dasm_put(Dst, 869);
+            break;
+		case COMPLEX_DOUBLE_TYPE:
+		case COMPLEX_FLOAT_TYPE:
+		case STRUCT_TYPE:
+		case UNION_TYPE:{
+			lua_getuservalue(L,-1);
+            num_upvals += 2;
+			#if ARM_HF
+			{
+				int isfloat,hfasize=hfa_size(L,-2,mt,&isfloat);
+				if(hfasize>0){
+					switch(hfasize){
+						case 8:
+							dasm_put(Dst, 874);
+							break;
+						case 6:
+							dasm_put(Dst, 876);
+							break;
+						case 4:
+						case 3:
+							dasm_put(Dst, 878);
+							break;
+						case 2:
+						case 1:
+							dasm_put(Dst, 880);
+							break;
+							
+					}
+					dasm_put(Dst, 882, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+					switch(hfasize){
+						case 8:
+							dasm_put(Dst, 895);
+							break;
+						case 6:
+							dasm_put(Dst, 898);
+							break;
+						case 4:
+							dasm_put(Dst, 901);
+							break;
+						case 3:
+							dasm_put(Dst, 904);
+							break;
+						case 2:
+							dasm_put(Dst, 907);
+							break;
+						case 1:
+							dasm_put(Dst, 910);
+							break;
+							
+					}
+					dasm_put(Dst, 913);
+					break;
+				}
+			}
+			
+			#endif
+			if(mt->base_size>4){
+				// value are stored in return storage in r0 for softfp, set usr value here
+				if(!lua_isnil(L,-1)){
+					dasm_put(Dst, 915, (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+				}
+			}else if(mt->is_empty){
+				dasm_put(Dst, 927);
+				break;
+			}else{
+				dasm_put(Dst, 929, (unsigned short)(mt), (((unsigned int)(mt))>>16), (unsigned short)(lua_upvalueindex(num_upvals)), (((unsigned int)(lua_upvalueindex(num_upvals)))>>16));
+			}
+            dasm_put(Dst, 943);
+			break;
+		}	
+        default:
+            luaL_error(L, "NYI: call return type");
+        }
+    }
+
+#ifdef __thumb__
+    dasm_put(Dst, 945);
+#else	
+    dasm_put(Dst, 948);
+#endif	
+    assert(lua_gettop(L) == top + num_upvals);
+    {
+        cfunction f = compile(Dst, L, NULL, LUA_NOREF);
+        /* add a callback as an upval so that the jitted code gets cleaned up when
+         * the function gets gc'd */
+        push_callback(L, f, func);
+        lua_pushcclosure(L, (lua_CFunction) f, num_upvals+1);
+    }
+}
+
diff --git a/source/texk/web2c/luatexdir/luaffi/ctype.c b/source/texk/web2c/luatexdir/luaffi/ctype.c
index 18ad5f21e..e53513eb4 100644
--- a/source/texk/web2c/luatexdir/luaffi/ctype.c
+++ b/source/texk/web2c/luatexdir/luaffi/ctype.c
@@ -1,315 +1,315 @@
-/* vim: ts=4 sw=4 sts=4 et tw=78
- * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
- * Portions copyright (c) 2011 James R. McKaskill.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-#include <ctype.h>
-#include "ffi.h"
-
-static int to_define_key;
-
-static void update_on_definition(lua_State* L, int ct_usr, int ct_idx)
-{
-    ct_usr = lua_absindex(L, ct_usr);
-    ct_idx = lua_absindex(L, ct_idx);
-
-    lua_pushlightuserdata(L, &to_define_key);
-    lua_rawget(L, ct_usr);
-
-    if (lua_isnil(L, -1)) {
-        lua_pop(L, 1); /* pop the nil */
-
-        /* {} */
-        lua_newtable(L);
-
-        /* {__mode='k'} */
-        lua_newtable(L);
-        lua_pushliteral(L, "k");
-        lua_setfield(L, -2, "__mode");
-
-        /* setmetatable({}, {__mode='k'}) */
-        lua_setmetatable(L, -2);
-
-        /* usr[TO_UPDATE_KEY] = setmetatable({}, {__mode='k'}) */
-        lua_pushlightuserdata(L, &to_define_key);
-        lua_pushvalue(L, -2);
-        lua_rawset(L, ct_usr);
-
-        /* leave the table on the stack */
-    }
-
-    /* to_update[ctype or cdata] = true */
-    lua_pushvalue(L, ct_idx);
-    lua_pushboolean(L, 1);
-    lua_rawset(L, -3);
-
-    /* pop the to_update table */
-    lua_pop(L, 1);
-}
-
-void set_defined(lua_State* L, int ct_usr, struct ctype* ct)
-{
-    ct_usr = lua_absindex(L, ct_usr);
-
-    ct->is_defined = 1;
-
-    /* update ctypes and cdatas that were created before the definition came in */
-    lua_pushlightuserdata(L, &to_define_key);
-    lua_rawget(L, ct_usr);
-
-    if (!lua_isnil(L, -1)) {
-        lua_pushnil(L);
-
-        while (lua_next(L, -2)) {
-            struct ctype* upd = (struct ctype*) lua_touserdata(L, -2);
-            upd->base_size = ct->base_size;
-            upd->align_mask = ct->align_mask;
-            upd->is_defined = 1;
-            upd->is_variable_struct = ct->is_variable_struct;
-            upd->variable_increment = ct->variable_increment;
-            assert(!upd->variable_size_known);
-            lua_pop(L, 1);
-        }
-
-        lua_pop(L, 1);
-        /* usr[TO_UPDATE_KEY] = nil */
-        lua_pushlightuserdata(L, &to_define_key);
-        lua_pushnil(L);
-        lua_rawset(L, ct_usr);
-    } else {
-        lua_pop(L, 1);
-    }
-}
-void setup_ctype(lua_State* L,int ct_usr,const struct ctype* ct){
-    push_upval(L, &ctype_mt_key);
-    lua_setmetatable(L, -2);
-
-#if LUA_VERSION_NUM == 501
-    if (!ct_usr || lua_isnil(L, ct_usr)) {
-        push_upval(L, &niluv_key);
-        lua_setfenv(L, -2);
-    }
-#endif
-
-    if (ct_usr && !lua_isnil(L, ct_usr)) {
-        lua_pushvalue(L, ct_usr);
-        lua_setuservalue(L, -2);
-    }
-
-    if (!ct->is_defined && ct_usr && !lua_isnil(L, ct_usr)) {
-        update_on_definition(L, ct_usr, -1);
-    }
-}
-struct member_type* push_member_type(lua_State* L, int ct_usr, const struct member_type* mt)
-{
-    struct member_type* ret;
-    ct_usr = lua_absindex(L, ct_usr);
-
-    ret = (struct member_type*) lua_newuserdata(L, sizeof(struct member_type));
-    *ret = *mt;
-
-    setup_ctype(L,ct_usr,&mt->ct);
-
-    return ret;
-}
-
-struct ctype* push_ctype(lua_State* L, int ct_usr, const struct ctype* ct)
-{
-    struct ctype* ret;
-    ct_usr = lua_absindex(L, ct_usr);
-
-    ret = (struct ctype*) lua_newuserdata(L, sizeof(struct ctype));
-    *ret = *ct;
-
-    setup_ctype(L,ct_usr,ct);
-
-    return ret;
-}
-
-size_t ctype_size(lua_State* L, const struct ctype* ct)
-{
-    if (ct->pointers - ct->is_array) {
-        return sizeof(void*) * (ct->is_array ? ct->array_size : 1);
-
-    } else if (!ct->is_defined || ct->type == VOID_TYPE) {
-        return luaL_error(L, "can't calculate size of an undefined type");
-
-    } else if (ct->variable_size_known) {
-        assert(ct->is_variable_struct && !ct->is_array);
-        return ct->base_size + ct->variable_increment;
-
-    } else if (ct->is_variable_array || ct->is_variable_struct) {
-        return luaL_error(L, "internal error: calc size of variable type with unknown size");
-
-    } else {
-        return ct->base_size * (ct->is_array ? ct->array_size : 1);
-    }
-}
-
-void* push_cdata(lua_State* L, int ct_usr, const struct ctype* ct)
-{
-    struct cdata* cd;
-    size_t sz = ct->is_reference ? sizeof(void*) : ctype_size(L, ct);
-    ct_usr = lua_absindex(L, ct_usr);
-
-    /* This is to stop valgrind from complaining. Bitfields are accessed in 8
-     * byte chunks so that the code doesn't have to deal with different access
-     * patterns, but this means that occasionally it will read past the end of
-     * the struct. As its not setting the bits past the end (only reading and
-     * then writing the bits back) and the read is aligned its a non-issue,
-     * but valgrind complains nonetheless.
-     */
-    /* Changed:To allow fast write to memory for struct in 64-bit machine in jit
-     */
-    //if (ct->has_bitfield) {
-        sz = ALIGN_UP(sz, 7);
-    //}
-
-    cd = (struct cdata*) lua_newuserdata(L, sizeof(struct cdata) + sz);
-    *(struct ctype*) &cd->type = *ct;
-    memset(cd+1, 0, sz);
-
-    /* TODO: handle cases where lua_newuserdata returns a pointer that is not
-     * aligned */
-#if 0
-    assert((uintptr_t) (cd + 1) % 8 == 0);
-#endif
-
-#if LUA_VERSION_NUM == 501
-    if (!ct_usr || lua_isnil(L, ct_usr)) {
-        push_upval(L, &niluv_key);
-        lua_setfenv(L, -2);
-    }
-#endif
-
-    if (ct_usr && !lua_isnil(L, ct_usr)) {
-        lua_pushvalue(L, ct_usr);
-        lua_setuservalue(L, -2);
-    }
-
-    push_upval(L, &cdata_mt_key);
-    lua_setmetatable(L, -2);
-
-    if (!ct->is_defined && ct_usr && !lua_isnil(L, ct_usr)) {
-        update_on_definition(L, ct_usr, -1);
-    }
-
-    return cd+1;
-}
-
-void push_callback(lua_State* L, cfunction luafunc, cfunction cfunc)
-{
-    cfunction* pf = (cfunction*) lua_newuserdata(L, 2 * sizeof(cfunction));
-    pf[0] = luafunc;
-    pf[1] = cfunc;
-
-    push_upval(L, &callback_mt_key);
-    lua_setmetatable(L, -2);
-}
-
-/* returns the value as a ctype, pushes the user value onto the stack */
-void check_ctype(lua_State* L, int idx, struct ctype* ct)
-{
-    if (lua_isstring(L, idx)) {
-        struct parser P;char ch;
-        P.line = 1;
-        P.prev = P.next = lua_tostring(L, idx);
-        P.align_mask = DEFAULT_ALIGN_MASK;
-        parse_type(L, &P, ct);
-        parse_argument(L, &P, -1, ct, NULL, NULL, 0);
-        ch=P.next[0];
-        if(ch&&!isspace(ch)){
-            luaL_error(L,"unexpected end of type name :%s",P.next);
-        }
-        lua_remove(L, -2); /* remove the user value from parse_type */
-
-    } else if (lua_getmetatable(L, idx)) {
-        if (!equals_upval(L, -1, &ctype_mt_key)
-                && !equals_upval(L, -1, &cdata_mt_key)) {
-            goto err;
-        }
-
-        lua_pop(L, 1); /* pop the metatable */
-        *ct = *(struct ctype*) lua_touserdata(L, idx);
-        lua_getuservalue(L, idx);
-
-    } else {
-        goto err;
-    }
-
-    return;
-
-err:
-    luaL_error(L, "expected cdata, ctype or string for arg #%d", idx);
-}
-
-static ALWAYS_INLINE int is_cdata(lua_State* L, int idx){
-    if (!lua_isuserdata(L, idx) || !lua_getmetatable(L, idx)) {
-        lua_pushnil(L);
-        return 0;
-    }
-
-    if (!equals_upval(L, -1, &cdata_mt_key)) {
-        lua_pop(L, 1); /* mt */
-        lua_pushnil(L);
-        return 0;
-    }
-    lua_pop(L, 1); /* mt */
-    return 1;
-}
-
-/**
- * get_ctype return the type for the c_data on idx
- * @param L
- * @param idx
- * @return
- */
-const struct ctype* get_ctype(lua_State* L, int idx){
-
-    if(!is_cdata(L,idx))
-        return NULL;
-
-    return  &((struct cdata*) lua_touserdata(L, idx))->type;
-
-}
-/* to_cdata returns the struct cdata* and pushes the user value onto the
- * stack. If the index is not a ctype then ct is set to the zero value such
- * that ct->type is INVALID_TYPE, a nil is pushed, and NULL is returned. */
-void* to_cdata(lua_State* L, int idx, struct ctype* ct)
-{
-    struct cdata* cd;
-
-    memset(ct, 0, sizeof(struct ctype));
-
-    if(!is_cdata(L,idx))
-        return NULL;
-
-    cd = (struct cdata*) lua_touserdata(L, idx);
-    *ct = cd->type;
-    lua_getuservalue(L, idx);
-
-    if (ct->is_reference) {
-        return *(void**) (cd+1);
-
-    } else if (ct->pointers && !ct->is_array) {
-        return *(void**) (cd+1);
-
-    } else {
-        return cd + 1;
-    }
-}
-
-/* check_cdata returns the struct cdata* and pushes the user value onto the
- * stack. Also dereferences references. */
-void* check_cdata(lua_State* L, int idx, struct ctype* ct)
-{
-    void* p = to_cdata(L, idx, ct);
-    if (ct->type == INVALID_TYPE) {
-        luaL_error(L, "expected cdata for arg #%d", idx);
-    }
-    return p;
-}
-
+/* vim: ts=4 sw=4 sts=4 et tw=78
+ * Portions copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+ * Portions copyright (c) 2011 James R. McKaskill.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+#include <ctype.h>
+#include "ffi.h"
+
+static int to_define_key;
+
+static void update_on_definition(lua_State* L, int ct_usr, int ct_idx)
+{
+    ct_usr = lua_absindex(L, ct_usr);
+    ct_idx = lua_absindex(L, ct_idx);
+
+    lua_pushlightuserdata(L, &to_define_key);
+    lua_rawget(L, ct_usr);
+
+    if (lua_isnil(L, -1)) {
+        lua_pop(L, 1); /* pop the nil */
+
+        /* {} */
+        lua_newtable(L);
+
+        /* {__mode='k'} */
+        lua_newtable(L);
+        lua_pushliteral(L, "k");
+        lua_setfield(L, -2, "__mode");
+
+        /* setmetatable({}, {__mode='k'}) */
+        lua_setmetatable(L, -2);
+
+        /* usr[TO_UPDATE_KEY] = setmetatable({}, {__mode='k'}) */
+        lua_pushlightuserdata(L, &to_define_key);
+        lua_pushvalue(L, -2);
+        lua_rawset(L, ct_usr);
+
+        /* leave the table on the stack */
+    }
+
+    /* to_update[ctype or cdata] = true */
+    lua_pushvalue(L, ct_idx);
+    lua_pushboolean(L, 1);
+    lua_rawset(L, -3);
+
+    /* pop the to_update table */
+    lua_pop(L, 1);
+}
+
+void set_defined(lua_State* L, int ct_usr, struct ctype* ct)
+{
+    ct_usr = lua_absindex(L, ct_usr);
+
+    ct->is_defined = 1;
+
+    /* update ctypes and cdatas that were created before the definition came in */
+    lua_pushlightuserdata(L, &to_define_key);
+    lua_rawget(L, ct_usr);
+
+    if (!lua_isnil(L, -1)) {
+        lua_pushnil(L);
+
+        while (lua_next(L, -2)) {
+            struct ctype* upd = (struct ctype*) lua_touserdata(L, -2);
+            upd->base_size = ct->base_size;
+            upd->align_mask = ct->align_mask;
+            upd->is_defined = 1;
+            upd->is_variable_struct = ct->is_variable_struct;
+            upd->variable_increment = ct->variable_increment;
+            assert(!upd->variable_size_known);
+            lua_pop(L, 1);
+        }
+
+        lua_pop(L, 1);
+        /* usr[TO_UPDATE_KEY] = nil */
+        lua_pushlightuserdata(L, &to_define_key);
+        lua_pushnil(L);
+        lua_rawset(L, ct_usr);
+    } else {
+        lua_pop(L, 1);
+    }
+}
+void setup_ctype(lua_State* L,int ct_usr,const struct ctype* ct){
+    push_upval(L, &ctype_mt_key);
+    lua_setmetatable(L, -2);
+
+#if LUA_VERSION_NUM == 501
+    if (!ct_usr || lua_isnil(L, ct_usr)) {
+        push_upval(L, &niluv_key);
+        lua_setfenv(L, -2);
+    }
+#endif
+
+    if (ct_usr && !lua_isnil(L, ct_usr)) {
+        lua_pushvalue(L, ct_usr);
+        lua_setuservalue(L, -2);
+    }
+
+    if (!ct->is_defined && ct_usr && !lua_isnil(L, ct_usr)) {
+        update_on_definition(L, ct_usr, -1);
+    }
+}
+struct member_type* push_member_type(lua_State* L, int ct_usr, const struct member_type* mt)
+{
+    struct member_type* ret;
+    ct_usr = lua_absindex(L, ct_usr);
+
+    ret = (struct member_type*) lua_newuserdata(L, sizeof(struct member_type));
+    *ret = *mt;
+
+    setup_ctype(L,ct_usr,&mt->ct);
+
+    return ret;
+}
+
+struct ctype* push_ctype(lua_State* L, int ct_usr, const struct ctype* ct)
+{
+    struct ctype* ret;
+    ct_usr = lua_absindex(L, ct_usr);
+
+    ret = (struct ctype*) lua_newuserdata(L, sizeof(struct ctype));
+    *ret = *ct;
+
+    setup_ctype(L,ct_usr,ct);
+
+    return ret;
+}
+
+size_t ctype_size(lua_State* L, const struct ctype* ct)
+{
+    if (ct->pointers - ct->is_array) {
+        return sizeof(void*) * (ct->is_array ? ct->array_size : 1);
+
+    } else if (!ct->is_defined || ct->type == VOID_TYPE) {
+        return luaL_error(L, "can't calculate size of an undefined type");
+
+    } else if (ct->variable_size_known) {
+        assert(ct->is_variable_struct && !ct->is_array);
+        return ct->base_size + ct->variable_increment;
+
+    } else if (ct->is_variable_array || ct->is_variable_struct) {
+        return luaL_error(L, "internal error: calc size of variable type with unknown size");
+
+    } else {
+        return ct->base_size * (ct->is_array ? ct->array_size : 1);
+    }
+}
+
+void* push_cdata(lua_State* L, int ct_usr, const struct ctype* ct)
+{
+    struct cdata* cd;
+    size_t sz = ct->is_reference ? sizeof(void*) : ctype_size(L, ct);
+    ct_usr = lua_absindex(L, ct_usr);
+
+    /* This is to stop valgrind from complaining. Bitfields are accessed in 8
+     * byte chunks so that the code doesn't have to deal with different access
+     * patterns, but this means that occasionally it will read past the end of
+     * the struct. As its not setting the bits past the end (only reading and
+     * then writing the bits back) and the read is aligned its a non-issue,
+     * but valgrind complains nonetheless.
+     */
+    /* Changed:To allow fast write to memory for struct in 64-bit machine in jit
+     */
+    //if (ct->has_bitfield) {
+        sz = ALIGN_UP(sz, 7);
+    //}
+
+    cd = (struct cdata*) lua_newuserdata(L, sizeof(struct cdata) + sz);
+    *(struct ctype*) &cd->type = *ct;
+    memset(cd+1, 0, sz);
+
+    /* TODO: handle cases where lua_newuserdata returns a pointer that is not
+     * aligned */
+#if 0
+    assert((uintptr_t) (cd + 1) % 8 == 0);
+#endif
+
+#if LUA_VERSION_NUM == 501
+    if (!ct_usr || lua_isnil(L, ct_usr)) {
+        push_upval(L, &niluv_key);
+        lua_setfenv(L, -2);
+    }
+#endif
+
+    if (ct_usr && !lua_isnil(L, ct_usr)) {
+        lua_pushvalue(L, ct_usr);
+        lua_setuservalue(L, -2);
+    }
+
+    push_upval(L, &cdata_mt_key);
+    lua_setmetatable(L, -2);
+
+    if (!ct->is_defined && ct_usr && !lua_isnil(L, ct_usr)) {
+        update_on_definition(L, ct_usr, -1);
+    }
+
+    return cd+1;
+}
+
+void push_callback(lua_State* L, cfunction luafunc, cfunction cfunc)
+{
+    cfunction* pf = (cfunction*) lua_newuserdata(L, 2 * sizeof(cfunction));
+    pf[0] = luafunc;
+    pf[1] = cfunc;
+
+    push_upval(L, &callback_mt_key);
+    lua_setmetatable(L, -2);
+}
+
+/* returns the value as a ctype, pushes the user value onto the stack */
+void check_ctype(lua_State* L, int idx, struct ctype* ct)
+{
+    if (lua_isstring(L, idx)) {
+        struct parser P;char ch;
+        P.line = 1;
+        P.prev = P.next = lua_tostring(L, idx);
+        P.align_mask = DEFAULT_ALIGN_MASK;
+        parse_type(L, &P, ct);
+        parse_argument(L, &P, -1, ct, NULL, NULL, 0);
+        ch=P.next[0];
+        if(ch&&!isspace(ch)){
+            luaL_error(L,"unexpected end of type name :%s",P.next);
+        }
+        lua_remove(L, -2); /* remove the user value from parse_type */
+
+    } else if (lua_getmetatable(L, idx)) {
+        if (!equals_upval(L, -1, &ctype_mt_key)
+                && !equals_upval(L, -1, &cdata_mt_key)) {
+            goto err;
+        }
+
+        lua_pop(L, 1); /* pop the metatable */
+        *ct = *(struct ctype*) lua_touserdata(L, idx);
+        lua_getuservalue(L, idx);
+
+    } else {
+        goto err;
+    }
+
+    return;
+
+err:
+    luaL_error(L, "expected cdata, ctype or string for arg #%d", idx);
+}
+
+static ALWAYS_INLINE int is_cdata(lua_State* L, int idx){
+    if (!lua_isuserdata(L, idx) || !lua_getmetatable(L, idx)) {
+        lua_pushnil(L);
+        return 0;
+    }
+
+    if (!equals_upval(L, -1, &cdata_mt_key)) {
+        lua_pop(L, 1); /* mt */
+        lua_pushnil(L);
+        return 0;
+    }
+    lua_pop(L, 1); /* mt */
+    return 1;
+}
+
+/**
+ * get_ctype return the type for the c_data on idx
+ * @param L
+ * @param idx
+ * @return
+ */
+const struct ctype* get_ctype(lua_State* L, int idx){
+
+    if(!is_cdata(L,idx))
+        return NULL;
+
+    return  &((struct cdata*) lua_touserdata(L, idx))->type;
+
+}
+/* to_cdata returns the struct cdata* and pushes the user value onto the
+ * stack. If the index is not a ctype then ct is set to the zero value such
+ * that ct->type is INVALID_TYPE, a nil is pushed, and NULL is returned. */
+void* to_cdata(lua_State* L, int idx, struct ctype* ct)
+{
+    struct cdata* cd;
+
+    memset(ct, 0, sizeof(struct ctype));
+
+    if(!is_cdata(L,idx))
+        return NULL;
+
+    cd = (struct cdata*) lua_touserdata(L, idx);
+    *ct = cd->type;
+    lua_getuservalue(L, idx);
+
+    if (ct->is_reference) {
+        return *(void**) (cd+1);
+
+    } else if (ct->pointers && !ct->is_array) {
+        return *(void**) (cd+1);
+
+    } else {
+        return cd + 1;
+    }
+}
+
+/* check_cdata returns the struct cdata* and pushes the user value onto the
+ * stack. Also dereferences references. */
+void* check_cdata(lua_State* L, int idx, struct ctype* ct)
+{
+    void* p = to_cdata(L, idx, ct);
+    if (ct->type == INVALID_TYPE) {
+        luaL_error(L, "expected cdata for arg #%d", idx);
+    }
+    return p;
+}
+
diff --git a/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.c b/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.c
index 405c12a0c..6ee97b827 100644
--- a/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.c
+++ b/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.c
@@ -1,165 +1,165 @@
-
-
-#include "fake_dlfcn.h"
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <elf.h>
-#include <android/log.h>
-
-#define TAG_NAME	"Osl_DL"
-#ifdef NDEBUG
-#define log_info(fmt,args...)
-#define log_err(fmt,args...)
-#else
-#define log_info(fmt,args...) __android_log_print(ANDROID_LOG_INFO, TAG_NAME, (const char *) fmt, ##args)
-#define log_err(fmt,args...) __android_log_print(ANDROID_LOG_ERROR, TAG_NAME, (const char *) fmt, ##args)
-#endif
-//#ifdef LOG_DBG
-#define log_dbg log_info
-//#else
-//#define log_dbg(...)
-//#endif
-
-#ifdef __LP64__
-#define Elf_Ehdr Elf64_Ehdr
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym  Elf64_Sym
-#else
-#define Elf_Ehdr Elf32_Ehdr
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym  Elf32_Sym
-#endif
-
-struct ctx {
-    void *load_addr;
-    void *dynstr;
-    void *dynsym;
-    int nsyms;
-    off_t bias;
-};
-
-//extern "C" {
-void fake_dlclose(void *handle) {
-    if (handle) {
-        struct ctx *ctx = (struct ctx *) handle;
-        if (ctx->dynsym) free(ctx->dynsym);    /* we're saving dynsym and dynstr */
-        if (ctx->dynstr) free(ctx->dynstr);    /* from library file just in case */
-        free(ctx);
-    }
-}
-
-/* flags are ignored */
-
-void *fake_dlopen(const char *libpath, int flags) {
-    FILE *maps;
-    char buff[256];
-    struct ctx *ctx = 0;
-    off_t load_addr, size;
-    int k, fd = -1, found = 0;
-    void *shoff;
-    Elf_Ehdr *elf = (Elf_Ehdr *) MAP_FAILED;
-
-#define fatal(fmt, args...) do { log_err(fmt,##args); goto err_exit; } while(0)
-
-    maps = fopen("/proc/self/maps", "r");
-    if (!maps) fatal("failed to open maps");
-
-    while (!found && fgets(buff, sizeof(buff), maps))
-        if (strstr(buff, "r-xp") && strstr(buff, libpath)) found = 1;
-
-    fclose(maps);
-
-    if (!found) fatal("%s not found in my userspace", libpath);
-
-    if (sscanf(buff, "%lx", &load_addr) != 1)
-        fatal("failed to read load address for %s", libpath);
-
-    log_info("%s loaded in Android at 0x%08lx", libpath, load_addr);
-
-    /* Now, mmap the same library once again */
-
-    fd = open(libpath, O_RDONLY);
-    if (fd < 0) fatal("failed to open %s", libpath);
-
-    size = lseek(fd, 0, SEEK_END);
-    if (size <= 0) fatal("lseek() failed for %s", libpath);
-
-    elf = (Elf_Ehdr *) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
-    close(fd);
-    fd = -1;
-
-    if (elf == MAP_FAILED) fatal("mmap() failed for %s", libpath);
-
-    ctx = (struct ctx *) calloc(1, sizeof(struct ctx));
-    if (!ctx) fatal("no memory for %s", libpath);
-
-    ctx->load_addr = (void *) load_addr;
-    shoff = ((void *) elf) + elf->e_shoff;
-    for (k = 0; k < elf->e_shnum; k++, shoff += elf->e_shentsize) {
-
-        Elf_Shdr *sh = (Elf_Shdr *) shoff;
-        //log_dbg("%s: k=%d shdr=%p type=%x", __func__, k, sh, sh->sh_type);
-
-        switch (sh->sh_type) {
-
-            case SHT_DYNSYM:
-                if (ctx->dynsym) fatal("%s: duplicate DYNSYM sections", libpath); /* .dynsym */
-                ctx->dynsym = malloc(sh->sh_size);
-                if (!ctx->dynsym) fatal("%s: no memory for .dynsym", libpath);
-                memcpy(ctx->dynsym, ((void *) elf) + sh->sh_offset, sh->sh_size);
-                ctx->nsyms = (sh->sh_size / sizeof(Elf_Sym));
-                break;
-
-            case SHT_STRTAB:
-                if (ctx->dynstr) break;    /* .dynstr is guaranteed to be the first STRTAB */
-                ctx->dynstr = malloc(sh->sh_size);
-                if (!ctx->dynstr) fatal("%s: no memory for .dynstr", libpath);
-                memcpy(ctx->dynstr, ((void *) elf) + sh->sh_offset, sh->sh_size);
-                break;
-
-            case SHT_PROGBITS:
-                if (!ctx->dynstr || !ctx->dynsym) break;
-                /* won't even bother checking against the section name */
-                ctx->bias = (off_t) sh->sh_addr - (off_t) sh->sh_offset;
-                k = elf->e_shnum;  /* exit for */
-                break;
-        }
-    }
-
-    munmap(elf, size);
-    elf = 0;
-
-    if (!ctx->dynstr || !ctx->dynsym) fatal("dynamic sections not found in %s", libpath);
-
-#undef fatal
-
-    log_dbg("%s: ok, dynsym = %p, dynstr = %p", libpath, ctx->dynsym, ctx->dynstr);
-
-    return ctx;
-
-    err_exit:
-    if (fd >= 0) close(fd);
-    if (elf != MAP_FAILED) munmap(elf, size);
-    fake_dlclose(ctx);
-    return 0;
-}
-
-void *fake_dlsym(void *handle, const char *name) {
-    int k;
-    struct ctx *ctx = (struct ctx *) handle;
-    Elf_Sym *sym = (Elf_Sym *) ctx->dynsym;
-    char *strings = (char *) ctx->dynstr;
-
-    for (k = 0; k < ctx->nsyms; k++, sym++)
-        if (strcmp(strings + sym->st_name, name) == 0) {
-            /*  NB: sym->st_value is an offset into the section for relocatables,
-            but a VMA for shared libs or exe files, so we have to subtract the bias */
-            void *ret = ctx->load_addr + sym->st_value - ctx->bias;
-            log_info("%s found at %p", name, ret);
-            return ret;
-        }
-    return 0;
-}
+
+
+#include "fake_dlfcn.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <elf.h>
+#include <android/log.h>
+
+#define TAG_NAME	"Osl_DL"
+#ifdef NDEBUG
+#define log_info(fmt,args...)
+#define log_err(fmt,args...)
+#else
+#define log_info(fmt,args...) __android_log_print(ANDROID_LOG_INFO, TAG_NAME, (const char *) fmt, ##args)
+#define log_err(fmt,args...) __android_log_print(ANDROID_LOG_ERROR, TAG_NAME, (const char *) fmt, ##args)
+#endif
+//#ifdef LOG_DBG
+#define log_dbg log_info
+//#else
+//#define log_dbg(...)
+//#endif
+
+#ifdef __LP64__
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym  Elf64_Sym
+#else
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym  Elf32_Sym
+#endif
+
+struct ctx {
+    void *load_addr;
+    void *dynstr;
+    void *dynsym;
+    int nsyms;
+    off_t bias;
+};
+
+//extern "C" {
+void fake_dlclose(void *handle) {
+    if (handle) {
+        struct ctx *ctx = (struct ctx *) handle;
+        if (ctx->dynsym) free(ctx->dynsym);    /* we're saving dynsym and dynstr */
+        if (ctx->dynstr) free(ctx->dynstr);    /* from library file just in case */
+        free(ctx);
+    }
+}
+
+/* flags are ignored */
+
+void *fake_dlopen(const char *libpath, int flags) {
+    FILE *maps;
+    char buff[256];
+    struct ctx *ctx = 0;
+    off_t load_addr, size;
+    int k, fd = -1, found = 0;
+    void *shoff;
+    Elf_Ehdr *elf = (Elf_Ehdr *) MAP_FAILED;
+
+#define fatal(fmt, args...) do { log_err(fmt,##args); goto err_exit; } while(0)
+
+    maps = fopen("/proc/self/maps", "r");
+    if (!maps) fatal("failed to open maps");
+
+    while (!found && fgets(buff, sizeof(buff), maps))
+        if (strstr(buff, "r-xp") && strstr(buff, libpath)) found = 1;
+
+    fclose(maps);
+
+    if (!found) fatal("%s not found in my userspace", libpath);
+
+    if (sscanf(buff, "%lx", &load_addr) != 1)
+        fatal("failed to read load address for %s", libpath);
+
+    log_info("%s loaded in Android at 0x%08lx", libpath, load_addr);
+
+    /* Now, mmap the same library once again */
+
+    fd = open(libpath, O_RDONLY);
+    if (fd < 0) fatal("failed to open %s", libpath);
+
+    size = lseek(fd, 0, SEEK_END);
+    if (size <= 0) fatal("lseek() failed for %s", libpath);
+
+    elf = (Elf_Ehdr *) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
+    close(fd);
+    fd = -1;
+
+    if (elf == MAP_FAILED) fatal("mmap() failed for %s", libpath);
+
+    ctx = (struct ctx *) calloc(1, sizeof(struct ctx));
+    if (!ctx) fatal("no memory for %s", libpath);
+
+    ctx->load_addr = (void *) load_addr;
+    shoff = ((void *) elf) + elf->e_shoff;
+    for (k = 0; k < elf->e_shnum; k++, shoff += elf->e_shentsize) {
+
+        Elf_Shdr *sh = (Elf_Shdr *) shoff;
+        //log_dbg("%s: k=%d shdr=%p type=%x", __func__, k, sh, sh->sh_type);
+
+        switch (sh->sh_type) {
+
+            case SHT_DYNSYM:
+                if (ctx->dynsym) fatal("%s: duplicate DYNSYM sections", libpath); /* .dynsym */
+                ctx->dynsym = malloc(sh->sh_size);
+                if (!ctx->dynsym) fatal("%s: no memory for .dynsym", libpath);
+                memcpy(ctx->dynsym, ((void *) elf) + sh->sh_offset, sh->sh_size);
+                ctx->nsyms = (sh->sh_size / sizeof(Elf_Sym));
+                break;
+
+            case SHT_STRTAB:
+                if (ctx->dynstr) break;    /* .dynstr is guaranteed to be the first STRTAB */
+                ctx->dynstr = malloc(sh->sh_size);
+                if (!ctx->dynstr) fatal("%s: no memory for .dynstr", libpath);
+                memcpy(ctx->dynstr, ((void *) elf) + sh->sh_offset, sh->sh_size);
+                break;
+
+            case SHT_PROGBITS:
+                if (!ctx->dynstr || !ctx->dynsym) break;
+                /* won't even bother checking against the section name */
+                ctx->bias = (off_t) sh->sh_addr - (off_t) sh->sh_offset;
+                k = elf->e_shnum;  /* exit for */
+                break;
+        }
+    }
+
+    munmap(elf, size);
+    elf = 0;
+
+    if (!ctx->dynstr || !ctx->dynsym) fatal("dynamic sections not found in %s", libpath);
+
+#undef fatal
+
+    log_dbg("%s: ok, dynsym = %p, dynstr = %p", libpath, ctx->dynsym, ctx->dynstr);
+
+    return ctx;
+
+    err_exit:
+    if (fd >= 0) close(fd);
+    if (elf != MAP_FAILED) munmap(elf, size);
+    fake_dlclose(ctx);
+    return 0;
+}
+
+void *fake_dlsym(void *handle, const char *name) {
+    int k;
+    struct ctx *ctx = (struct ctx *) handle;
+    Elf_Sym *sym = (Elf_Sym *) ctx->dynsym;
+    char *strings = (char *) ctx->dynstr;
+
+    for (k = 0; k < ctx->nsyms; k++, sym++)
+        if (strcmp(strings + sym->st_name, name) == 0) {
+            /*  NB: sym->st_value is an offset into the section for relocatables,
+            but a VMA for shared libs or exe files, so we have to subtract the bias */
+            void *ret = ctx->load_addr + sym->st_value - ctx->bias;
+            log_info("%s found at %p", name, ret);
+            return ret;
+        }
+    return 0;
+}
 //}
\ No newline at end of file
diff --git a/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.h b/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.h
index b8fb6e36b..f2eae6c95 100644
--- a/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.h
+++ b/source/texk/web2c/luatexdir/luaffi/fake_dlfcn.h
@@ -1,20 +1,20 @@
-
-
-#ifndef HOOKMANAGER_FAKE_DLFCN_H
-#define HOOKMANAGER_FAKE_DLFCN_H
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-__attribute__ ((visibility ("default"))) void *fake_dlopen(const char *libpath, int flags);
-__attribute__ ((visibility ("default"))) void fake_dlclose(void* handle);
-__attribute__ ((visibility ("default"))) void *fake_dlsym(void *handle, const char *name);
-#ifdef __cplusplus
-};
-#endif
-#endif //HOOKMANAGER_FAKE_DLFCN_H
+
+
+#ifndef HOOKMANAGER_FAKE_DLFCN_H
+#define HOOKMANAGER_FAKE_DLFCN_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+__attribute__ ((visibility ("default"))) void *fake_dlopen(const char *libpath, int flags);
+__attribute__ ((visibility ("default"))) void fake_dlclose(void* handle);
+__attribute__ ((visibility ("default"))) void *fake_dlsym(void *handle, const char *name);
+#ifdef __cplusplus
+};
+#endif
+#endif //HOOKMANAGER_FAKE_DLFCN_H
diff --git a/source/texk/web2c/luatexdir/luatex_svnversion.h b/source/texk/web2c/luatexdir/luatex_svnversion.h
index e79a15c30..deef2e2d6 100644
--- a/source/texk/web2c/luatexdir/luatex_svnversion.h
+++ b/source/texk/web2c/luatexdir/luatex_svnversion.h
@@ -1,4 +1,4 @@
 #ifndef luatex_svn_revision_h
 #define luatex_svn_revision_h
-#define luatex_svn_revision 7636
+#define luatex_svn_revision 7637
 #endif
-- 
GitLab