Browse Source

Changes to the core Lua interpreter

Hugo Musso Gualandi 4 years ago
parent
commit
aac8fb43a3
4 changed files with 86 additions and 6 deletions
  1. 1 0
      src/lfunc.c
  2. 7 0
      src/lobject.h
  3. 1 5
      src/luaconf.h
  4. 77 1
      src/lvm.c

+ 1 - 0
src/lfunc.c

@@ -260,6 +260,7 @@ Proto *luaF_newproto (lua_State *L) {
   f->linedefined = 0;
   f->lastlinedefined = 0;
   f->source = NULL;
+  f->aot_implementation = NULL;
   return f;
 }
 

+ 7 - 0
src/lobject.h

@@ -533,6 +533,12 @@ typedef struct AbsLineInfo {
   int line;
 } AbsLineInfo;
 
+
+/*
+** AOT implementation
+*/
+typedef void (*AotCompiledFunction) (lua_State *L, struct CallInfo *ci);
+
 /*
 ** Function Prototypes
 */
@@ -559,6 +565,7 @@ typedef struct Proto {
   LocVar *locvars;  /* information about local variables (debug information) */
   TString  *source;  /* used for debug information */
   GCObject *gclist;
+  AotCompiledFunction aot_implementation;
 } Proto;
 
 /* }================================================================== */

+ 1 - 5
src/luaconf.h

@@ -305,12 +305,8 @@
 ** give a warning about it. To avoid these warnings, change to the
 ** default definition.
 */
-#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
-    defined(__ELF__)		/* { */
-#define LUAI_FUNC	__attribute__((visibility("internal"))) extern
-#else				/* }{ */
+/* AOT: export all internal APIs */
 #define LUAI_FUNC	extern
-#endif				/* } */
 
 #define LUAI_DDEC(dec)	LUAI_FUNC dec
 #define LUAI_DDEF	/* empty */

+ 77 - 1
src/lvm.c

@@ -30,6 +30,11 @@
 #include "ltm.h"
 #include "lvm.h"
 
+/*
+** We use ifdefs to clearly mark the parts that we had to change
+*/
+#define LUAOT 1
+
 
 /*
 ** By default, use jump tables in the main interpreter loop on gcc
@@ -1125,7 +1130,6 @@ void luaV_finishOp (lua_State *L) {
 #define vmcase(l)	case l:
 #define vmbreak		break
 
-
 void luaV_execute (lua_State *L, CallInfo *ci) {
   LClosure *cl;
   TValue *k;
@@ -1135,10 +1139,19 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
 #if LUA_USE_JUMPTABLE
 #include "ljumptab.h"
 #endif
+#if LUAOT
+  trap = L->hookmask;
+  cl = clLvalue(s2v(ci->func));
+  lua_assert(ci->callstatus & CIST_FRESH);
+  if (cl->p->aot_implementation) {
+      return cl->p->aot_implementation(L, ci);
+  }
+#else
  startfunc:
   trap = L->hookmask;
  returning:  /* trap already set */
   cl = clLvalue(s2v(ci->func));
+#endif
   k = cl->p->k;
   pc = ci->u.l.savedpc;
   if (l_unlikely(trap)) {
@@ -1613,6 +1626,24 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         }
         vmbreak;
       }
+#if LUAOT
+      vmcase(OP_CALL) {
+        CallInfo *newci;
+        int b = GETARG_B(i);
+        int nresults = GETARG_C(i) - 1;
+        if (b != 0)  /* fixed number of arguments? */
+          L->top = ra + b;  /* top signals number of arguments */
+        /* else previous instruction set top */
+        savepc(L);  /* in case of errors */
+        if ((newci = luaD_precall(L, ra, nresults)) == NULL)
+          updatetrap(ci);  /* C call; nothing else to be done */
+        else {  /* Lua call: run function in this same C frame */
+          newci->callstatus = CIST_FRESH;
+          Protect(luaV_execute(L, newci));
+        }
+        vmbreak;
+      }
+#else
       vmcase(OP_CALL) {
         CallInfo *newci;
         int b = GETARG_B(i);
@@ -1630,6 +1661,44 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         }
         vmbreak;
       }
+#endif
+
+#if LUAOT
+      vmcase(OP_TAILCALL) {
+        int b = GETARG_B(i);  /* number of arguments + 1 (function) */
+        int nparams1 = GETARG_C(i);
+        /* delta is virtual 'func' - real 'func' (vararg functions) */
+        int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
+        if (b != 0)
+          L->top = ra + b;
+        else  /* previous instruction set top */
+          b = cast_int(L->top - ra);
+        savepc(ci);  /* several calls here can raise errors */
+        if (TESTARG_k(i)) {
+          luaF_closeupval(L, base);  /* close upvalues from current call */
+          lua_assert(L->tbclist < base);  /* no pending tbc variables */
+          lua_assert(base == ci->func + 1);
+        }
+        while (!ttisfunction(s2v(ra))) {  /* not a function? */
+          luaD_tryfuncTM(L, ra);  /* try '__call' metamethod */
+          b++;  /* there is now one extra argument */
+          checkstackGCp(L, 1, ra);
+        }
+        if (!ttisLclosure(s2v(ra))) {  /* C function? */
+          luaD_precall(L, ra, LUA_MULTRET);  /* call it */
+          updatetrap(ci);
+          updatestack(ci);  /* stack may have been relocated */
+          ci->func -= delta;  /* restore 'func' (if vararg) */
+          luaD_poscall(L, ci, cast_int(L->top - ra));  /* finish caller */
+          updatetrap(ci);  /* 'luaD_poscall' can change hooks */
+          goto ret;  /* caller returns after the tail call */
+        }
+        ci->func -= delta;  /* restore 'func' (if vararg) */
+        luaD_pretailcall(L, ci, ra, b);  /* prepare call frame */
+        return luaV_execute(L, ci); /* execute the callee */
+        vmbreak;
+      }
+#else
       vmcase(OP_TAILCALL) {
         int b = GETARG_B(i);  /* number of arguments + 1 (function) */
         int nparams1 = GETARG_C(i);
@@ -1662,7 +1731,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         ci->func -= delta;  /* restore 'func' (if vararg) */
         luaD_pretailcall(L, ci, ra, b);  /* prepare call frame */
         goto startfunc;  /* execute the callee */
+        vmbreak;
       }
+#endif
       vmcase(OP_RETURN) {
         int n = GETARG_B(i) - 1;  /* number of results */
         int nparams1 = GETARG_C(i);
@@ -1719,12 +1790,17 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
           }
         }
        ret:  /* return from a Lua function */
+#if LUAOT
+        lua_assert(ci->callstatus & CIST_FRESH);
+        return;
+#else
         if (ci->callstatus & CIST_FRESH)
           return;  /* end this frame */
         else {
           ci = ci->previous;
           goto returning;  /* continue running caller in this frame */
         }
+#endif
       }
       vmcase(OP_FORLOOP) {
         if (ttisinteger(s2v(ra + 2))) {  /* integer loop? */