Open AsynchronousAI opened 1 year ago
Removed doc, mir, and readme files.
diff --git a/lua-5.3.6/Makefile b/LuaJIT-5.3.6-master/Makefile
index a2820e0..dee2ee4 100644
--- a/lua-5.3.6/Makefile
+++ b/LuaJIT-5.3.6-master/Makefile
@@ -51,7 +51,12 @@ R= $V.6
# Targets start here.
all: $(PLAT)
-$(PLATS) clean:
+$(PLATS):
+ cd mir && $(MAKE)
+ cd src && $(MAKE) $@
+
+clean:
+ cd mir && $(MAKE) $@
cd src && $(MAKE) $@
test: dummy
diff --git a/lua-5.3.6/src/Makefile b/LuaJIT-5.3.6-master/src/Makefile
index a13afb9..d16b769 100644
--- a/lua-5.3.6/src/Makefile
+++ b/LuaJIT-5.3.6-master/src/Makefile
@@ -19,9 +19,9 @@ SYSCFLAGS=
SYSLDFLAGS=
SYSLIBS=
-MYCFLAGS=
-MYLDFLAGS=
-MYLIBS=
+MYCFLAGS=-I../mir/ -I../mir/c2mir
+MYLDFLAGS=-L../mir/
+MYLIBS=-lmir
MYOBJS=
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
@@ -31,7 +31,7 @@ PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
- ltm.o lundump.o lvm.o lzio.o
+ ltm.o lundump.o lvm.o lzio.o YMEM.o YGC.o YJIT.o
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
@@ -95,22 +95,21 @@ bsd:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
c89:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89"
@echo ''
- @echo '*** C89 does not guarantee 64-bit integers for Lua.'
+ @echo '*** C89 does not support Lua-NOGC for Lua.'
@echo ''
freebsd:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -I/usr/include/edit" SYSLIBS="-Wl,-E -ledit" CC="cc"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE -I/usr/include/edit" SYSLIBS="-Wl,-E -ledit" CC="cc"
generic: $(ALL)
linux:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -lpthread -L../mir/build/ -lmir"
macosx:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline -lpthread"
mingw:
$(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \
@@ -133,7 +132,7 @@ lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
ltable.h lundump.h lvm.h
lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
-lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h YGC.h
lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
@@ -152,7 +151,7 @@ ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
lgc.h lstate.h ltm.h lzio.h lmem.h
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
+ llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h YGC.h
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
@@ -172,7 +171,7 @@ lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
ldo.h lfunc.h lstring.h lgc.h ltable.h
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
- lstring.h ltable.h
+ lstring.h ltable.h YGC.h
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
@@ -190,8 +189,10 @@ lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
- ltable.h lvm.h
+ ltable.h lvm.h YGC.h
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
lobject.h ltm.h lzio.h
-
+YMEM.o: YMEM.h lstate.h
+YGC.o: YGC.c lgc.h lfunc.h ltable.h lstring.h lauxlib.h YMEM.h
+YJIT.o: YJIT.c YMEM.h
# (end of Makefile)
diff --git a/LuaJIT-5.3.6-master/src/YGC.c b/LuaJIT-5.3.6-master/src/YGC.c
new file mode 100644
index 0000000..f4779ee
--- /dev/null
+++ b/LuaJIT-5.3.6-master/src/YGC.c
@@ -0,0 +1,526 @@
+/*
+ * @Author: Yuerer
+ * @Date: 2020-12-16 10:01:20
+ * @LastEditTime: 2021-04-19 16:47:36
+ */
+
+#include "YGC.h"
+
+#include <string.h>
+
+#include "lfunc.h"
+#include "ltable.h"
+#include "lstring.h"
+#include "lauxlib.h"
+
+#include "YMEM.h"
+
+#define Y_NOGCCCLOSE 0
+#define Y_NOGCOPEN 1
+#define Y_NOGCCOUNT 2
+#define Y_NOGCLEN 3
+
+#define Y_makenogc(x) l_setbit((x)->marked, Y_NOGCBIT)
+#define Y_clearnogc(x) resetbit((x)->marked, Y_NOGCBIT)
+
+static void Y_linkrevert (global_State *g, GCObject *o);
+static void Y_closeupvalue (lua_State *L, UpVal *u);
+static void Y_reallymarkobject (lua_State *L, GCObject *o, int b);
+static void Y_traverseproto (lua_State *L, Proto *f, int b);
+static void Y_traverseLclosure (lua_State *L, LClosure *cl, int b);
+static void Y_traversetable (lua_State *L, Table *h, int b);
+static int Y_isweaktable (lua_State *L, const struct Table *h);
+
+#define Y_valis(x, b) (iscollectable(x) && (b ? !Y_isnogc(gcvalue(x)) : Y_isnogc(gcvalue(x))))
+#define Y_markvalue(L, o, b) { if (Y_valis(o, b)) Y_reallymarkobject(L, gcvalue(o), b); }
+#define Y_markobject(L, t, b) { Y_reallymarkobject(L, obj2gco(t), b); }
+#define Y_markobjectN(L, t, b) { if (t) Y_markobject(L, t, b); }
+#define Y_maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
+#define Y_makeblack(x) \
+ (x->marked = cast_byte((x->marked & Y_maskcolors) | cast(lu_byte, bitmask(BLACKBIT))))
+#define Y_resetobject(g,o) \
+ { Y_clearnogc(o); Y_makeblack(o); Y_linkrevert(g, o); }
+
+
+static void Y_linkrevert (global_State *g, GCObject *o) {
+ GCObject **nogc = &g->Y_nogc;
+ while (*nogc != NULL) {
+ GCObject *curr = *nogc;
+ if (curr == o) {
+ *nogc = curr->next;
+ curr->next = g->allgc;
+ g->allgc = curr;
+ break;
+ }
+ nogc = &curr->next;
+ }
+}
+
+static void Y_closeupvalue (lua_State *L, UpVal *u) {
+ UpVal **up = &L->openupval;
+ while (*up != NULL) {
+ UpVal *uv = *up;
+ if (uv == u) {
+ *up = uv->u.open.next;
+ setobj(L, &uv->u.value, uv->v);
+ uv->v = &uv->u.value;
+ break;
+ }
+ up = &uv->u.open.next;
+ }
+}
+
+static void Y_reallymarkobject (lua_State *L, GCObject *o, int b) {
+ global_State *g = G(L);
+ switch (o->tt) {
+ case LUA_TSHRSTR: {
+ lu_mem mem = sizelstring(gco2ts(o)->shrlen);
+ if (b) {
+ Y_makenogc(o);
+ } else {
+ Y_resetobject(g, o);
+ }
+ g->Y_GCmemnogc += (b ? mem : -mem);
+ break;
+ }
+ case LUA_TLNGSTR: {
+ lu_mem mem = sizelstring(gco2ts(o)->u.lnglen);
+ if (b) {
+ Y_makenogc(o);
+ } else {
+ Y_resetobject(g, o);
+ }
+ g->Y_GCmemnogc += (b ? mem : -mem);
+ break;
+ }
+ case LUA_TTABLE: {
+ if (Y_isweaktable(L, gco2t(o))) {
+ luaL_error(L, "Not support weak tables");
+ break;
+ }
+ if (b) {
+ Y_makenogc(o);
+ } else {
+ Y_resetobject(g, o);
+ }
+ Y_traversetable(L, gco2t(o), b);
+ break;
+ }
+ case LUA_TLCL: {
+ if (b) {
+ Y_makenogc(o);
+ } else {
+ Y_resetobject(g, o);
+ }
+ Y_traverseLclosure(L, gco2lcl(o), b);
+ break;
+ }
+ case LUA_TPROTO: {
+ if (b) {
+ Y_makenogc(o);
+ } else {
+ Y_resetobject(g, o);
+ }
+ Y_traverseproto(L, gco2p(o), b);
+ break;
+ }
+ case LUA_TUSERDATA: {
+ luaL_error(L, "Not support userdata");
+ break;
+ }
+ case LUA_TTHREAD: {
+ luaL_error(L, "Not support thread");
+ break;
+ }
+ case LUA_TCCL: {
+ luaL_error(L, "Not support C function");
+ break;
+ }
+ default: break;
+ }
+}
+
+static void Y_traverseproto (lua_State *L, Proto *f, int b) {
+ if (f->cache && !Y_isnogc(f->cache)) {
+ f->cache = NULL;
+ }
+ int i;
+ Y_markobjectN(L, f->source, b);
+ for (i = 0; i < f->sizek; i ++) {
+ Y_markvalue(L, &f->k[i], b);
+ }
+ for (i = 0; i < f->sizeupvalues; i ++) {
+ Y_markobjectN(L, f->upvalues[i].name, b)
+ }
+ for (i = 0; i < f->sizep; i ++) {
+ Y_markobjectN(L, f->p[i], b);
+ }
+ for (i = 0; i <f->sizelocvars; i ++) {
+ Y_markobjectN(L, f->locvars[i].varname, b);
+ }
+ lu_mem mem = sizeof(Proto) + sizeof(Instruction) * f->sizecode +
+ sizeof(Proto *) * f->sizep +
+ sizeof(TValue) * f->sizek +
+ sizeof(int) * f->sizelineinfo +
+ sizeof(LocVar) * f->sizelocvars +
+ sizeof(Upvaldesc) * f->sizeupvalues;
+ G(L)->Y_GCmemnogc += (b ? mem : -mem);
+}
+
+static void Y_traverseLclosure (lua_State *L, LClosure *cl, int b) {
+ int i;
+ Y_markobjectN(L, cl->p, b);
+ Table *reg = hvalue(&G(L)->l_registry);
+ const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
+ GCObject *gto = gcvalue(gt);
+
+ for (i = 0; i < cl->nupvalues; i ++) {
+ UpVal *uv = cl->upvals[i];
+ if (uv != NULL) {
+ GCObject *o = gcvalue(uv->v);
+ /* skip _ENV */
+ if (o == gto) continue;
+ if (b && upisopen(uv)) {
+ Y_closeupvalue(L, uv);
+ }
+ Y_markvalue(L, uv->v, b);
+ }
+ }
+ lu_mem mem = sizeLclosure(cl->nupvalues);
+ G(L)->Y_GCmemnogc += (b ? mem : -mem);
+}
+
+static void Y_traversetable (lua_State *L, Table *h, int b) {
+ Y_markobjectN(L, h->metatable, b);
+ Node *n, *limit = gnode(h, cast(size_t, sizenode(h)));
+ unsigned int i;
+ for (i = 0; i < h->sizearray; i++) {
+ Y_markvalue(L, &h->array[i], b);
+ }
+ for (n = gnode(h, 0); n < limit; n++) {
+ if (!ttisnil(gval(n))) {
+ Y_markvalue(L, gkey(n), b);
+ Y_markvalue(L, gval(n), b);
+ }
+ }
+ lu_mem mem = sizeof(Table) + sizeof(TValue) * h->sizearray +
+ sizeof(Node) * cast(size_t, allocsizenode(h));
+ G(L)->Y_GCmemnogc += (b ? mem : -mem);
+}
+
+static int Y_isweaktable (lua_State *L, const struct Table *h) {
+ const char *weakkey, *weakvalue;
+ const TValue *mode = gfasttm(G(L), h->metatable, TM_MODE);
+ if (mode && ttisstring(mode) &&
+ ((weakkey = strchr(svalue(mode), 'k')),
+ (weakvalue = strchr(svalue(mode), 'v')),
+ (weakkey || weakvalue))) {
+ return 1;
+ }
+ return 0;
+}
+
+static const struct Table* Y_opttable (lua_State *L, int arg) {
+ if (lua_isnoneornil(L, arg) || lua_type(L, arg) != LUA_TTABLE) {
+ return NULL;
+ }
+ return cast(Table*, lua_topointer(L, arg));
+}
+
+static int Y_nogc (lua_State *L, int what, const struct Table *h) {
+ int res = 0;
+ global_State *g = G(L);
+ switch (what) {
+ case Y_NOGCCCLOSE: {
+ if (!h) {
+ luaL_argerror(L, 2, "Missing a table object");
+ }
+ Y_markobject(L, h, Y_NOGCCCLOSE);
+ break;
+ }
+ case Y_NOGCOPEN: {
+ if (!h) {
+ luaL_argerror(L, 2, "Missing a table object");
+ }
+ Y_markobject(L, h, Y_NOGCOPEN);
+ break;
+ }
+ case Y_NOGCCOUNT: {
+ res = cast_int(g->Y_GCmemnogc >> 10);
+ break;
+ }
+ case Y_NOGCLEN: {
+ GCObject *o = g->Y_nogc;
+ while (o) {
+ res ++;
+ o = o->next;
+ }
+ break;
+ }
+ default: res = -1;
+
+ }
+ return res;
+}
+
+int nogc (lua_State *L) {
+ static const char* const opts[] = {"close", "open", "count",
+ "len", NULL};
+ static const int optsnum[] = {Y_NOGCCCLOSE, Y_NOGCOPEN, Y_NOGCCOUNT,
+ Y_NOGCLEN};
+ int o = optsnum[luaL_checkoption(L, 1, "count", opts)];
+ const struct Table *ex = Y_opttable(L, 2);
+ int res = Y_nogc(L, o, ex);
+ switch (o) {
+ case Y_NOGCCOUNT: {
+ lua_pushnumber(L, (lua_Number)res + ((lua_Number)res/1024));
+ return 1;
+ }
+ case Y_NOGCLEN: {
+ lua_pushinteger(L, res);
+ return 1;
+ }
+ default: return 0;
+ }
+ return 0;
+}
+
+/* --------------------- Background Garbage Collect --------------------- */
+
+#define Y_BGGCCLOSE 0
+#define Y_BGGCOPEN 1
+#define Y_BGGCISRUNNING 2
+
+static void Y_luaF_freeproto (lua_State *L, Proto *f);
+static void Y_luaH_free (lua_State *L, Table *t);
+static size_t Y_linkbgjob (Y_bgjob *j, GCObject *o);
+static void Y_upvdeccount (lua_State *L, LClosure *cl);
+static void Y_freeobj (lua_State *L, GCObject *o);
+static void *Y_bgProcessJobs (void *arg);
+
+static void Y_luaF_freeproto (lua_State *L, Proto *f) {
+ Y_luaM_freearray(L, f->code, f->sizecode);
+ Y_luaM_freearray(L, f->p, f->sizep);
+ Y_luaM_freearray(L, f->k, f->sizek);
+ Y_luaM_freearray(L, f->lineinfo, f->sizelineinfo);
+ Y_luaM_freearray(L, f->locvars, f->sizelocvars);
+ Y_luaM_freearray(L, f->upvalues, f->sizeupvalues);
+ Y_luaM_free(L, f);
+}
+
+static void Y_luaH_free (lua_State *L, Table *t) {
+ if (!isdummy(t))
+ Y_luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
+ Y_luaM_freearray(L, t->array, t->sizearray);
+ Y_luaM_free(L, t);
+}
+
+static Y_bgjob *Y_jobs = NULL;
+struct Y_bgjob {
+ Y_bgjob *next;
+ GCObject *Y_bggc;
+};
+
+/* link GCObject to a background job
+ and return the size of the GCObject
+ that will be released */
+static size_t Y_linkbgjob (Y_bgjob *j, GCObject *o) {
+ o->next = j->Y_bggc;
+ j->Y_bggc = o;
+ size_t osize = 0;
+ switch (o->tt) {
+ case LUA_TPROTO: {
+ Proto *f = gco2p(o);
+ osize += sizeof(*(f->code)) * f->sizecode;
+ osize += sizeof(*(f->p)) * f->sizep;
+ osize += sizeof(*(f->k)) * f->sizek;
+ osize += sizeof(*(f->lineinfo)) * f->sizelineinfo;
+ osize += sizeof(*(f->locvars)) * f->sizelocvars;
+ osize += sizeof(*(f->upvalues)) * f->sizeupvalues;
+ osize += sizeof(*(f));
+ break;
+ }
+ case LUA_TLCL: osize = sizeLclosure(gco2lcl(o)->nupvalues); break;
+ case LUA_TCCL: osize = sizeCclosure(gco2ccl(o)->nupvalues); break;
+ case LUA_TTABLE: {
+ Table *t = gco2t(o);
+ if (!isdummy(t)) osize += sizeof(*(t->node)) * cast(size_t, sizenode(t));
+ osize += sizeof(*(t->array)) * t->sizearray;
+ osize += sizeof(*(t));
+ break;
+ }
+ case LUA_TUSERDATA: osize = sizeudata(gco2u(o)); break;
+ case LUA_TSHRSTR: osize = sizelstring(gco2ts(o)->shrlen); break;
+ case LUA_TLNGSTR: osize = sizelstring(gco2ts(o)->u.lnglen); break;
+ default: lua_assert(0);
+ }
+ return osize;
+}
+
+static void Y_upvdeccount (lua_State *L, LClosure *cl) {
+ int i;
+ for (i = 0; i < cl->nupvalues; i++) {
+ UpVal *uv = cl->upvals[i];
+ if (uv)
+ luaC_upvdeccount(L, uv);
+ }
+}
+
+static void Y_freeobj (lua_State *L, GCObject *o) {
+ /* threads are released in the main thread */
+ switch (o->tt) {
+ case LUA_TPROTO: Y_luaF_freeproto(L, gco2p(o)); break;
+ case LUA_TLCL: {
+ /* dec upvalue refcount in the main thread */
+ Y_luaM_freemem(L, gco2lcl(o), sizeLclosure(gco2lcl(o)->nupvalues));
+ break;
+ }
+ case LUA_TCCL: {
+ Y_luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
+ break;
+ }
+ case LUA_TTABLE: Y_luaH_free(L, gco2t(o)); break;
+ case LUA_TUSERDATA: Y_luaM_freemem(L, o, sizeudata(gco2u(o))); break;
+ case LUA_TSHRSTR: {
+ /* remove it from hash table has been executed in the main thread */
+ Y_luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
+ break;
+ }
+ case LUA_TLNGSTR: {
+ Y_luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
+ break;
+ }
+ default: lua_assert(0);
+ }
+}
+
+void *Y_bgProcessJobs (void *arg) {
+ lua_State *L= cast(lua_State*, arg);
+ global_State *g = G(L);
+#if !defined(LUA_USE_WINDOWS)
+ pthread_mutex_lock(&g->Y_bgmutex);
+ while (1) {
+ Y_bgjob **p = &Y_jobs;
+ if (*p == NULL) {
+ pthread_cond_wait(&g->Y_bgcond, &g->Y_bgmutex);
+ continue;
+ }
+ Y_bgjob *curr = *p;
+ *p = curr->next;
+ pthread_mutex_unlock(&g->Y_bgmutex);
+ GCObject **op = &curr->Y_bggc;
+ while (*op != NULL) {
+ GCObject *curr = *op;
+ *op = curr->next;
+ Y_freeobj(L, curr);
+ }
+ Y_luaM_free(L, curr);
+ pthread_mutex_lock(&g->Y_bgmutex);
+ }
+#endif
+ return NULL;
+}
+
+Y_bgjob *Y_createbgjob (lua_State *L) {
+ if (!G(L)->Y_bgrunning) return NULL;
+ Y_bgjob *j = Y_luaM_new(L, Y_bgjob);
+ j->next = NULL;
+ j->Y_bggc = NULL;
+ return j;
+}
+
+void Y_submitbgjob (lua_State *L, Y_bgjob *j) {
+ global_State *g = G(L);
+ if (!g->Y_bgrunning) return;
+#if !defined(LUA_USE_WINDOWS)
+ pthread_mutex_lock(&g->Y_bgmutex);
+ j->next = Y_jobs;
+ Y_jobs = j;
+ pthread_cond_signal(&g->Y_bgcond);
+ pthread_mutex_unlock(&g->Y_bgmutex);
+#endif
+}
+
+void Y_trybgfree (lua_State *L, GCObject *o, Y_bgjob *j, void(*fgfreeobj)(lua_State*, GCObject*)) {
+ global_State *g = G(L);
+ if (!g->Y_bgrunning) {
+ fgfreeobj(L, o);
+ return;
+ }
+ size_t osize = 0;
+ switch (o->tt) {
+ case LUA_TPROTO: osize = Y_linkbgjob(j, o); break;
+ case LUA_TLCL: {
+ Y_upvdeccount(L, gco2lcl(o));
+ Y_linkbgjob(j, o);
+ break;
+ }
+ case LUA_TCCL: osize = Y_linkbgjob(j, o); break;
+ case LUA_TTABLE: osize = Y_linkbgjob(j, o); break;
+ case LUA_TTHREAD: {
+ /* release the memory by the main thread */
+ luaE_freethread(L, gco2th(o));
+ break;
+ }
+ case LUA_TUSERDATA: osize = Y_linkbgjob(j, o); break;
+ case LUA_TSHRSTR:
+ /* remove it from hash table by main thread */
+ luaS_remove(L, gco2ts(o));
+ /* release the memory by background thread */
+ osize = Y_linkbgjob(j, o);
+ break;
+ case LUA_TLNGSTR: osize = Y_linkbgjob(j, o); break;
+ default: lua_assert(0);
+ }
+ g->GCdebt -= osize;
+}
+
+void Y_initgcstate (lua_State *L) {
+ global_State *g = G(L);
+ g->Y_nogc = NULL;
+ g->Y_GCmemnogc = 0;
+ g->Y_bgrunning = 0;
+#if !defined(LUA_USE_WINDOWS)
+ pthread_mutex_init(&g->Y_bgmutex, NULL);
+ pthread_cond_init(&g->Y_bgcond, NULL);
+ /* fixme: check return value */
+ pthread_create(&g->Y_bgthread, NULL, Y_bgProcessJobs, cast(void*, L));
+#endif
+}
+
+static int Y_bggc (lua_State *L, int what) {
+ int res = 0;
+ global_State *g = G(L);
+ switch (what) {
+ case Y_BGGCCLOSE: {
+ g->Y_bgrunning = 0;
+ break;
+ }
+ case Y_BGGCOPEN: {
+ g->Y_bgrunning = 1;
+ break;
+ }
+ case Y_BGGCISRUNNING: {
+ res = g->Y_bgrunning;
+ break;
+ }
+ default: res = -1;
+ }
+ return res;
+}
+
+#if defined(LUA_USE_WINDOWS)
+int bggc (lua_State *L) { luaL_error(L, "Not support for windows"); }
+#else
+int bggc (lua_State *L) {
+ static const char* const opts[] = {"close", "open", "isrunning", NULL};
+ static const int optsnum[] = {Y_BGGCCLOSE, Y_BGGCOPEN, Y_BGGCISRUNNING};
+ int o = optsnum[luaL_checkoption(L, 1, "isrunning", opts)];
+ int res = Y_bggc(L, o);
+ if (o == Y_BGGCISRUNNING) {
+ lua_pushboolean(L, res);
+ return 1;
+ }
+ return 0;
+}
+#endif
\ No newline at end of file
diff --git a/LuaJIT-5.3.6-master/src/YGC.h b/LuaJIT-5.3.6-master/src/YGC.h
new file mode 100644
index 0000000..2758754
--- /dev/null
+++ b/LuaJIT-5.3.6-master/src/YGC.h
@@ -0,0 +1,40 @@
+/*
+ * @Author: Yuerer
+ * @Date: 2020-12-16 09:54:20
+ * @LastEditTime: 2021-04-19 20:45:01
+ */
+
+#ifndef YGC_H
+#define YGC_H
+
+/* windows and c89 support nogc but not bggc */
+#if !defined(LUA_USE_WINDOWS)
+#include <pthread.h>
+#endif
+
+#include "lgc.h"
+
+/* lgc.c */
+#define Y_NOGCBIT 4 /* object not to be collected */
+#define Y_isnogc(x) testbit((x)->marked, Y_NOGCBIT)
+
+/* lbaselib.c */
+int nogc (lua_State *L);
+int bggc (lua_State *L);
+
+/* lstate.c */
+void Y_initgcstate (lua_State *L);
+
+/* lgc.c */
+typedef struct Y_bgjob Y_bgjob;
+Y_bgjob* Y_createbgjob (lua_State *L);
+void Y_submitbgjob (lua_State *L, Y_bgjob *j);
+void Y_trybgfree (lua_State*,GCObject*,Y_bgjob*,void(*)(lua_State*, GCObject*));
+
+/* lbaselib.c */
+#define Y_GCBASEFUNCS \
+{"nogc", nogc}, \
+{"bggc", bggc}
+
+
+#endif
diff --git a/LuaJIT-5.3.6-master/src/YJIT.c b/LuaJIT-5.3.6-master/src/YJIT.c
new file mode 100644
index 0000000..2d23f5c
--- /dev/null
+++ b/LuaJIT-5.3.6-master/src/YJIT.c
@@ -0,0 +1,1633 @@
+/*
+ * @Author: Yuerer
+ * @Date: 2021-05-19 20:05:20
+ * @LastEditTime: 2021-05-27 14:25:20
+ */
+
+#include "YJIT.h"
+
+#include <string.h>
+
+#include "YMEM.h"
+
+#include "lvm.h"
+#include "lopcodes.h"
+#include "lauxlib.h"
+#include "lfunc.h"
+#include "ldebug.h"
+
+
+void Y_initjitstate (lua_State *L) {
+ global_State *g = G(L);
+ g->Y_jitstate = Y_luaM_new(L, YJIT_State);
+ g->Y_jitstate->Y_mirctx = MIR_init();
+ memset(&g->Y_jitstate->Y_c2miropts, 0, sizeof(struct c2mir_options));
+ g->Y_jitstate->Y_c2miropts.message_file = stderr;
+ g->Y_jitstate->Y_c2miropts.module_num = 0;
+ g->Y_jitstate->Y_jitrunning = 1;
+ g->Y_jitstate->Y_limitsize = 100;
+ g->Y_jitstate->Y_limitcount = 50;
+ g->Y_jitstate->Y_jitcount = 0;
+}
+
+void Y_closejitstate (lua_State *L) {
+ global_State *g = G(L);
+ MIR_finish(g->Y_jitstate->Y_mirctx);
+ Y_luaM_free(L, g->Y_jitstate);
+}
+
+void Y_initjitproto (lua_State *L, Proto *p) {
+ p->Y_jitproto = Y_luaM_new(L, YJIT_Proto);
+ p->Y_jitproto->Y_jitfunc = NULL;
+ p->Y_jitproto->Y_jitstatus = YJIT_NOT_COMPILE;
+ p->Y_jitproto->Y_execcount = 0;
+}
+
+void Y_closejitproto (lua_State *L, Proto *p) {
+ Y_luaM_free(L, p->Y_jitproto);
+}
+
+/* internal use */
+typedef struct Y_jitbuffer {
+ char *buffer;
+ size_t p;
+ size_t size;
+ size_t capacity;
+ void *ud;
+} Y_jitbuffer;
+
+static int Y_getc (void *data) {
+ Y_jitbuffer *buff = data;
+ if (buff->p >= buff->size) return EOF;
+ int c = buff->buffer[buff->p];
+ if (c == 0) {
+ c = EOF;
+ } else {
+ buff->p ++;
+ }
+ return c;
+}
+
+static void Y_initbuffer (lua_State *L, Y_jitbuffer *buff, size_t capacity) {
+ buff->size = buff->p = 0;
+ if (capacity <= 0) {
+ buff->buffer = NULL;
+ buff->capacity = 0;
+ return;
+ }
+ buff->buffer = Y_luaM_newvector(L, capacity, char);
+ memset(buff->buffer, 0, capacity * sizeof(char));
+ buff->capacity = capacity;
+ buff->ud = L;
+}
+
+static void Y_resizebuffer (Y_jitbuffer *buff, size_t buffsize) {
+ lua_State *L = cast(lua_State*, buff->ud);
+ if (buff->capacity >= buffsize) return;
+ size_t newsize = buffsize * 2;
+ buff->buffer = Y_luaM_reallocv(L, buff->buffer, buff->capacity, newsize, char);
+ buff->capacity = newsize;
+}
+
+#define Y_freebuffer(buff) \
+ Y_luaM_freemem(cast(lua_State*, ((buff)->ud)), (buff)->buffer, (buff)->capacity);
+
+static const char LUA_HEADER[];
+
+static void Y_str2buffer (Y_jitbuffer *buff, const char *str) {
+ size_t len = strlen(str);
+ size_t newsize = buff->size + len + 2;
+ Y_resizebuffer(buff, newsize);
+ strcpy(&buff->buffer[buff->size], str);
+ buff->size += len;
+ buff->buffer[buff->size++] = '\n';
+ buff->buffer[buff->size] = 0;
+}
+
+static void Y_fstr2buffer (Y_jitbuffer *buff, const char *fmt, ...) {
+ va_list args;
+ char local_buffer[1024];
+ va_start(args, fmt);
+ int n = vsnprintf(local_buffer, sizeof(local_buffer), fmt, args);
+ if (n < 0) abort();
+ va_end(args);
+ Y_str2buffer(buff, local_buffer);
+}
+
+typedef struct Y_luafunction {
+ const char *name;
+ void *func;
+} Y_luafunction;
+
+static Y_luafunction LUA_FUNCTIONS[] = {
+ {"Y_luaV_gettable", Y_luaV_gettable},
+ {"Y_luaV_settable", Y_luaV_settable},
+ {"Y_luaV_newtable", Y_luaV_newtable},
+ {"Y_luaV_concat", Y_luaV_concat},
+ {"Y_luaV_closure", Y_luaV_closure},
+ {"Y_luaV_setupval", Y_luaV_setupval},
+ {"Y_luaV_setlist", Y_luaV_setlist},
+ {"Y_luaV_vararg", Y_luaV_vararg},
+ {"luaD_precall", luaD_precall},
+ {"luaD_poscall", luaD_poscall},
+ {"luaD_call", luaD_call},
+ {"luaG_runerror", luaG_runerror},
+ {"luaO_arith", luaO_arith},
+ {"luaV_objlen", luaV_objlen},
+ {"luaV_execute", luaV_execute},
+ {"luaV_equalobj", luaV_equalobj},
+ {"luaV_lessthan", luaV_lessthan},
+ {"luaV_lessequal", luaV_lessequal},
+ {"luaV_tonumber_", luaV_tonumber_},
+ {"luaV_tointeger", luaV_tointeger},
+ {"luaT_trybinTM", luaT_trybinTM},
+ {"luaF_close", luaF_close},
+ {NULL, NULL},
+};
+
+static void *import_resolver (const char *name) {
+ for (int i = 0; LUA_FUNCTIONS[i].name; i ++) {
+ if (!strcmp(name, LUA_FUNCTIONS[i].name)) {
+ return LUA_FUNCTIONS[i].func;
+ }
+ }
+ return NULL;
+}
+
+/* ---------------------------- codegen ---------------------------- */
+#define CODE(fmt, ...) Y_fstr2buffer(buff, fmt ,##__VA_ARGS__)
+
+#define RA CODE("ra = R(%d);", A)
+#define RB CODE("rb = R(%d);", B)
+#define RA_EQ_RB CODE("setobj2s(L, ra, rb);")
+#define RB_EQ_RA CODE("setobj2s(L, rb, ra);")
+#define RB_EQ_RC CODE("setobj2s(L, rb, rc);")
+
+#define RKB \
+ do { \
+ if (!ISK(B)) { \
+ CODE("rb = R(%d);", B); \
+ } else { \
+ CODE("rb = K(%d);", INDEXK(B)); \
+ } \
+ } while (0)
+
+#define RKC \
+ do { \
+ if (!ISK(C)) { \
+ CODE("rc = R(%d);", C); \
+ } else { \
+ CODE("rc = K(%d);", INDEXK(C)); \
+ } \
+ } while (0)
+
+#define KBX CODE("rb = K(%d);", Bx)
+
+/* stack expansion may occur when calling a lua function */
+#define PROTECT_BASE CODE("base = ci->u.l.base;")
+
+/* in order to display the correct line number when an error is reported */
+#define UPDATE_SAVEDPC CODE("ci->u.l.savedpc = &cl->p->code[%d];", savedpc)
+
+#define SET_LABEL \
+ do { \
+ if (is_jmps[pc]) { \
+ CODE("Label_%d:", pc); \
+ } \
+ } while (0)
+
+#define JMP CODE("goto Label_%d;", pc)
+#define ERROR(str) CODE("luaG_runerror(L, %s);", #str)
+
+/* 0: R(A) := R(B) */
+static void emit_move (int A, int B, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ RA_EQ_RB;
+}
+
+/* 1-2: R(A) := K(Bx) */
+static void emit_loadk (int A, int Bx, Y_jitbuffer *buff) {
+ RA;
+ KBX;
+ RA_EQ_RB;
+}
+
+/* 3: R(A) := (Bool)B if (C) pc++ */
+static void emit_loadbool (int A, int B, int C, int pc, Y_jitbuffer *buff) {
+ RA;
+ CODE("setbvalue(ra, %d);", B);
+ if (C) JMP;
+}
+
+/* 4: R(A), R(A+1), ..., R(A+B) := nil */
+static void emit_loadnil (int A, int B, Y_jitbuffer *buff) {
+ RA;
+ int b = B;
+ do {
+ CODE("setnilvalue(ra++);");
+ } while (b--);
+}
+
+/* 5: R(A) := UpValue[B] */
+static void emit_getupval (int A, int B, Y_jitbuffer *buff) {
+ RA;
+ CODE("setobj2s(L, ra, cl->upvals[%d]->v);", B);
+}
+
+/* 6: R(A) := UpValue[B][RK(C)] */
+static void emit_gettabup (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("Y_luaV_gettable(L, cl->upvals[%d]->v, rc, ra);", B);
+ PROTECT_BASE;
+}
+
+/* 7: R(A) := R(B)[RK(C)] */
+static void emit_gettable (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("Y_luaV_gettable(L, rb, rc, ra);");
+ PROTECT_BASE;
+}
+
+/* 8: UpValue[A][RK(B)] := RK(C) */
+static void emit_settabup (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("Y_luaV_settable(L, cl->upvals[%d]->v, rb, rc);", A);
+ PROTECT_BASE;
+}
+
+/* 9: UpValue[B] := R(A) */
+static void emit_setupval (int A, int B, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ UPDATE_SAVEDPC;
+ CODE("Y_luaV_setupval(L, cl, ra, %d);", B);
+}
+
+/* 10: R(A)[RK(B)] := RK(C) */
+static void emit_settable (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("Y_luaV_settable(L, ra, rb, rc);");
+ PROTECT_BASE;
+}
+
+/* 11: R(A) := {} (arraysize = B, hashsize = C) */
+static void emit_newtable (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ unsigned int nasize = luaO_fb2int(B), nhsize = luaO_fb2int(C);
+ RA;
+ UPDATE_SAVEDPC;
+ CODE("Y_luaV_newtable(L, ci, ra, %u, %u);", nasize, nhsize);
+ PROTECT_BASE;
+}
+
+/* 12: R(A + 1) := R(B); R(A) := R(B)[RK(C)] */
+static void emit_self (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ RKC;
+ CODE("setobj2s(L, ra + 1, rb);");
+ UPDATE_SAVEDPC;
+ CODE("Y_luaV_gettable(L, rb, rc, ra);");
+ PROTECT_BASE;
+}
+
+/* 13: R(A) := RK(B) + RK(C) */
+static void emit_add (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ CODE("if (ttisinteger(rb) && ttisinteger(rc)) {");
+ CODE(" ib = ivalue(rb); ic = ivalue(rc);");
+ CODE(" setivalue(ra, intop(+, ib, ic));");
+ CODE("} else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {");
+ CODE(" setfltvalue(ra, luai_numadd(L, nb, nc));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rc, ra, TM_ADD);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 14: R(A) := RK(B) - RK(C) */
+static void emit_sub (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ CODE("if (ttisinteger(rb) && ttisinteger(rc)) {");
+ CODE(" ib = ivalue(rb); ic = ivalue(rc);");
+ CODE(" setivalue(ra, intop(-, ib, ic));");
+ CODE("} else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {");
+ CODE(" setfltvalue(ra, luai_numsub(L, nb, nc));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rc, ra, TM_SUB);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 15: R(A) := RK(B) * RK(C) */
+static void emit_mul (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ CODE("if (ttisinteger(rb) && ttisinteger(rc)) {");
+ CODE(" ib = ivalue(rb); ic = ivalue(rc);");
+ CODE(" setivalue(ra, intop(*, ib, ic));");
+ CODE("} else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {");
+ CODE(" setfltvalue(ra, luai_nummul(L, nb, nc));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rc, ra, TM_MUL);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 16: R(A) := RK(B) % RK(C) */
+static void emit_mod (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("luaO_arith(L, %d, rb, rc, ra);", LUA_OPMOD);
+ PROTECT_BASE;
+}
+
+/* 17: R(A) := RK(B) ^ RK(C) */
+static void emit_pow (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("luaO_arith(L, %d, rb, rc, ra);", LUA_OPPOW);
+ PROTECT_BASE;
+}
+
+/* 18: R(A) := RK(B) / RK(C) */
+static void emit_div (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ CODE("if (tonumber(rb, &nb) && tonumber(rc, &nc)) {");
+ CODE(" setfltvalue(ra, luai_numdiv(L, nb, nc));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rc, ra, TM_DIV);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 19: R(A) := RK(B) // RK(C) */
+static void emit_idiv (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("luaO_arith(L, %d, rb, rc, ra);", LUA_OPIDIV);
+ PROTECT_BASE;
+}
+
+/* 20: R(A) := RK(B) & RK(C) */
+static void emit_band (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ CODE("if (tointeger(rb, &ib) && tointeger(rc, &ic)) {");
+ CODE(" setivalue(ra, intop(&, ib, ic));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rc, ra, TM_BAND);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 21: R(A) := RK(B) | RK(C) */
+static void emit_bor (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ CODE("if (tointeger(rb, &ib) && tointeger(rc, &ic)) {");
+ CODE(" setivalue(ra, intop(|, ib, ic));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rc, ra, TM_BOR);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 22: R(A) := RK(B) ~ RK(C) */
+static void emit_bxor (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ CODE("if (tointeger(rb, &ib) && tointeger(rc, &ic)) {");
+ CODE(" setivalue(ra, intop(^, ib, ic));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rc, ra, TM_BXOR);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 23: R(A) := RK(B) << RK(C) */
+static void emit_shl (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("luaO_arith(L, %d, rb, rc, ra);", LUA_OPSHL);
+ PROTECT_BASE;
+}
+
+/* 24: R(A) := RK(B) >> RK(C) */
+static void emit_shr (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("luaO_arith(L, %d, rb, rc, ra);", LUA_OPSHR);
+ PROTECT_BASE;
+}
+
+/* 25: R(A) := -R(B) */
+static void emit_unm (int A, int B, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ CODE("if (ttisinteger(rb)) {");
+ CODE(" ib = ivalue(rb);");
+ CODE(" setivalue(ra, intop(-, 0, ib));");
+ CODE("} else if (tonumber(rb, &nb)) {");
+ CODE(" setfltvalue(ra, luai_numunm(L, nb));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rb, ra, TM_UNM);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 26: R(A) := ~R(B) */
+static void emit_bnot (int A, int B, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ CODE("if (tointeger(rb, &ib)) {");
+ CODE(" setivalue(ra, intop(^, ~l_castS2U(0), ib));");
+ CODE("} else {");
+ UPDATE_SAVEDPC;
+ CODE(" luaT_trybinTM(L, rb, rb, ra, TM_BNOT);");
+ PROTECT_BASE;
+ CODE("}");
+}
+
+/* 27: R(A) := not R(B) */
+static void emit_not (int A, int B, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ CODE("result = l_isfalse(rb);");
+ CODE("setbvalue(ra, result);");
+}
+
+/* 28: R(A) := length of R(B) */
+static void emit_len (int A, int B, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ UPDATE_SAVEDPC;
+ CODE("luaV_objlen(L, ra, rb);");
+ PROTECT_BASE;
+}
+
+/* 29: R(A) := [R(B) .. R(C)] */
+static void emit_concat (int A, int B, int C, Y_jitbuffer *buff) {
+ CODE("Y_luaV_concat(L, ci, %d, %d, %d);", A, B, C);
+ PROTECT_BASE;
+}
+
+/* 30: jmp to pc; if (A) close UpValues >= R(A - 1) */
+static void emit_jmp (int A, int pc, Y_jitbuffer *buff) {
+ if (A) {
+ CODE("ra = R(%d);", A - 1);
+ CODE("luaF_close(L, ra);");
+ }
+ JMP;
+}
+
+/* 31-33: if ((RK(B) op RK(C)) != A pc ++; else; donextjmp to pc */
+static void emit_binary_test (int A, int B, int C, int savedpc, int pc, int jmp_A, OpCode op, Y_jitbuffer *buff) {
+ const char *testfunc;
+ switch (op) {
+ case OP_EQ: testfunc = "luaV_equalobj"; break;
+ case OP_LT: testfunc = "luaV_lessthan"; break;
+ case OP_LE: testfunc = "luaV_lessequal"; break;
+ default: lua_assert(0);
+ }
+ RKB;
+ RKC;
+ UPDATE_SAVEDPC;
+ CODE("result = %s(L, rb, rc);", testfunc);
+ PROTECT_BASE;
+ CODE("if (result == %d) {", A);
+ if (jmp_A) {
+ /* close UpValues >= R(jmp_A - 1) */
+ CODE(" ra = R(%d);", jmp_A - 1);
+ CODE(" luaF_close(L, ra);");
+ }
+ JMP;
+ CODE("}");
+}
+
+/* 34: if R(A) != (Bool)C pc ++; else; donextjmp to pc;
+ local a, b; a = a and b */
+static void emit_test (int A, int C, int pc, int jmp_A, Y_jitbuffer *buff) {
+ RA;
+ if (C) {
+ CODE("result = l_isfalse(ra);");
+ } else {
+ CODE("result = !l_isfalse(ra);");
+ }
+ CODE("if (!result) {");
+ if (jmp_A) {
+ /* close UpValues >= R(jmp_A - 1) */
+ CODE(" ra = R(%d);", jmp_A - 1);
+ CODE(" luaF_close(L, ra);");
+ }
+ JMP;
+ CODE("}");
+}
+
+/* 35: if R(B) != (Bool)C pc ++; else; ra = rb; donextjmp to pc;
+ local a, b, c; a = b and c */
+static void emit_testset (int A, int B, int C, int pc, int jmp_A, Y_jitbuffer *buff) {
+ RA;
+ RB;
+ if (C) {
+ CODE("result = l_isfalse(rb);");
+ } else {
+ CODE("result = !l_isfalse(rb);");
+ }
+ CODE("if (!result) {");
+ RA_EQ_RB;
+ if (jmp_A) {
+ /* close UpValues >= R(jmp_A - 1) */
+ CODE(" ra = R(%d);", jmp_A - 1);
+ CODE(" luaF_close(L, ra);");
+ }
+ JMP;
+ CODE("}");
+}
+
+/* 36-37: [R(A) .. R(A + C - 2)] := [R(A) .. R(A + 1) .. R(A + B - 1)] */
+static void emit_call (int A, int B, int C, int savedpc, Y_jitbuffer *buff) {
+ RA;
+ /* when C == 0, nresults = -1 == LUA_MULTRET */
+ int nresults = C - 1;
+ if (B) CODE("L->top = R(%d);", A + B);
+ UPDATE_SAVEDPC;
+ CODE("result = luaD_precall(L, ra, %d, 1);", nresults);
+ CODE("if (result) {");
+ CODE(" if (result == 1 && %d >= 0) {", nresults);
+ CODE(" L->top = ci->top;");
+ CODE(" }");
+ CODE("} else {");
+ /* when we call a lua function in the jit function
+ , we need to fix the top of the stack by ourselves */
+ CODE(" result = luaV_execute(L);");
+ CODE(" if (result) L->top = ci->top;");
+ CODE("}");
+ PROTECT_BASE;
+}
+
+/* 38: return R(A) ... R(A + B - 2) */
+static void emit_return (int A, int B, Y_jitbuffer *buff) {
+ /* return to the luaD_precall function and fix the top of the stack! */
+ RA;
+ CODE("if (cl->p->sizep > 0) luaF_close(L, base);");
+ CODE("return luaD_poscall(L, ci, ra, (%d != 0 ? %d - 1 : cast_int(L->top - ra)));", B, B);
+}
+
+/* 39: R(A) += R(A + 2); if R(A) <= R(A + 1) pc += sBx; R(A + 3) = R(A) */
+static void emit_forloop (int A, int pc, Y_jitbuffer *buff) {
+ CODE("if (is_iloop_%d) {", A);
+ CODE(" iinit_%d += istep_%d;", A, A);
+ CODE(" if ((0 < istep_%d) ? (iinit_%d <= ilimit_%d) : (ilimit_%d <= iinit_%d)) {", A, A, A, A, A);
+ /* R(A + 3) is external index */
+ CODE(" setivalue(R(%d), iinit_%d);", A + 3, A);
+ JMP;
+ CODE(" }");
+ CODE("} else {");
+ CODE(" ninit_%d += nstep_%d;", A, A);
+ CODE(" if ((0.0 < nstep_%d) ? (ninit_%d <= nlimit_%d) : (nlimit_%d <= ninit_%d)) {", A, A, A, A, A);
+ /* R(A + 3) is external index */
+ CODE(" setfltvalue(R(%d), ninit_%d);", A + 3, A);
+ JMP;
+ CODE(" }");
+ CODE("}");
+}
+
+/* 40: R(A) -= R(A + 2); pc += sBx donextjmp to pc */
+static void emit_forprep (int A, int pc, int savedpc, lu_byte need_define, Y_jitbuffer *buff) {
+ /* avoid redefinition */
+ if (need_define) {
+ CODE("lua_Integer iinit_%d = 0, ilimit_%d = 0, istep_%d = 0;", A, A, A);
+ CODE("lua_Number ninit_%d = 0, nlimit_%d = 0, nstep_%d = 0;", A, A, A);
+ /* for OP_FORLOOP */
+ CODE("int is_iloop_%d = 0;", A);
+ }
+ RA; /* init */
+ CODE("rb = ra + 1;"); /* plimit */
+ CODE("rc = ra + 2;"); /* pstep */
+ UPDATE_SAVEDPC;
+ CODE("if (ttisinteger(ra) && ttisinteger(rc) && ttisinteger(rb)) { ");
+ CODE(" ilimit_%d = ivalue(rb);", A);
+ CODE(" iinit_%d = ivalue(ra);", A);
+ CODE(" istep_%d = ivalue(rc);", A);
+ CODE(" iinit_%d -= istep_%d;", A, A);
+ CODE(" is_iloop_%d = 1;", A);
+ CODE("} else { ");
+ CODE(" if (!tonumber(rb, &nlimit_%d)) {", A);
+ ERROR("'for' limit must be a number");
+ CODE(" }");
+ CODE(" if (!tonumber(rc, &nstep_%d)) {", A);
+ ERROR("'for' step must be a number");
+ CODE(" }");
+ CODE(" if (!tonumber(ra, &ninit_%d)) {", A);
+ ERROR("'for' initial value must be a number");
+ CODE(" }");
+ CODE(" ninit_%d -= nstep_%d;", A, A);
+ CODE(" is_iloop_%d = 0;", A);
+ CODE("}");
+ JMP;
+}
+
+/* 41: R(A + 3), ..., R(A + 2 + C) := Function(R(A)) (R(A + 1), R(A + 2))*/
+static void emit_tforcall (int A, int C, int tforloop_A, int pc, Y_jitbuffer *buff) {
+ RA;
+ /* ra + 3 = cb */
+ CODE("rb = ra + 5;"); /* (ra + 3) + 2 */
+ CODE("rc = ra + 2;");
+ RB_EQ_RC;
+ CODE("rb = ra + 4;"); /* (ra + 3) + 1 */
+ CODE("rc = ra + 1;");
+ RB_EQ_RC;
+ CODE("rb = ra + 3;"); /* cb */
+ RB_EQ_RA;
+ CODE("L->top = rb + 3;"); /* func + 2 args */
+ CODE("luaD_call(L, rb, %d);", C);
+ PROTECT_BASE;
+ CODE("L->top = ci->top;");
+ /* enter OP_TFORLOOP */
+ A = tforloop_A;
+ RA;
+ CODE("if (!ttisnil(ra + 1)) {"); /* continue loop? */
+ CODE(" setobj2s(L, ra, ra + 1);");
+ JMP;
+ CODE("}");
+}
+
+/* 42: if R(A + 1) != nil then R(A) = R(A + 1) donextjmp to pc */
+static void emit_tforloop (int A, int pc, Y_jitbuffer *buff) {
+ RA;
+ CODE("if (!ttisnil(ra + 1) {"); /* continue loop? */
+ CODE(" setobj2s(L, ra, ra + 1);");
+ JMP;
+ CODE("}");
+}
+
+/* 43: R(A)[(C - 1) * FPF + i] := R(A + i) */
+static void emit_setlist (int A, int B, int C, Y_jitbuffer *buff) {
+ RA;
+ CODE("Y_luaV_setlist(L, ci, ra, %d, %d);", B, C);
+}
+
+/* 44: R(A) := closure(Proto[Bx]) */
+static void emit_closure (int A, int Bx, Y_jitbuffer *buff) {
+ CODE("Y_luaV_closure(L, ci, cl, %d, %d);", A, Bx);
+ PROTECT_BASE;
+}
+
+/* 45: R(A), R(A + 1), ..., R(A + B - 2) = vararg */
+static void emit_vararg (int A, int B, Y_jitbuffer *buff) {
+ CODE("Y_luaV_vararg(L, ci, cl, %d, %d);", A, B);
+ /* lua function is not called, but the stack may be expanded */
+ PROTECT_BASE;
+}
+
+#define OPEN_FUNC(name) \
+ do { \
+ CODE("int %s (lua_State *L) {", name); \
+ CODE("int result = 0;"); \
+ CODE("lua_Integer ib = 0, ic = 0;"); \
+ CODE("lua_Number nb = 0.0, nc = 0.0;"); \
+ CODE("StkId ra = NULL, rb = NULL, rc = NULL;"); \
+ CODE("CallInfo *ci = L->ci;"); \
+ CODE("LClosure *cl = clLvalue(ci->func);"); \
+ CODE("TValue *k = cl->p->k;"); \
+ CODE("StkId base = ci->u.l.base;"); \
+ } while (0)
+
+#define CLOSE_FUNC \
+ do { \
+ CODE("return 0;"); \
+ CODE("}"); \
+ } while (0)
+
+#define GET_OPERANDS \
+ do { \
+ A = GETARG_A(i); \
+ B = GETARG_B(i); \
+ C = GETARG_C(i); \
+ Bx = GETARG_Bx(i); \
+ sBx = GETARG_sBx(i); \
+ } while (0)
+
+static void Y_setjmps (Proto *p, lu_byte *is_jmps) {
+ Instruction i;
+ for (int pc = 0; pc < p->sizecode; pc ++) {
+ i = p->code[pc];
+ switch (GET_OPCODE(i)) {
+ case OP_LOADBOOL: {
+ if (GETARG_C(i)) is_jmps[pc + 2] = 1;
+ break;
+ }
+ case OP_JMP:
+ case OP_FORLOOP:
+ case OP_FORPREP:
+ case OP_TFORLOOP: {
+ is_jmps[GETARG_sBx(i) + pc + 1] = 1;
+ break;
+ }
+ default: break;
+ }
+ }
+}
+
+static void Y_codegen (lua_State *L, Proto *p, const char *name, Y_jitbuffer *buff) {
+ Y_str2buffer(buff, LUA_HEADER);
+ OPEN_FUNC(name);
+ const Instruction *code = p->code;
+ Instruction i;
+ lu_byte *is_jmps = Y_luaM_newvector(L, p->sizecode, lu_byte);
+ memset(is_jmps, 0, p->sizecode * sizeof(is_jmps[0]));
+ /* avoid forprep redefinition */
+ lu_byte *is_defineds = Y_luaM_newvector(L, p->maxstacksize, lu_byte);
+ memset(is_defineds, 0, p->maxstacksize * sizeof(is_defineds[0]));
+ Y_setjmps(p, is_jmps);
+ int A, B, C, Bx, sBx;
+ for (int pc = 0; pc < p->sizecode; pc ++) {
+ i = code[pc];
+ OpCode op = GET_OPCODE(i);
+ SET_LABEL;
+ GET_OPERANDS;
+ switch (op) {
+ case OP_MOVE: {
+ emit_move(A, B, buff);
+ break;
+ }
+ case OP_LOADK: {
+ emit_loadk(A, Bx, buff);
+ break;
+ }
+ case OP_LOADKX: {
+ /* skip OP_LOADKX */
+ i = code[++ pc];
+ op = GET_OPCODE(i);
+ lua_assert(op == OP_EXTRAARG);
+ /* OP_EXTRAARG now */
+ int extra_Ax = GETARG_Ax(i);
+ emit_loadk(A, extra_Ax, buff);
+ break;
+ }
+ case OP_LOADBOOL: {
+ emit_loadbool(A, B, C, pc + 2, buff);
+ break;
+ }
+ case OP_LOADNIL: {
+ emit_loadnil(A, B, buff);
+ break;
+ }
+ case OP_GETUPVAL: {
+ emit_getupval(A, B, buff);
+ break;
+ }
+ case OP_GETTABUP: {
+ emit_gettabup(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_GETTABLE: {
+ emit_gettable(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_SETTABUP: {
+ emit_settabup(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_SETUPVAL: {
+ emit_setupval(A, B, pc + 1, buff);
+ break;
+ }
+ case OP_SETTABLE: {
+ emit_settable(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_NEWTABLE: {
+ emit_newtable(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_SELF: {
+ emit_self(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_ADD: {
+ emit_add(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_SUB: {
+ emit_sub(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_MUL: {
+ emit_mul(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_MOD: {
+ emit_mod(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_POW: {
+ emit_pow(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_DIV: {
+ emit_div(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_IDIV: {
+ emit_idiv(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_BAND: {
+ emit_band(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_BOR: {
+ emit_bor(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_BXOR: {
+ emit_bxor(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_SHL: {
+ emit_shl(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_SHR: {
+ emit_shr(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_UNM: {
+ emit_unm(A, B, pc + 1, buff);
+ break;
+ }
+ case OP_BNOT: {
+ emit_bnot(A, B, pc + 1, buff);
+ break;
+ }
+ case OP_NOT: {
+ emit_not(A, B, buff);
+ break;
+ }
+ case OP_LEN: {
+ emit_len(A, B, pc + 1, buff);
+ break;
+ }
+ case OP_CONCAT: {
+ emit_concat(A, B, C, buff);
+ break;
+ }
+ case OP_JMP: {
+ emit_jmp(A, pc + sBx + 1, buff);
+ break;
+ }
+ case OP_EQ:
+ case OP_LT:
+ case OP_LE: {
+ /* skip OP_JMP */
+ i = code[++ pc];
+ lua_assert(GET_OPCODE(i) == OP_JMP);
+ /* OP_JMP now */
+ int jmp_sBx = GETARG_sBx(i);
+ int jmp_A = GETARG_A(i);
+ /* pc has been increased */
+ emit_binary_test(A, B, C, pc, jmp_sBx + pc + 1, jmp_A, op, buff);
+ break;
+ }
+ case OP_TEST: {
+ /* skip OP_JMP */
+ i = code[++ pc];
+ op = GET_OPCODE(i);
+ lua_assert(op == OP_JMP);
+ /* OP_JMP now */
+ int jmp_sBx = GETARG_sBx(i);
+ int jmp_A = GETARG_A(i);
+ emit_test(A, C, jmp_sBx + pc + 1, jmp_A, buff);
+ break;
+ }
+ case OP_TESTSET: {
+ /* skip OP_JMP */
+ i = code[++ pc];
+ op = GET_OPCODE(i);
+ lua_assert(op == OP_JMP);
+ /* OP_JMP now */
+ int jmp_sBx = GETARG_sBx(i);
+ int jmp_A = GETARG_A(i);
+ emit_testset(A, B, C, jmp_sBx + pc + 1, jmp_A, buff);
+ break;
+ }
+ case OP_CALL:
+ case OP_TAILCALL: {
+ emit_call(A, B, C, pc + 1, buff);
+ break;
+ }
+ case OP_RETURN: {
+ emit_return(A, B, buff);
+ break;
+ }
+ /* Numberical for loop */
+ case OP_FORLOOP: {
+ emit_forloop(A, pc + sBx + 1, buff);
+ break;
+ }
+ case OP_FORPREP: {
+ lu_byte need_define = !is_defineds[A];
+ if (need_define) is_defineds[A] = 1;
+ emit_forprep(A, pc + sBx + 1, pc, need_define, buff);
+ break;
+ }
+ case OP_TFORCALL: {
+ /* skip OP_TFORCALL */
+ i = code[++ pc];
+ op = GET_OPCODE(i);
+ lua_assert(op == OP_TFORLOOP);
+ /* OP_TFORLOOP now */
+ emit_tforcall(A, C, GETARG_A(i), GETARG_sBx(i) + pc + 1, buff);
+ break;
+ }
+ case OP_TFORLOOP: {
+ emit_tforloop(A, sBx + pc + 1, buff);
+ break;
+ }
+ case OP_SETLIST: {
+ if (C == 0) {
+ /* skip OP_SETLIST */
+ i = code[++ pc];
+ op = GET_OPCODE(i);
+ lua_assert(op == OP_EXTRAARG);
+ /* OP_EXTRAARG now */
+ int extra_Ax = GETARG_Ax(i);
+ C = extra_Ax;
+ }
+ /* if C == 0 C = next instruciton Ax */
+ emit_setlist(A, B, C, buff);
+ break;
+ }
+ case OP_CLOSURE: {
+ emit_closure(A, Bx, buff);
+ break;
+ }
+ case OP_VARARG: {
+ emit_vararg(A, B, buff);
+ break;
+ }
+ case OP_EXTRAARG: {
+ lua_assert(0);
+ break;
+ }
+ default: break;
+ }
+ }
+ CLOSE_FUNC;
+ Y_luaM_freearray(L, is_jmps, p->sizecode);
+ Y_luaM_freearray(L, is_defineds, p->maxstacksize);
+ // printf("%s\n", &buff->buffer[strlen(LUA_HEADER)]);
+ // FILE *f = fopen("test.log", "w+");
+ // fprintf(f, "%s\n", buff->buffer);
+ // fclose(f);
+}
+
+int Y_compile (lua_State *L, Proto *p) {
+ global_State *g = G(L);
+ YJIT_Status status = p->Y_jitproto->Y_jitstatus;
+ if (status == YJIT_IS_COMPILED) return 1;
+ int tocompile = 0;
+ if (status == YJIT_MUST_COMPILE) {
+ tocompile = 1;
+ } else if (p->sizecode > g->Y_jitstate->Y_limitsize &&
+ p->Y_jitproto->Y_execcount > g->Y_jitstate->Y_limitcount) {
+ tocompile = 1;
+ }
+ if (!tocompile) return 0;
+ int is_success = 1;
+ MIR_context_t ctx = g->Y_jitstate->Y_mirctx;
+ c2mir_init(ctx);
+ MIR_gen_init(ctx, 2);
+ Y_jitbuffer buff;
+ Y_initbuffer(L, &buff, strlen(LUA_HEADER) + 4096);
+
+ char name[32];
+ snprintf(name, sizeof(name), "Y_func_%ld",
+ ++ g->Y_jitstate->Y_c2miropts.module_num);
+ Y_codegen(L, p, name, &buff);
+
+ if (!c2mir_compile(ctx, &g->Y_jitstate->Y_c2miropts, Y_getc, &buff, name, NULL)) {
+ p->Y_jitproto->Y_jitstatus = YJIT_CANT_COMPILE;
+ is_success = 0;
+ goto CLEANUP;
+ }
+ /* c2mir_compile will clear the name */
+ snprintf(name, sizeof(name), "Y_func_%ld",
+ g->Y_jitstate->Y_c2miropts.module_num);
+
+ MIR_module_t module = DLIST_TAIL(MIR_module_t, *MIR_get_module_list(ctx));
+ MIR_load_module(ctx, module);
+ MIR_link(ctx, MIR_set_gen_interface, import_resolver);
+ MIR_item_t func = DLIST_HEAD(MIR_item_t, module->items);
+ while (func) {
+ if (func->item_type == MIR_func_item && !strcmp(name, func->u.func->name)) {
+ break;
+ }
+ func = DLIST_NEXT(MIR_item_t, func);
+ }
+ if (func == NULL) {
+ p->Y_jitproto->Y_jitstatus = YJIT_CANT_COMPILE;
+ is_success = 0;
+ goto CLEANUP;
+ }
+ int (*fp)(lua_State *L) = MIR_gen(ctx, 0, func);
+ if (fp) {
+ p->Y_jitproto->Y_jitfunc = fp;
+ p->Y_jitproto->Y_jitstatus = YJIT_IS_COMPILED;
+ } else {
+ p->Y_jitproto->Y_jitfunc = NULL;
+ p->Y_jitproto->Y_jitstatus = YJIT_CANT_COMPILE;
+ is_success = 0;
+ goto CLEANUP;
+ }
+CLEANUP:
+ MIR_gen_finish(ctx);
+ c2mir_finish(ctx);
+ Y_freebuffer(&buff);
+ return is_success;
+}
+
+#define Y_JITCLOSE 0
+#define Y_JITOPEN 1
+#define Y_JITCOUNT 2
+#define Y_JITCODEGEN 3
+#define Y_JITCOMPILE 4
+#define Y_JITISCOMPILED 5
+#define Y_JITISRUNNING 6
+#define Y_JITSETLIMITSIZE 7
+#define Y_JITSETLIMITCOUNT 8
+
+static Proto* Y_checktoproto (lua_State *L, int arg) {
+ luaL_argcheck(L, lua_isfunction(L, arg) && !lua_iscfunction(L, arg), 2,
+ "Must be a Lua function");
+ LClosure *cl = cast(LClosure*, lua_topointer(L, arg));
+ return cl->p;
+}
+
+static int Y_jit (lua_State *L, int what) {
+ int res = 0;
+ global_State *g = G(L);
+ switch (what) {
+ case Y_JITCLOSE: {
+ g->Y_jitstate->Y_jitrunning = 0;
+ break;
+ }
+ case Y_JITOPEN: {
+ g->Y_jitstate->Y_jitrunning = 1;
+ break;
+ }
+ case Y_JITCOUNT: {
+ res = g->Y_jitstate->Y_jitcount;
+ break;
+ }
+ /* jit(L) will handle this case */
+ case Y_JITCODEGEN: break;
+ case Y_JITCOMPILE: {
+ Proto *p = Y_checktoproto(L, 2);
+ if (p->Y_jitproto->Y_jitstatus != YJIT_IS_COMPILED)
+ p->Y_jitproto->Y_jitstatus = YJIT_MUST_COMPILE;
+ Y_compile(L, p);
+ break;
+ }
+ case Y_JITISCOMPILED: {
+ Proto *p = Y_checktoproto(L, 2);
+ res = (p->Y_jitproto->Y_jitstatus == YJIT_IS_COMPILED);
+ break;
+ }
+ case Y_JITISRUNNING: {
+ res = g->Y_jitstate->Y_jitrunning;
+ break;
+ }
+ case Y_JITSETLIMITSIZE: {
+ res = g->Y_jitstate->Y_limitsize;
+ int ex = (int)luaL_optinteger(L, 2, 0);
+ g->Y_jitstate->Y_limitsize = ex;
+ break;
+ }
+ case Y_JITSETLIMITCOUNT: {
+ res = g->Y_jitstate->Y_limitsize;
+ int ex = (int)luaL_optinteger(L, 2, 0);
+ g->Y_jitstate->Y_limitcount = ex;
+ break;
+ }
+ default: res = -1;
+ }
+ return res;
+}
+
+int jit (lua_State *L) {
+ static const char* const opts[] = {"close", "open", "count",
+ "codegen", "compile", "iscompiled", "isrunning",
+ "setlimitsize", "setlimitcount", NULL};
+ static const int optsnum[] = {Y_JITCLOSE, Y_JITOPEN, Y_JITCOUNT,
+ Y_JITCODEGEN, Y_JITCOMPILE, Y_JITISCOMPILED, Y_JITISRUNNING,
+ Y_JITSETLIMITSIZE, Y_JITSETLIMITCOUNT};
+
+ int o = optsnum[luaL_checkoption(L, 1, "isrunning", opts)];
+ int res = Y_jit(L, o);
+ switch (o) {
+ case Y_JITCOUNT: {
+ lua_pushinteger(L, res);
+ return 1;
+ }
+ case Y_JITCODEGEN: {
+ Proto *p = Y_checktoproto(L, 2);
+ Y_jitbuffer buff;
+ Y_initbuffer(L, &buff, strlen(LUA_HEADER) + 4096);
+ Y_codegen(L, p, "Y_codegen_", &buff);
+ lua_pushlstring(L, buff.buffer, buff.size);
+ Y_freebuffer(&buff);
+ return 1;
+ }
+ case Y_JITCOMPILE:
+ case Y_JITISCOMPILED:
+ case Y_JITISRUNNING: {
+ lua_pushboolean(L, res);
+ return 1;
+ }
+ case Y_JITSETLIMITSIZE:
+ case Y_JITSETLIMITCOUNT: {
+ lua_pushinteger(L, res);
+ return 1;
+ }
+ default: break;
+ }
+ return 0;
+}
+
+static const char LUA_HEADER[] = {
+ "#ifdef __MIRC__\n"
+ "#endif\n"
+ "typedef long long size_t;\n"
+ "typedef long long ptrdiff_t;\n"
+ "typedef long long intptr_t;\n"
+ "typedef long long int64_t;\n"
+ "typedef unsigned long long uint64_t;\n"
+ "typedef int int32_t;\n"
+ "typedef unsigned int uint32_t;\n"
+ "typedef short int16_t;\n"
+ "typedef unsigned short uint16_t;\n"
+ "typedef char int8_t;\n"
+ "typedef unsigned char uint8_t;\n"
+ "typedef size_t lu_mem;\n"
+ "typedef ptrdiff_t l_mem;\n"
+ "typedef unsigned char lu_byte;\n"
+ "typedef uint16_t LuaType;\n"
+ "#define NULL ((void *)0)\n"
+ "typedef struct lua_State lua_State;\n"
+ "#define LUA_TNONE (-1)\n"
+ "#define LUA_TNIL 0\n"
+ "#define LUA_TBOOLEAN 1\n"
+ "#define LUA_TLIGHTUSERDATA 2\n"
+ "#define LUA_TNUMBER 3\n"
+ "#define LUA_TSTRING 4\n"
+ "#define LUA_TTABLE 5\n"
+ "#define LUA_TFUNCTION 6\n"
+ "#define LUA_TUSERDATA 7\n"
+ "#define LUA_TTHREAD 8\n"
+ "#define LUA_OK 0\n"
+ "typedef enum {TM_INDEX,TM_NEWINDEX,TM_GC,\n"
+ " TM_MODE,TM_LEN,TM_EQ,TM_ADD,TM_SUB,TM_MUL,\n"
+ " TM_MOD,TM_POW,TM_DIV,TM_IDIV,TM_BAND,TM_BOR,\n"
+ " TM_BXOR,TM_SHL,TM_SHR,TM_UNM,TM_BNOT,TM_LT,\n"
+ " TM_LE,TM_CONCAT,TM_CALL,TM_N\n"
+ "} TMS;\n"
+ "typedef double lua_Number;\n"
+ "typedef int64_t lua_Integer;\n"
+ "typedef uint64_t lua_Unsigned;\n"
+ "typedef int (*lua_CFunction) (lua_State *L);\n"
+ "typedef union {\n"
+ " lua_Number n;\n"
+ " double u;\n"
+ " void *s;\n"
+ " lua_Integer i;\n"
+ " long l;\n"
+ "} L_Umaxalign;\n"
+ "#define lua_assert(c) ((void)0)\n"
+ "#define check_exp(c,e) (e)\n"
+ "#define lua_longassert(c) ((void)0)\n"
+ "#define cast(t, exp) ((t)(exp))\n"
+ "#define cast_void(i) cast(void, (i))\n"
+ "#define cast_byte(i) cast(lu_byte, (i))\n"
+ "#define cast_num(i) cast(lua_Number, (i))\n"
+ "#define cast_int(i) cast(int, (i))\n"
+ "#define cast_uchar(i) cast(unsigned char, (i))\n"
+ "#define l_castS2U(i) ((lua_Unsigned)(i))\n"
+ "#define l_castU2S(i) ((lua_Integer)(i))\n"
+ "#define l_noret void\n"
+ "typedef unsigned int Instruction;\n"
+ "#define luai_numdiv(L,a,b) ((a)/(b))\n"
+ "#define luai_numadd(L,a,b) ((a)+(b))\n"
+ "#define luai_numsub(L,a,b) ((a)-(b))\n"
+ "#define luai_nummul(L,a,b) ((a)*(b))\n"
+ "#define luai_numunm(L,a) (-(a))\n"
+ "#define luai_numeq(a,b) ((a)==(b))\n"
+ "#define LUA_TLCL (LUA_TFUNCTION | (0 << 4))\n"
+ "#define LUA_TLCF (LUA_TFUNCTION | (1 << 4))\n"
+ "#define LUA_TCCL (LUA_TFUNCTION | (2 << 4))\n"
+ "#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4))\n"
+ "#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4))\n"
+ "#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4))\n"
+ "#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4))\n"
+ "#define BIT_ISCOLLECTABLE (1 << 15)\n"
+ "#define ctb(t) ((t) | BIT_ISCOLLECTABLE)\n"
+ "typedef struct GCObject GCObject;\n"
+ "#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked\n"
+ "struct GCObject {\n"
+ " CommonHeader;\n"
+ "};\n"
+ "typedef union Value {\n"
+ " GCObject *gc;\n"
+ " void *p;\n"
+ " int b;\n"
+ " lua_CFunction f;\n"
+ " lua_Integer i;\n"
+ " lua_Number n;\n"
+ "} Value;\n"
+ "#define TValuefields Value value_; LuaType tt_\n"
+ "typedef struct lua_TValue {\n"
+ " TValuefields;\n"
+ "} TValue;\n"
+ "#define NILCONSTANT {NULL}, LUA_TNIL\n"
+ "#define val_(o) ((o)->value_)\n"
+ "#define rttype(o) ((o)->tt_)\n"
+ "#define novariant(x) ((x) & 0x0F)\n"
+ "#define ttype(o) (rttype(o) & 0x7F)\n"
+ "#define ttnov(o) (novariant(rttype(o)))\n"
+ "#define checktag(o,t) (rttype(o) == (t))\n"
+ "#define checktype(o,t) (ttnov(o) == (t))\n"
+ "#define ttisnumber(o) checktype((o), LUA_TNUMBER)\n"
+ "#define ttisfloat(o) checktag((o), LUA_TNUMFLT)\n"
+ "#define ttisinteger(o) checktag((o), LUA_TNUMINT)\n"
+ "#define ttisnil(o) checktag((o), LUA_TNIL)\n"
+ "#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)\n"
+ "#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)\n"
+ "#define ttisstring(o) checktype((o), LUA_TSTRING)\n"
+ "#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))\n"
+ "#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))\n"
+ "#define ttistable(o) checktype((o), LUA_TTABLE)\n"
+ "#define ttisarray(o) (ttisiarray(o) || ttisfarray(o))\n"
+ "#define ttisLtable(o) checktag((o), ctb(LUA_TTABLE))\n"
+ "#define ttisfunction(o) checktype(o, LUA_TFUNCTION)\n"
+ "#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)\n"
+ "#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))\n"
+ "#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))\n"
+ "#define ttislcf(o) checktag((o), LUA_TLCF)\n"
+ "#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))\n"
+ "#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))\n"
+ "#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)\n"
+ "#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)\n"
+ "#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)\n"
+ "#define nvalue(o) check_exp(ttisnumber(o), \\\n"
+ " (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))\n"
+ "#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)\n"
+ "#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)\n"
+ "#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))\n"
+ "#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))\n"
+ "#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))\n"
+ "#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))\n"
+ "#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))\n"
+ "#define fvalue(o) check_exp(ttislcf(o), val_(o).f)\n"
+ "#define fcfvalue(o) check_exp(ttisfcf(o), val_(o).p)\n"
+ "#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))\n"
+ "#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)\n"
+ "#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))\n"
+ "#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))\n"
+ "#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))\n"
+ "#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)\n"
+ "#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)\n"
+ "#define checkliveness(L,obj) \\\n"
+ " lua_longassert(!iscollectable(obj) || \\\n"
+ " (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))\n"
+ "#define settt_(o,t) ((o)->tt_=(t))\n"
+ "#define setfltvalue(obj,x) \\\n"
+ " { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }\n"
+ "#define chgfltvalue(obj,x) \\\n"
+ " { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }\n"
+ "#define setivalue(obj,x) \\\n"
+ " { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }\n"
+ "#define chgivalue(obj,x) \\\n"
+ " { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }\n"
+ "#define setnilvalue(obj) settt_(obj, LUA_TNIL)\n"
+ "#define setfvalue(obj,x) \\\n"
+ " { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }\n"
+ "#define setfvalue_fastcall(obj, x, tag) \\\n"
+ "{ \\\n"
+ " TValue *io = (obj); \\\n"
+ " lua_assert(tag >= 1 && tag < 0x80); \\\n"
+ " val_(io).p = (x); \\\n"
+ "}\n"
+ "#define setpvalue(obj,x) \\\n"
+ " { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }\n"
+ "#define setbvalue(obj,x) \\\n"
+ " { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }\n"
+ "#define setgcovalue(L,obj,x) \\\n"
+ " { TValue *io = (obj); GCObject *i_g=(x); \\\n"
+ " val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }\n"
+ "#define setsvalue(L,obj,x) \\\n"
+ " { TValue *io = (obj); TString *x_ = (x); \\\n"
+ " val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \\\n"
+ " checkliveness(L,io); }\n"
+ "#define setuvalue(L,obj,x) \\\n"
+ " { TValue *io = (obj); Udata *x_ = (x); \\\n"
+ " val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \\\n"
+ " checkliveness(L,io); }\n"
+ "#define setthvalue(L,obj,x) \\\n"
+ " { TValue *io = (obj); lua_State *x_ = (x); \\\n"
+ " val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \\\n"
+ " checkliveness(L,io); }\n"
+ "#define setclLvalue(L,obj,x) \\\n"
+ " { TValue *io = (obj); LClosure *x_ = (x); \\\n"
+ " val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \\\n"
+ " checkliveness(L,io); }\n"
+ "#define setclCvalue(L,obj,x) \\\n"
+ " { TValue *io = (obj); CClosure *x_ = (x); \\\n"
+ " val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \\\n"
+ " checkliveness(L,io); }\n"
+ "#define sethvalue(L,obj,x) \\\n"
+ " { TValue *io = (obj); Table *x_ = (x); \\\n"
+ " val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \\\n"
+ " checkliveness(L,io); }\n"
+ "#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)\n"
+ "#define setobj(L,obj1,obj2) \\\n"
+ " { TValue *io1=(obj1); const TValue *io2=(obj2); io1->tt_ = io2->tt_; val_(io1).n = val_(io2).n; \\\n"
+ " (void)L; }\n"
+ "#define setobjs2s setobj\n"
+ "#define setobj2s setobj\n"
+ "#define setsvalue2s setsvalue\n"
+ "#define sethvalue2s sethvalue\n"
+ "#define setptvalue2s setptvalue\n"
+ "#define setobjt2t setobj\n"
+ "#define setobj2n setobj\n"
+ "#define setsvalue2n setsvalue\n"
+ "#define setobj2t setobj\n"
+ "typedef TValue *StkId;\n"
+ "typedef struct TString {\n"
+ " CommonHeader;\n"
+ " lu_byte extra;\n"
+ " lu_byte shrlen;\n"
+ " unsigned int hash;\n"
+ " union {\n"
+ " size_t lnglen;\n"
+ " struct TString *hnext;\n"
+ " } u;\n"
+ "} TString;\n"
+ "typedef union UTString {\n"
+ " L_Umaxalign dummy;\n"
+ " TString tsv;\n"
+ "} UTString;\n"
+ "#define getstr(ts) \\\n"
+ " check_exp(sizeof((ts)->extra), cast(char *, (ts)) + sizeof(UTString))\n"
+ "#define svalue(o) getstr(tsvalue(o))\n"
+ "#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)\n"
+ "#define vslen(o) tsslen(tsvalue(o))\n"
+ "typedef struct Udata {\n"
+ " CommonHeader;\n"
+ " LuaType ttuv_;\n"
+ " struct Table *metatable;\n"
+ " size_t len;\n"
+ " union Value user_;\n"
+ "} Udata;\n"
+ "typedef union UUdata {\n"
+ " L_Umaxalign dummy;\n"
+ " Udata uv;\n"
+ "} UUdata;\n"
+ "#define getudatamem(u) \\\n"
+ " check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata)))\n"
+ "#define setuservalue(L,u,o) \\\n"
+ " { const TValue *io=(o); Udata *iu = (u); \\\n"
+ " iu->user_ = io->value_; iu->ttuv_ = rttype(io); \\\n"
+ " checkliveness(L,io); }\n"
+ "#define getuservalue(L,u,o) \\\n"
+ " { TValue *io=(o); const Udata *iu = (u); \\\n"
+ " io->value_ = iu->user_; settt_(io, iu->ttuv_); \\\n"
+ " checkliveness(L,io); }\n"
+ "typedef struct Upvaldesc {\n"
+ " TString *name;\n"
+ " TString *usertype;\n"
+ " lu_byte instack;\n"
+ " lu_byte idx;\n"
+ "} Upvaldesc;\n"
+ "typedef struct LocVar {\n"
+ " TString *varname;\n"
+ " TString *usertype;\n"
+ " int startpc;\n"
+ " int endpc;\n"
+ "} LocVar;\n"
+ "typedef struct Proto {\n"
+ " CommonHeader;\n"
+ " lu_byte numparams;\n"
+ " lu_byte is_vararg;\n"
+ " lu_byte maxstacksize;\n"
+ " int sizeupvalues;\n"
+ " int sizek;\n"
+ " int sizecode;\n"
+ " int sizelineinfo;\n"
+ " int sizep;\n"
+ " int sizelocvars;\n"
+ " int linedefined;\n"
+ " int lastlinedefined;\n"
+ " TValue *k;\n"
+ " Instruction *code;\n"
+ " struct Proto **p;\n"
+ " int *lineinfo;\n"
+ " LocVar *locvars;\n"
+ " Upvaldesc *upvalues;\n"
+ " struct LClosure *cache;\n"
+ " TString *source;\n"
+ " GCObject *gclist;\n"
+ "} Proto;\n"
+ "typedef struct UpVal UpVal;\n"
+ "#define ClosureHeader \\\n"
+ " CommonHeader; lu_byte nupvalues; GCObject *gclist\n"
+ "typedef struct CClosure {\n"
+ " ClosureHeader;\n"
+ " lua_CFunction f;\n"
+ " TValue upvalue[1];\n"
+ "} CClosure;\n"
+ "typedef struct LClosure {\n"
+ " ClosureHeader;\n"
+ " struct Proto *p;\n"
+ " UpVal *upvals[1];\n"
+ "} LClosure;\n"
+ "typedef union Closure {\n"
+ " CClosure c;\n"
+ " LClosure l;\n"
+ "} Closure;\n"
+ "#define isLfunction(o) ttisLclosure(o)\n"
+ "#define getproto(o) (clLvalue(o)->p)\n"
+ "typedef union TKey {\n"
+ " struct {\n"
+ " TValuefields;\n"
+ " int next;\n"
+ " } nk;\n"
+ " TValue tvk;\n"
+ "} TKey;\n"
+ "#define setnodekey(L,key,obj) \\\n"
+ " { TKey *k_=(key); const TValue *io_=(obj); \\\n"
+ " k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \\\n"
+ " (void)L; checkliveness(L,io_); }\n"
+ "typedef struct Node {\n"
+ " TValue i_val;\n"
+ " TKey i_key;\n"
+ "} Node;\n"
+ "typedef struct Table {\n"
+ " CommonHeader;\n"
+ " lu_byte flags;\n"
+ " lu_byte lsizenode;\n"
+ " unsigned int sizearray;\n"
+ " TValue *array;\n"
+ " Node *node;\n"
+ " Node *lastfree;\n"
+ " struct Table *metatable;\n"
+ " GCObject *gclist;\n"
+ " unsigned int hmask;\n"
+ "} Table;\n"
+ "typedef struct Mbuffer {\n"
+ " char *buffer;\n"
+ " size_t n;\n"
+ " size_t buffsize;\n"
+ "} Mbuffer;\n"
+ "typedef struct stringtable {\n"
+ " TString **hash;\n"
+ " int nuse;\n"
+ " int size;\n"
+ "} stringtable;\n"
+ "struct lua_Debug;\n"
+ "typedef intptr_t lua_KContext;\n"
+ "typedef int(*lua_KFunction)(struct lua_State *L, int status, lua_KContext ctx);\n"
+ "typedef void *(*lua_Alloc)(void *ud, void *ptr, size_t osize,\n"
+ " size_t nsize);\n"
+ "typedef void(*lua_Hook)(struct lua_State *L, struct lua_Debug *ar);\n"
+ "typedef struct CallInfo {\n"
+ " StkId func;\n"
+ " StkId top;\n"
+ " struct CallInfo *previous, *next;\n"
+ " union {\n"
+ " struct {\n"
+ " StkId base;\n"
+ " const Instruction *savedpc;\n"
+ " } l;\n"
+ " struct {\n"
+ " lua_KFunction k;\n"
+ " ptrdiff_t old_errfunc;\n"
+ " lua_KContext ctx;\n"
+ " } c;\n"
+ " } u;\n"
+ " ptrdiff_t extra;\n"
+ " short nresults;\n"
+ " unsigned short callstatus;\n"
+ " unsigned short stacklevel;\n"
+ " lu_byte jitstatus;\n"
+ " lu_byte magic;\n"
+ "} CallInfo;\n"
+ "typedef struct global_State global_State;\n"
+ "struct lua_State {\n"
+ " CommonHeader;\n"
+ " lu_byte status;\n"
+ " StkId top;\n"
+ " global_State *l_G;\n"
+ " CallInfo *ci;\n"
+ " const Instruction *oldpc;\n"
+ " StkId stack_last;\n"
+ " StkId stack;\n"
+ " UpVal *openupval;\n"
+ " GCObject *gclist;\n"
+ " struct lua_State *twups;\n"
+ " struct lua_longjmp *errorJmp;\n"
+ " CallInfo base_ci;\n"
+ " volatile lua_Hook hook;\n"
+ " ptrdiff_t errfunc;\n"
+ " int stacksize;\n"
+ " int basehookcount;\n"
+ " int hookcount;\n"
+ " unsigned short nny;\n"
+ " unsigned short nCcalls;\n"
+ " lu_byte hookmask;\n"
+ " lu_byte allowhook;\n"
+ " unsigned short nci;\n"
+ " lu_byte magic;\n"
+ "};\n"
+ "#define G(L) (L->l_G)\n"
+ "union GCUnion {\n"
+ " GCObject gc;\n"
+ " struct TString ts;\n"
+ " struct Udata u;\n"
+ " union Closure cl;\n"
+ " struct Table h;\n"
+ " struct Proto p;\n"
+ " struct lua_State th;\n"
+ "};\n"
+ "struct UpVal {\n"
+ " TValue *v;\n"
+ " lu_mem refcount;\n"
+ " union {\n"
+ " struct {\n"
+ " UpVal *next;\n"
+ " int touched;\n"
+ " } open;\n"
+ " TValue value;\n"
+ " } u;\n"
+ "};\n"
+ "#define cast_u(o) cast(union GCUnion *, (o))\n"
+ "#define gco2ts(o) \\\n"
+ " check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))\n"
+ "#define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))\n"
+ "#define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))\n"
+ "#define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c))\n"
+ "#define gco2cl(o) \\\n"
+ " check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))\n"
+ "#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))\n"
+ "#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))\n"
+ "#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))\n"
+ "#define obj2gco(v) \\\n"
+ " check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))\n"
+ "#define LUA_FLOORN2I 0\n"
+ "#define tonumber(o,n) \\\n"
+ " (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))\n"
+ "#define tointeger(o,i) \\\n"
+ " (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))\n"
+ "#define R(i) (base + i)\n"
+ "#define K(i) (k + i)\n"
+ "#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))\n"
+ "#define inf (1./0.)\n\n"
+};
\ No newline at end of file
diff --git a/LuaJIT-5.3.6-master/src/YJIT.h b/LuaJIT-5.3.6-master/src/YJIT.h
new file mode 100644
index 0000000..49f8536
--- /dev/null
+++ b/LuaJIT-5.3.6-master/src/YJIT.h
@@ -0,0 +1,58 @@
+/*
+ * @Author: Yuerer
+ * @Date: 2021-05-19 20:03:20
+ * @LastEditTime: 2021-05-19 20:03:20
+ */
+
+#ifndef YJIT_H
+#define YJIT_H
+
+#include "lua.h"
+#include "llimits.h"
+
+#include "mir.h"
+#include "c2mir.h"
+#include "mir-gen.h"
+
+typedef struct Proto Proto;
+
+/* lbaselib.c */
+int jit (lua_State *L);
+
+/* lstate.c */
+typedef struct YJIT_State {
+ MIR_context_t Y_mirctx;
+ struct c2mir_options Y_c2miropts;
+ lu_byte Y_jitrunning;
+ int Y_limitsize;
+ int Y_limitcount;
+ int Y_jitcount;
+} YJIT_State;
+
+void Y_initjitstate (lua_State *L);
+void Y_closejitstate (lua_State *L);
+
+/* lbaselib.c */
+#define Y_JITBASEFUNCS \
+{"jit", jit}
+
+typedef enum {
+ YJIT_NOT_COMPILE = 0,
+ YJIT_CANT_COMPILE = 1,
+ YJIT_MUST_COMPILE = 2,
+ YJIT_IS_COMPILED = 3,
+} YJIT_Status;
+
+/* lfunc.c */
+typedef struct YJIT_Proto {
+ lua_CFunction Y_jitfunc;
+ YJIT_Status Y_jitstatus;
+ int Y_execcount;
+} YJIT_Proto;
+
+void Y_initjitproto (lua_State *L, Proto *p);
+void Y_closejitproto (lua_State *L, Proto *p);
+
+int Y_compile (lua_State *L, Proto *p);
+
+#endif
\ No newline at end of file
diff --git a/LuaJIT-5.3.6-master/src/YMEM.c b/LuaJIT-5.3.6-master/src/YMEM.c
new file mode 100644
index 0000000..84523f3
--- /dev/null
+++ b/LuaJIT-5.3.6-master/src/YMEM.c
@@ -0,0 +1,45 @@
+/*
+ * @Author: Yuerer
+ * @Date: 2021-05-19 20:03:20
+ * @LastEditTime: 2021-05-19 20:03:20
+ */
+
+#include "YMEM.h"
+
+#include "ldo.h"
+
+
+void Y_luaM_free_ (lua_State *L, void *block, size_t osize) {
+ global_State *g = G(L);
+ (*g->frealloc)(g->ud, block, osize, 0);
+}
+
+void *Y_luaM_malloc (lua_State *L, size_t nsize) {
+ void *newblock;
+ global_State *g = G(L);
+ newblock = (*g->frealloc)(g->ud, NULL, 0, nsize);
+ if (newblock == NULL && nsize > 0) {
+ if (g->version) {
+ luaC_fullgc(L, 1);
+ newblock = (*g->frealloc)(g->ud, NULL, 0, nsize);
+ }
+ if (newblock == NULL)
+ luaD_throw(L, LUA_ERRMEM);
+ }
+ return newblock;
+}
+
+void *Y_luaM_realloc (lua_State *L, void *block, size_t osize, size_t nsize) {
+ void *newblock;
+ global_State *g = G(L);
+ newblock = (*g->frealloc)(g->ud, block, osize, nsize);
+ if (newblock == NULL && nsize > 0) {
+ if (g->version) {
+ luaC_fullgc(L, 1);
+ newblock = (*g->frealloc)(g->ud, block, osize, nsize);
+ }
+ if (newblock == NULL)
+ luaD_throw(L, LUA_ERRMEM);
+ }
+ return newblock;
+}
\ No newline at end of file
diff --git a/LuaJIT-5.3.6-master/src/YMEM.h b/LuaJIT-5.3.6-master/src/YMEM.h
new file mode 100644
index 0000000..7dd8ced
--- /dev/null
+++ b/LuaJIT-5.3.6-master/src/YMEM.h
@@ -0,0 +1,27 @@
+/*
+ * @Author: Yuerer
+ * @Date: 2021-05-19 20:03:20
+ * @LastEditTime: 2021-05-27 14:24:20
+ */
+
+#ifndef YMEM_H
+#define YMEM_H
+
+#include "lstate.h"
+#include "llimits.h"
+
+void Y_luaM_free_ (lua_State *L, void *block, size_t osize);
+void *Y_luaM_malloc (lua_State *L, size_t nsize);
+void *Y_luaM_realloc (lua_State *L, void *block, size_t osize, size_t nsize);
+
+#define Y_luaM_free(L, b) Y_luaM_free_(L, (b), sizeof(*(b)))
+#define Y_luaM_new(L, t) cast(t*, Y_luaM_malloc(L, sizeof(t)))
+#define Y_luaM_newvector(L,n,t) \
+ cast(t*, Y_luaM_malloc(L, (n)*(sizeof(t))))
+#define Y_luaM_reallocv(L, b, on, n, t) \
+ cast(t*, Y_luaM_realloc(L, (b), (on)*(sizeof(t)), (n)*(sizeof(t))))
+
+#define Y_luaM_freemem(L, b, s) Y_luaM_free_(L, (b), (s))
+#define Y_luaM_freearray(L, b, n) Y_luaM_free_(L, (b), (n)*sizeof(*(b)))
+
+#endif
\ No newline at end of file
diff --git a/lua-5.3.6/src/lbaselib.c b/LuaJIT-5.3.6-master/src/lbaselib.c
index 6460e4f..e49ebe7 100644
--- a/lua-5.3.6/src/lbaselib.c
+++ b/LuaJIT-5.3.6-master/src/lbaselib.c
@@ -20,6 +20,8 @@
#include "lauxlib.h"
#include "lualib.h"
+#include "YGC.h"
+#include "YJIT.h"
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
@@ -479,6 +481,8 @@ static const luaL_Reg base_funcs[] = {
/* placeholders */
{"_G", NULL},
{"_VERSION", NULL},
+ Y_GCBASEFUNCS,
+ Y_JITBASEFUNCS,
{NULL, NULL}
};
diff --git a/lua-5.3.6/src/ldo.c b/LuaJIT-5.3.6-master/src/ldo.c
index 316e45c..8ef12ec 100644
--- a/lua-5.3.6/src/ldo.c
+++ b/LuaJIT-5.3.6-master/src/ldo.c
@@ -410,9 +410,10 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
** the execution ('luaV_execute') to the caller, to allow stackless
** calls.) Returns true iff function has been executed (C function).
*/
-int luaD_precall (lua_State *L, StkId func, int nresults) {
+int luaD_precall (lua_State *L, StkId func, int nresults, int need_adjust) {
lua_CFunction f;
CallInfo *ci;
+ global_State *g = G(L);
switch (ttype(func)) {
case LUA_TCCL: /* C closure */
f = clCvalue(func)->f;
@@ -460,12 +461,38 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->callstatus = CIST_LUA;
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
+ YJIT_Status status = p->Y_jitproto->Y_jitstatus;
+ if (G(L)->mainthread == L && g->Y_jitstate->Y_jitrunning) {
+ if (status != YJIT_IS_COMPILED && status != YJIT_CANT_COMPILE) {
+ if (Y_compile(L, p)) g->Y_jitstate->Y_jitcount ++;
+ }
+ if (p->Y_jitproto->Y_jitfunc != NULL) {
+ ci->u.l.savedpc ++;
+ if (++L->nCcalls >= LUAI_MAXCCALLS) {
+ if (L->nCcalls == LUAI_MAXCCALLS) {
+ luaG_runerror(L, "stack overflow");
+ }
+ else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3))) {
+ luaD_throw(L, LUA_ERRERR);
+ }
+ }
+ L->nny ++;
+ n = (*p->Y_jitproto->Y_jitfunc)(L); /* poscall will be executed inside */
+ L->nny --;
+ L->nCcalls --;
+ /* precall -> poscall(return) -> fix top
+ sometimes need to handle the return value themseleves */
+ if (need_adjust && n) L->top = L->ci->top;
+ return 2;
+ }
+ p->Y_jitproto->Y_execcount ++;
+ }
return 0;
}
default: { /* not a function */
checkstackp(L, 1, func); /* ensure space for metamethod */
tryfuncTM(L, func); /* try to get '__call' metamethod */
- return luaD_precall(L, func, nresults); /* now it must be a function */
+ return luaD_precall(L, func, nresults, need_adjust); /* now it must be a function */
}
}
}
@@ -495,7 +522,7 @@ static void stackerror (lua_State *L) {
void luaD_call (lua_State *L, StkId func, int nResults) {
if (++L->nCcalls >= LUAI_MAXCCALLS)
stackerror(L);
- if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
+ if (!luaD_precall(L, func, nResults, 0)) /* is a Lua function? */
luaV_execute(L); /* call it */
L->nCcalls--;
}
@@ -621,7 +648,7 @@ static void resume (lua_State *L, void *ud) {
StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
if (L->status == LUA_OK) { /* starting a coroutine? */
- if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
+ if (!luaD_precall(L, firstArg - 1, LUA_MULTRET, 0)) /* Lua function? */
luaV_execute(L); /* call it */
}
else { /* resuming from previous yield */
diff --git a/lua-5.3.6/src/ldo.h b/LuaJIT-5.3.6-master/src/ldo.h
index 3b2983a..a8102b0 100644
--- a/lua-5.3.6/src/ldo.h
+++ b/LuaJIT-5.3.6-master/src/ldo.h
@@ -39,7 +39,7 @@ typedef void (*Pfunc) (lua_State *L, void *ud);
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
const char *mode);
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
-LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
+LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults, int need_adjust);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
diff --git a/lua-5.3.6/src/lfunc.c b/LuaJIT-5.3.6-master/src/lfunc.c
index ccafbb8..5e7b127 100644
--- a/lua-5.3.6/src/lfunc.c
+++ b/LuaJIT-5.3.6-master/src/lfunc.c
@@ -118,6 +118,7 @@ Proto *luaF_newproto (lua_State *L) {
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
+ Y_initjitproto(L, f);
return f;
}
@@ -129,6 +130,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
+ Y_closejitproto(L, f);
luaM_free(L, f);
}
diff --git a/lua-5.3.6/src/lgc.c b/LuaJIT-5.3.6-master/src/lgc.c
index db4df82..8460dd7 100644
--- a/lua-5.3.6/src/lgc.c
+++ b/LuaJIT-5.3.6-master/src/lgc.c
@@ -25,6 +25,7 @@
#include "ltable.h"
#include "ltm.h"
+#include "YGC.h"
/*
** internal state for collector while inside the atomic phase. The
@@ -565,13 +566,13 @@ static void propagatemark (global_State *g) {
case LUA_TTABLE: {
Table *h = gco2t(o);
g->gray = h->gclist; /* remove from 'gray' list */
- size = traversetable(g, h);
+ size = (Y_isnogc(o) ? 0 : traversetable(g, h));
break;
}
case LUA_TLCL: {
LClosure *cl = gco2lcl(o);
g->gray = cl->gclist; /* remove from 'gray' list */
- size = traverseLclosure(g, cl);
+ size = (Y_isnogc(cl) ? 0 : traverseLclosure(g, cl));
break;
}
case LUA_TCCL: {
@@ -591,7 +592,7 @@ static void propagatemark (global_State *g) {
case LUA_TPROTO: {
Proto *p = gco2p(o);
g->gray = p->gclist; /* remove from 'gray' list */
- size = traverseproto(g, p);
+ size = (Y_isnogc(p) ? 0 : traverseproto(g, p));
break;
}
default: lua_assert(0); return;
@@ -736,18 +737,27 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
global_State *g = G(L);
int ow = otherwhite(g);
int white = luaC_white(g); /* current white */
+ Y_bgjob *j = Y_createbgjob(L);
while (*p != NULL && count-- > 0) {
GCObject *curr = *p;
+ if (g->gcstate == GCSswpallgc && Y_isnogc(curr)) {
+ *p = curr->next;
+ curr->next = g->Y_nogc;
+ g->Y_nogc = curr;
+ continue;
+ }
int marked = curr->marked;
if (isdeadm(ow, marked)) { /* is 'curr' dead? */
*p = curr->next; /* remove 'curr' from list */
- freeobj(L, curr); /* erase 'curr' */
+ /* try to erase 'curr' in the background */
+ Y_trybgfree(L, curr, j, &freeobj);
}
else { /* change mark to 'white' */
curr->marked = cast_byte((marked & maskcolors) | white);
p = &curr->next; /* go to next element */
}
}
+ Y_submitbgjob(L, j);
return (*p == NULL) ? NULL : p;
}
@@ -1041,7 +1051,6 @@ static lu_mem sweepstep (lua_State *L, global_State *g,
return 0;
}
-
static lu_mem singlestep (lua_State *L) {
global_State *g = G(L);
switch (g->gcstate) {
diff --git a/lua-5.3.6/src/lobject.h b/LuaJIT-5.3.6-master/src/lobject.h
index 2408861..4c12827 100644
--- a/lua-5.3.6/src/lobject.h
+++ b/LuaJIT-5.3.6-master/src/lobject.h
@@ -15,6 +15,8 @@
#include "llimits.h"
#include "lua.h"
+#include "YJIT.h"
+
/*
** Extra tags for non-values
@@ -426,6 +428,7 @@ typedef struct Proto {
struct LClosure *cache; /* last-created closure with this prototype */
TString *source; /* used for debug information */
GCObject *gclist;
+ YJIT_Proto *Y_jitproto;
} Proto;
diff --git a/lua-5.3.6/src/lstate.c b/LuaJIT-5.3.6-master/src/lstate.c
index c1a7664..146f0b8 100644
--- a/lua-5.3.6/src/lstate.c
+++ b/LuaJIT-5.3.6-master/src/lstate.c
@@ -248,6 +248,7 @@ static void close_state (lua_State *L) {
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
+ Y_closejitstate(L);
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}
@@ -328,6 +329,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->gcfinnum = 0;
g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL;
+ Y_initgcstate(L);
+ Y_initjitstate(L);
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */
diff --git a/lua-5.3.6/src/lstate.h b/LuaJIT-5.3.6-master/src/lstate.h
index 56b3741..f1c543e 100644
--- a/lua-5.3.6/src/lstate.h
+++ b/LuaJIT-5.3.6-master/src/lstate.h
@@ -14,6 +14,9 @@
#include "lzio.h"
+#include "YGC.h"
+#include "YJIT.h"
+
/*
** Some notes about garbage-collected objects: All objects in Lua must
@@ -169,6 +172,15 @@ typedef struct global_State {
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
+ GCObject *Y_nogc; /* list of objects not to be traversed or collected */
+ lu_mem Y_GCmemnogc; /* memory size of nogc linked list */
+ lu_byte Y_bgrunning; /* true if Background GC is running */
+#if !defined(LUA_USE_WINDOWS)
+ pthread_t Y_bgthread; /* background pthread */
+ pthread_mutex_t Y_bgmutex; /* background job mutex */
+ pthread_cond_t Y_bgcond;
+#endif
+ YJIT_State *Y_jitstate;
} global_State;
diff --git a/lua-5.3.6/src/lvm.c b/LuaJIT-5.3.6-master/src/lvm.c
index cc43d87..e14f963 100644
--- a/lua-5.3.6/src/lvm.c
+++ b/LuaJIT-5.3.6-master/src/lvm.c
@@ -31,6 +31,8 @@
#include "lvm.h"
+#include "YGC.h"
+
/* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 2000
@@ -645,7 +647,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
ncl->upvals[i]->refcount++;
/* new closure is white, so we do not need a barrier here */
}
- if (!isblack(p)) /* cache will not break GC invariant? */
+ if (!isblack(p) && !Y_isnogc(p) && !Y_isnogc(ncl)) /* cache will not break GC invariant? */
p->cache = ncl; /* save it on cache for reuse */
}
@@ -781,9 +783,108 @@ void luaV_finishOp (lua_State *L) {
if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
Protect(luaV_finishset(L,t,k,v,slot)); }
+#define Y_checkGC(L,c) \
+ { luaC_condGC(L, L->top = (c), /* limit of live values */ \
+ L->top = ci->top); /* restore top */ \
+ luai_threadyield(L); }
+
+void Y_luaV_gettable (lua_State *L, const TValue *t, TValue *k, StkId v) {
+ const TValue *slot;
+ if (luaV_fastget(L, t, k, slot, luaH_get)) {
+ setobj2s(L, v, slot);
+ } else {
+ luaV_finishget(L, t, k, v, slot);
+ }
+}
+
+void Y_luaV_settable (lua_State *L, const TValue *t, TValue *k, StkId v) {
+ const TValue *slot;
+ if (!luaV_fastset(L,t,k,slot,luaH_get,v)) {
+ luaV_finishset(L,t,k,v,slot);
+ }
+}
+
+void Y_luaV_newtable (lua_State *L, CallInfo *ci, StkId ra, unsigned int nasize, unsigned int nhsize) {
+ Table *t = luaH_new(L);
+ sethvalue(L, ra, t);
+ if (nasize != 0 || nhsize != 0) {
+ luaH_resize(L, t, nasize, nhsize);
+ }
+ Y_checkGC(L, ra + 1);
+}
+
+void Y_luaV_concat (lua_State *L, CallInfo *ci, int A, int B, int C) {
+ StkId ra, rb;
+ StkId base = ci->u.l.base;
+ L->top = base + C + 1;
+ Protect(luaV_concat(L, C - B + 1));
+ ra = base + A;
+ rb = base + B;
+ setobj2s(L, ra, rb);
+ checkGC(L, (ra >= rb ? ra + 1 : rb));
+ L->top = ci->top;
+}
+
+void Y_luaV_closure (lua_State *L, CallInfo *ci, LClosure *cl, int A, int Bx) {
+ StkId base = ci->u.l.base;
+ StkId ra = base + A;
+ Proto *p = cl->p->p[Bx];
+ LClosure *ncl = getcached(p, cl->upvals, base);
+ if (ncl == NULL) {
+ pushclosure(L, p, cl->upvals, base, ra);
+ } else {
+ setclLvalue(L, ra, ncl);
+ }
+ checkGC(L, ra + 1);
+}
+
+void Y_luaV_setupval (lua_State *L, LClosure *cl, StkId ra, int B) {
+ UpVal *uv = cl->upvals[B];
+ setobj(L, uv->v, ra);
+ luaC_upvalbarrier(L, uv);
+}
+void Y_luaV_setlist (lua_State *L, CallInfo *ci, StkId ra, int B, int C) {
+ int n = B;
+ int c = C; /* adjusted before calling this function */
+ unsigned int last;
+ Table *h;
+ if (n == 0) n = cast_int(L->top - ra) - 1;
+ h = hvalue(ra);
+ last = ((c - 1) * LFIELDS_PER_FLUSH) + n;
+ if (last > h->sizearray) {
+ luaH_resizearray(L, h, last);
+ }
+ for (; n > 0; n --) {
+ TValue *val = ra + n;
+ luaH_setint(L, h, last --, val);
+ luaC_barrierback(L, h, val);
+ }
+ L->top = ci->top;
+}
+
+void Y_luaV_vararg (lua_State *L, CallInfo *ci, LClosure *cl, int A, int B) {
+ StkId base = ci->u.l.base;
+ StkId ra = base + A;
+ B --;
+ int n = cast_int(base - ci->func) - cl->p->numparams - 1;
+ if (n < 0) n = 0;
+ if (B < 0) {
+ B = n;
+ Protect(luaD_checkstack(L, n));
+ ra = base + A;
+ L->top = ra + n;
+ }
+ int j;
+ for (j = 0; j < B && j < n; j ++) {
+ setobj2s(L, ra + j, base - n + j);
+ }
+ for (; j < B; j ++) {
+ setnilvalue(ra + j);
+ }
+}
-void luaV_execute (lua_State *L) {
+int luaV_execute (lua_State *L) {
CallInfo *ci = L->ci;
LClosure *cl;
TValue *k;
@@ -1131,8 +1232,10 @@ void luaV_execute (lua_State *L) {
int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */
- if (luaD_precall(L, ra, nresults)) { /* C function? */
- if (nresults >= 0)
+ /* 0 is Lua, 1 is C, 2 is jit */
+ int result = luaD_precall(L, ra, nresults, 1);
+ if (result) { /* C function? */
+ if (result == 1 && nresults >= 0)
L->top = ci->top; /* adjust results */
Protect((void)0); /* update 'base' */
}
@@ -1146,7 +1249,7 @@ void luaV_execute (lua_State *L) {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
- if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
+ if (luaD_precall(L, ra, LUA_MULTRET, 1)) { /* C function? */
Protect((void)0); /* update 'base' */
}
else {
@@ -1178,7 +1281,8 @@ void luaV_execute (lua_State *L) {
if (cl->p->sizep > 0) luaF_close(L, base);
b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */
- return; /* external invocation: return */
+ /* jit function need the value to fix the top of the stack */
+ return b; /* external invocation: return */
else { /* invocation via reentry: continue execution */
ci = L->ci;
if (b) L->top = ci->top;
diff --git a/lua-5.3.6/src/lvm.h b/LuaJIT-5.3.6-master/src/lvm.h
index a8f954f..7cc3542 100644
--- a/lua-5.3.6/src/lvm.h
+++ b/LuaJIT-5.3.6-master/src/lvm.h
@@ -103,11 +103,20 @@ LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishOp (lua_State *L);
-LUAI_FUNC void luaV_execute (lua_State *L);
+LUAI_FUNC int luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total);
LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
+LUAI_FUNC void Y_luaV_gettable (lua_State *L, const TValue *t, TValue *k, StkId v);
+LUAI_FUNC void Y_luaV_settable (lua_State *L, const TValue *t, TValue *k, StkId v);
+LUAI_FUNC void Y_luaV_newtable (lua_State *L, CallInfo *ci, StkId ra, unsigned int nasize, unsigned int nhsize);
+LUAI_FUNC void Y_luaV_concat (lua_State *L, CallInfo *ci, int A, int B, int C);
+LUAI_FUNC void Y_luaV_closure (lua_State*L, CallInfo *ci, LClosure *cl, int A, int Bx);
+LUAI_FUNC void Y_luaV_setupval (lua_State *L, LClosure *cl, StkId ra, int B);
+LUAI_FUNC void Y_luaV_setlist (lua_State *L, CallInfo *ci, StkId ra, int B, int C);
+LUAI_FUNC void Y_luaV_vararg (lua_State *L, CallInfo *ci, LClosure *cl, int A, int B);
+
#endif
The JIT files make the patch large so here is the patch which is just the core lua files as a patch not the JIT files so you can manually copy those.
diff --git a/lua-5.3.6/Makefile b/LuaJIT-5.3.6-master/Makefile
index a2820e0..dee2ee4 100644
--- a/lua-5.3.6/Makefile
+++ b/LuaJIT-5.3.6-master/Makefile
@@ -51,7 +51,12 @@ R= $V.6
# Targets start here.
all: $(PLAT)
-$(PLATS) clean:
+$(PLATS):
+ cd mir && $(MAKE)
+ cd src && $(MAKE) $@
+
+clean:
+ cd mir && $(MAKE) $@
cd src && $(MAKE) $@
test: dummy
diff --git a/lua-5.3.6/src/Makefile b/LuaJIT-5.3.6-master/src/Makefile
index a13afb9..d16b769 100644
--- a/lua-5.3.6/src/Makefile
+++ b/LuaJIT-5.3.6-master/src/Makefile
@@ -19,9 +19,9 @@ SYSCFLAGS=
SYSLDFLAGS=
SYSLIBS=
-MYCFLAGS=
-MYLDFLAGS=
-MYLIBS=
+MYCFLAGS=-I../mir/ -I../mir/c2mir
+MYLDFLAGS=-L../mir/
+MYLIBS=-lmir
MYOBJS=
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
@@ -31,7 +31,7 @@ PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
- ltm.o lundump.o lvm.o lzio.o
+ ltm.o lundump.o lvm.o lzio.o YMEM.o YGC.o YJIT.o
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
@@ -95,22 +95,21 @@ bsd:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
c89:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89"
@echo ''
- @echo '*** C89 does not guarantee 64-bit integers for Lua.'
+ @echo '*** C89 does not support Lua-NOGC for Lua.'
@echo ''
freebsd:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -I/usr/include/edit" SYSLIBS="-Wl,-E -ledit" CC="cc"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE -I/usr/include/edit" SYSLIBS="-Wl,-E -ledit" CC="cc"
generic: $(ALL)
linux:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -lpthread -L../mir/build/ -lmir"
macosx:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline -lpthread"
mingw:
$(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \
@@ -133,7 +132,7 @@ lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
ltable.h lundump.h lvm.h
lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
-lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
+lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h YGC.h
lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
@@ -152,7 +151,7 @@ ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
lgc.h lstate.h ltm.h lzio.h lmem.h
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
+ llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h YGC.h
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
@@ -172,7 +171,7 @@ lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
ldo.h lfunc.h lstring.h lgc.h ltable.h
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
- lstring.h ltable.h
+ lstring.h ltable.h YGC.h
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
@@ -190,8 +189,10 @@ lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
- ltable.h lvm.h
+ ltable.h lvm.h YGC.h
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
lobject.h ltm.h lzio.h
-
+YMEM.o: YMEM.h lstate.h
+YGC.o: YGC.c lgc.h lfunc.h ltable.h lstring.h lauxlib.h YMEM.h
+YJIT.o: YJIT.c YMEM.h
# (end of Makefile)
diff --git a/lua-5.3.6/src/lbaselib.c b/LuaJIT-5.3.6-master/src/lbaselib.c
index 6460e4f..e49ebe7 100644
--- a/lua-5.3.6/src/lbaselib.c
+++ b/LuaJIT-5.3.6-master/src/lbaselib.c
@@ -20,6 +20,8 @@
#include "lauxlib.h"
#include "lualib.h"
+#include "YGC.h"
+#include "YJIT.h"
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
@@ -479,6 +481,8 @@ static const luaL_Reg base_funcs[] = {
/* placeholders */
{"_G", NULL},
{"_VERSION", NULL},
+ Y_GCBASEFUNCS,
+ Y_JITBASEFUNCS,
{NULL, NULL}
};
diff --git a/lua-5.3.6/src/ldo.c b/LuaJIT-5.3.6-master/src/ldo.c
index 316e45c..8ef12ec 100644
--- a/lua-5.3.6/src/ldo.c
+++ b/LuaJIT-5.3.6-master/src/ldo.c
@@ -410,9 +410,10 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
** the execution ('luaV_execute') to the caller, to allow stackless
** calls.) Returns true iff function has been executed (C function).
*/
-int luaD_precall (lua_State *L, StkId func, int nresults) {
+int luaD_precall (lua_State *L, StkId func, int nresults, int need_adjust) {
lua_CFunction f;
CallInfo *ci;
+ global_State *g = G(L);
switch (ttype(func)) {
case LUA_TCCL: /* C closure */
f = clCvalue(func)->f;
@@ -460,12 +461,38 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->callstatus = CIST_LUA;
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
+ YJIT_Status status = p->Y_jitproto->Y_jitstatus;
+ if (G(L)->mainthread == L && g->Y_jitstate->Y_jitrunning) {
+ if (status != YJIT_IS_COMPILED && status != YJIT_CANT_COMPILE) {
+ if (Y_compile(L, p)) g->Y_jitstate->Y_jitcount ++;
+ }
+ if (p->Y_jitproto->Y_jitfunc != NULL) {
+ ci->u.l.savedpc ++;
+ if (++L->nCcalls >= LUAI_MAXCCALLS) {
+ if (L->nCcalls == LUAI_MAXCCALLS) {
+ luaG_runerror(L, "stack overflow");
+ }
+ else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3))) {
+ luaD_throw(L, LUA_ERRERR);
+ }
+ }
+ L->nny ++;
+ n = (*p->Y_jitproto->Y_jitfunc)(L); /* poscall will be executed inside */
+ L->nny --;
+ L->nCcalls --;
+ /* precall -> poscall(return) -> fix top
+ sometimes need to handle the return value themseleves */
+ if (need_adjust && n) L->top = L->ci->top;
+ return 2;
+ }
+ p->Y_jitproto->Y_execcount ++;
+ }
return 0;
}
default: { /* not a function */
checkstackp(L, 1, func); /* ensure space for metamethod */
tryfuncTM(L, func); /* try to get '__call' metamethod */
- return luaD_precall(L, func, nresults); /* now it must be a function */
+ return luaD_precall(L, func, nresults, need_adjust); /* now it must be a function */
}
}
}
@@ -495,7 +522,7 @@ static void stackerror (lua_State *L) {
void luaD_call (lua_State *L, StkId func, int nResults) {
if (++L->nCcalls >= LUAI_MAXCCALLS)
stackerror(L);
- if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
+ if (!luaD_precall(L, func, nResults, 0)) /* is a Lua function? */
luaV_execute(L); /* call it */
L->nCcalls--;
}
@@ -621,7 +648,7 @@ static void resume (lua_State *L, void *ud) {
StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
if (L->status == LUA_OK) { /* starting a coroutine? */
- if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
+ if (!luaD_precall(L, firstArg - 1, LUA_MULTRET, 0)) /* Lua function? */
luaV_execute(L); /* call it */
}
else { /* resuming from previous yield */
diff --git a/lua-5.3.6/src/ldo.h b/LuaJIT-5.3.6-master/src/ldo.h
index 3b2983a..a8102b0 100644
--- a/lua-5.3.6/src/ldo.h
+++ b/LuaJIT-5.3.6-master/src/ldo.h
@@ -39,7 +39,7 @@ typedef void (*Pfunc) (lua_State *L, void *ud);
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
const char *mode);
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
-LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
+LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults, int need_adjust);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
diff --git a/lua-5.3.6/src/lfunc.c b/LuaJIT-5.3.6-master/src/lfunc.c
index ccafbb8..5e7b127 100644
--- a/lua-5.3.6/src/lfunc.c
+++ b/LuaJIT-5.3.6-master/src/lfunc.c
@@ -118,6 +118,7 @@ Proto *luaF_newproto (lua_State *L) {
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
+ Y_initjitproto(L, f);
return f;
}
@@ -129,6 +130,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
+ Y_closejitproto(L, f);
luaM_free(L, f);
}
diff --git a/lua-5.3.6/src/lgc.c b/LuaJIT-5.3.6-master/src/lgc.c
index db4df82..8460dd7 100644
--- a/lua-5.3.6/src/lgc.c
+++ b/LuaJIT-5.3.6-master/src/lgc.c
@@ -25,6 +25,7 @@
#include "ltable.h"
#include "ltm.h"
+#include "YGC.h"
/*
** internal state for collector while inside the atomic phase. The
@@ -565,13 +566,13 @@ static void propagatemark (global_State *g) {
case LUA_TTABLE: {
Table *h = gco2t(o);
g->gray = h->gclist; /* remove from 'gray' list */
- size = traversetable(g, h);
+ size = (Y_isnogc(o) ? 0 : traversetable(g, h));
break;
}
case LUA_TLCL: {
LClosure *cl = gco2lcl(o);
g->gray = cl->gclist; /* remove from 'gray' list */
- size = traverseLclosure(g, cl);
+ size = (Y_isnogc(cl) ? 0 : traverseLclosure(g, cl));
break;
}
case LUA_TCCL: {
@@ -591,7 +592,7 @@ static void propagatemark (global_State *g) {
case LUA_TPROTO: {
Proto *p = gco2p(o);
g->gray = p->gclist; /* remove from 'gray' list */
- size = traverseproto(g, p);
+ size = (Y_isnogc(p) ? 0 : traverseproto(g, p));
break;
}
default: lua_assert(0); return;
@@ -736,18 +737,27 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
global_State *g = G(L);
int ow = otherwhite(g);
int white = luaC_white(g); /* current white */
+ Y_bgjob *j = Y_createbgjob(L);
while (*p != NULL && count-- > 0) {
GCObject *curr = *p;
+ if (g->gcstate == GCSswpallgc && Y_isnogc(curr)) {
+ *p = curr->next;
+ curr->next = g->Y_nogc;
+ g->Y_nogc = curr;
+ continue;
+ }
int marked = curr->marked;
if (isdeadm(ow, marked)) { /* is 'curr' dead? */
*p = curr->next; /* remove 'curr' from list */
- freeobj(L, curr); /* erase 'curr' */
+ /* try to erase 'curr' in the background */
+ Y_trybgfree(L, curr, j, &freeobj);
}
else { /* change mark to 'white' */
curr->marked = cast_byte((marked & maskcolors) | white);
p = &curr->next; /* go to next element */
}
}
+ Y_submitbgjob(L, j);
return (*p == NULL) ? NULL : p;
}
@@ -1041,7 +1051,6 @@ static lu_mem sweepstep (lua_State *L, global_State *g,
return 0;
}
-
static lu_mem singlestep (lua_State *L) {
global_State *g = G(L);
switch (g->gcstate) {
diff --git a/lua-5.3.6/src/lobject.h b/LuaJIT-5.3.6-master/src/lobject.h
index 2408861..4c12827 100644
--- a/lua-5.3.6/src/lobject.h
+++ b/LuaJIT-5.3.6-master/src/lobject.h
@@ -15,6 +15,8 @@
#include "llimits.h"
#include "lua.h"
+#include "YJIT.h"
+
/*
** Extra tags for non-values
@@ -426,6 +428,7 @@ typedef struct Proto {
struct LClosure *cache; /* last-created closure with this prototype */
TString *source; /* used for debug information */
GCObject *gclist;
+ YJIT_Proto *Y_jitproto;
} Proto;
diff --git a/lua-5.3.6/src/lstate.c b/LuaJIT-5.3.6-master/src/lstate.c
index c1a7664..146f0b8 100644
--- a/lua-5.3.6/src/lstate.c
+++ b/LuaJIT-5.3.6-master/src/lstate.c
@@ -248,6 +248,7 @@ static void close_state (lua_State *L) {
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
+ Y_closejitstate(L);
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}
@@ -328,6 +329,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->gcfinnum = 0;
g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL;
+ Y_initgcstate(L);
+ Y_initjitstate(L);
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */
diff --git a/lua-5.3.6/src/lstate.h b/LuaJIT-5.3.6-master/src/lstate.h
index 56b3741..f1c543e 100644
--- a/lua-5.3.6/src/lstate.h
+++ b/LuaJIT-5.3.6-master/src/lstate.h
@@ -14,6 +14,9 @@
#include "lzio.h"
+#include "YGC.h"
+#include "YJIT.h"
+
/*
** Some notes about garbage-collected objects: All objects in Lua must
@@ -169,6 +172,15 @@ typedef struct global_State {
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
+ GCObject *Y_nogc; /* list of objects not to be traversed or collected */
+ lu_mem Y_GCmemnogc; /* memory size of nogc linked list */
+ lu_byte Y_bgrunning; /* true if Background GC is running */
+#if !defined(LUA_USE_WINDOWS)
+ pthread_t Y_bgthread; /* background pthread */
+ pthread_mutex_t Y_bgmutex; /* background job mutex */
+ pthread_cond_t Y_bgcond;
+#endif
+ YJIT_State *Y_jitstate;
} global_State;
diff --git a/lua-5.3.6/src/lvm.c b/LuaJIT-5.3.6-master/src/lvm.c
index cc43d87..e14f963 100644
--- a/lua-5.3.6/src/lvm.c
+++ b/LuaJIT-5.3.6-master/src/lvm.c
@@ -31,6 +31,8 @@
#include "lvm.h"
+#include "YGC.h"
+
/* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 2000
@@ -645,7 +647,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
ncl->upvals[i]->refcount++;
/* new closure is white, so we do not need a barrier here */
}
- if (!isblack(p)) /* cache will not break GC invariant? */
+ if (!isblack(p) && !Y_isnogc(p) && !Y_isnogc(ncl)) /* cache will not break GC invariant? */
p->cache = ncl; /* save it on cache for reuse */
}
@@ -781,9 +783,108 @@ void luaV_finishOp (lua_State *L) {
if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
Protect(luaV_finishset(L,t,k,v,slot)); }
+#define Y_checkGC(L,c) \
+ { luaC_condGC(L, L->top = (c), /* limit of live values */ \
+ L->top = ci->top); /* restore top */ \
+ luai_threadyield(L); }
+
+void Y_luaV_gettable (lua_State *L, const TValue *t, TValue *k, StkId v) {
+ const TValue *slot;
+ if (luaV_fastget(L, t, k, slot, luaH_get)) {
+ setobj2s(L, v, slot);
+ } else {
+ luaV_finishget(L, t, k, v, slot);
+ }
+}
+
+void Y_luaV_settable (lua_State *L, const TValue *t, TValue *k, StkId v) {
+ const TValue *slot;
+ if (!luaV_fastset(L,t,k,slot,luaH_get,v)) {
+ luaV_finishset(L,t,k,v,slot);
+ }
+}
+
+void Y_luaV_newtable (lua_State *L, CallInfo *ci, StkId ra, unsigned int nasize, unsigned int nhsize) {
+ Table *t = luaH_new(L);
+ sethvalue(L, ra, t);
+ if (nasize != 0 || nhsize != 0) {
+ luaH_resize(L, t, nasize, nhsize);
+ }
+ Y_checkGC(L, ra + 1);
+}
+
+void Y_luaV_concat (lua_State *L, CallInfo *ci, int A, int B, int C) {
+ StkId ra, rb;
+ StkId base = ci->u.l.base;
+ L->top = base + C + 1;
+ Protect(luaV_concat(L, C - B + 1));
+ ra = base + A;
+ rb = base + B;
+ setobj2s(L, ra, rb);
+ checkGC(L, (ra >= rb ? ra + 1 : rb));
+ L->top = ci->top;
+}
+
+void Y_luaV_closure (lua_State *L, CallInfo *ci, LClosure *cl, int A, int Bx) {
+ StkId base = ci->u.l.base;
+ StkId ra = base + A;
+ Proto *p = cl->p->p[Bx];
+ LClosure *ncl = getcached(p, cl->upvals, base);
+ if (ncl == NULL) {
+ pushclosure(L, p, cl->upvals, base, ra);
+ } else {
+ setclLvalue(L, ra, ncl);
+ }
+ checkGC(L, ra + 1);
+}
+
+void Y_luaV_setupval (lua_State *L, LClosure *cl, StkId ra, int B) {
+ UpVal *uv = cl->upvals[B];
+ setobj(L, uv->v, ra);
+ luaC_upvalbarrier(L, uv);
+}
+void Y_luaV_setlist (lua_State *L, CallInfo *ci, StkId ra, int B, int C) {
+ int n = B;
+ int c = C; /* adjusted before calling this function */
+ unsigned int last;
+ Table *h;
+ if (n == 0) n = cast_int(L->top - ra) - 1;
+ h = hvalue(ra);
+ last = ((c - 1) * LFIELDS_PER_FLUSH) + n;
+ if (last > h->sizearray) {
+ luaH_resizearray(L, h, last);
+ }
+ for (; n > 0; n --) {
+ TValue *val = ra + n;
+ luaH_setint(L, h, last --, val);
+ luaC_barrierback(L, h, val);
+ }
+ L->top = ci->top;
+}
+
+void Y_luaV_vararg (lua_State *L, CallInfo *ci, LClosure *cl, int A, int B) {
+ StkId base = ci->u.l.base;
+ StkId ra = base + A;
+ B --;
+ int n = cast_int(base - ci->func) - cl->p->numparams - 1;
+ if (n < 0) n = 0;
+ if (B < 0) {
+ B = n;
+ Protect(luaD_checkstack(L, n));
+ ra = base + A;
+ L->top = ra + n;
+ }
+ int j;
+ for (j = 0; j < B && j < n; j ++) {
+ setobj2s(L, ra + j, base - n + j);
+ }
+ for (; j < B; j ++) {
+ setnilvalue(ra + j);
+ }
+}
-void luaV_execute (lua_State *L) {
+int luaV_execute (lua_State *L) {
CallInfo *ci = L->ci;
LClosure *cl;
TValue *k;
@@ -1131,8 +1232,10 @@ void luaV_execute (lua_State *L) {
int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */
- if (luaD_precall(L, ra, nresults)) { /* C function? */
- if (nresults >= 0)
+ /* 0 is Lua, 1 is C, 2 is jit */
+ int result = luaD_precall(L, ra, nresults, 1);
+ if (result) { /* C function? */
+ if (result == 1 && nresults >= 0)
L->top = ci->top; /* adjust results */
Protect((void)0); /* update 'base' */
}
@@ -1146,7 +1249,7 @@ void luaV_execute (lua_State *L) {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
- if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
+ if (luaD_precall(L, ra, LUA_MULTRET, 1)) { /* C function? */
Protect((void)0); /* update 'base' */
}
else {
@@ -1178,7 +1281,8 @@ void luaV_execute (lua_State *L) {
if (cl->p->sizep > 0) luaF_close(L, base);
b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */
- return; /* external invocation: return */
+ /* jit function need the value to fix the top of the stack */
+ return b; /* external invocation: return */
else { /* invocation via reentry: continue execution */
ci = L->ci;
if (b) L->top = ci->top;
diff --git a/lua-5.3.6/src/lvm.h b/LuaJIT-5.3.6-master/src/lvm.h
index a8f954f..7cc3542 100644
--- a/lua-5.3.6/src/lvm.h
+++ b/LuaJIT-5.3.6-master/src/lvm.h
@@ -103,11 +103,20 @@ LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishOp (lua_State *L);
-LUAI_FUNC void luaV_execute (lua_State *L);
+LUAI_FUNC int luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total);
LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
+LUAI_FUNC void Y_luaV_gettable (lua_State *L, const TValue *t, TValue *k, StkId v);
+LUAI_FUNC void Y_luaV_settable (lua_State *L, const TValue *t, TValue *k, StkId v);
+LUAI_FUNC void Y_luaV_newtable (lua_State *L, CallInfo *ci, StkId ra, unsigned int nasize, unsigned int nhsize);
+LUAI_FUNC void Y_luaV_concat (lua_State *L, CallInfo *ci, int A, int B, int C);
+LUAI_FUNC void Y_luaV_closure (lua_State*L, CallInfo *ci, LClosure *cl, int A, int Bx);
+LUAI_FUNC void Y_luaV_setupval (lua_State *L, LClosure *cl, StkId ra, int B);
+LUAI_FUNC void Y_luaV_setlist (lua_State *L, CallInfo *ci, StkId ra, int B, int C);
+LUAI_FUNC void Y_luaV_vararg (lua_State *L, CallInfo *ci, LClosure *cl, int A, int B);
+
#endif
JIT536.patch