0002-Changes-to-the-core-Lua-interpreter.patch 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. From aac8fb43a394f2fcf709ec0240a6a04c7d6d8860 Mon Sep 17 00:00:00 2001
  2. From: Hugo Musso Gualandi <[email protected]>
  3. Date: Mon, 26 Apr 2021 13:25:53 -0300
  4. Subject: [PATCH 2/2] Changes to the core Lua interpreter
  5. ---
  6. src/lfunc.c | 1 +
  7. src/lobject.h | 7 +++++
  8. src/luaconf.h | 6 +---
  9. src/lvm.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++-
  10. 4 files changed, 86 insertions(+), 6 deletions(-)
  11. diff --git a/src/lfunc.c b/src/lfunc.c
  12. index f5889a2..8948099 100644
  13. --- a/src/lfunc.c
  14. +++ b/src/lfunc.c
  15. @@ -260,6 +260,7 @@ Proto *luaF_newproto (lua_State *L) {
  16. f->linedefined = 0;
  17. f->lastlinedefined = 0;
  18. f->source = NULL;
  19. + f->aot_implementation = NULL;
  20. return f;
  21. }
  22. diff --git a/src/lobject.h b/src/lobject.h
  23. index 950bebb..06319c8 100644
  24. --- a/src/lobject.h
  25. +++ b/src/lobject.h
  26. @@ -533,6 +533,12 @@ typedef struct AbsLineInfo {
  27. int line;
  28. } AbsLineInfo;
  29. +
  30. +/*
  31. +** AOT implementation
  32. +*/
  33. +typedef void (*AotCompiledFunction) (lua_State *L, struct CallInfo *ci);
  34. +
  35. /*
  36. ** Function Prototypes
  37. */
  38. @@ -559,6 +565,7 @@ typedef struct Proto {
  39. LocVar *locvars; /* information about local variables (debug information) */
  40. TString *source; /* used for debug information */
  41. GCObject *gclist;
  42. + AotCompiledFunction aot_implementation;
  43. } Proto;
  44. /* }================================================================== */
  45. diff --git a/src/luaconf.h b/src/luaconf.h
  46. index e64d2ee..0f8340a 100644
  47. --- a/src/luaconf.h
  48. +++ b/src/luaconf.h
  49. @@ -305,12 +305,8 @@
  50. ** give a warning about it. To avoid these warnings, change to the
  51. ** default definition.
  52. */
  53. -#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
  54. - defined(__ELF__) /* { */
  55. -#define LUAI_FUNC __attribute__((visibility("internal"))) extern
  56. -#else /* }{ */
  57. +/* AOT: export all internal APIs */
  58. #define LUAI_FUNC extern
  59. -#endif /* } */
  60. #define LUAI_DDEC(dec) LUAI_FUNC dec
  61. #define LUAI_DDEF /* empty */
  62. diff --git a/src/lvm.c b/src/lvm.c
  63. index c9729bc..9a9a6dc 100644
  64. --- a/src/lvm.c
  65. +++ b/src/lvm.c
  66. @@ -30,6 +30,11 @@
  67. #include "ltm.h"
  68. #include "lvm.h"
  69. +/*
  70. +** We use ifdefs to clearly mark the parts that we had to change
  71. +*/
  72. +#define LUAOT 1
  73. +
  74. /*
  75. ** By default, use jump tables in the main interpreter loop on gcc
  76. @@ -1125,7 +1130,6 @@ void luaV_finishOp (lua_State *L) {
  77. #define vmcase(l) case l:
  78. #define vmbreak break
  79. -
  80. void luaV_execute (lua_State *L, CallInfo *ci) {
  81. LClosure *cl;
  82. TValue *k;
  83. @@ -1135,10 +1139,19 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
  84. #if LUA_USE_JUMPTABLE
  85. #include "ljumptab.h"
  86. #endif
  87. +#if LUAOT
  88. + trap = L->hookmask;
  89. + cl = clLvalue(s2v(ci->func));
  90. + lua_assert(ci->callstatus & CIST_FRESH);
  91. + if (cl->p->aot_implementation) {
  92. + return cl->p->aot_implementation(L, ci);
  93. + }
  94. +#else
  95. startfunc:
  96. trap = L->hookmask;
  97. returning: /* trap already set */
  98. cl = clLvalue(s2v(ci->func));
  99. +#endif
  100. k = cl->p->k;
  101. pc = ci->u.l.savedpc;
  102. if (l_unlikely(trap)) {
  103. @@ -1613,6 +1626,24 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
  104. }
  105. vmbreak;
  106. }
  107. +#if LUAOT
  108. + vmcase(OP_CALL) {
  109. + CallInfo *newci;
  110. + int b = GETARG_B(i);
  111. + int nresults = GETARG_C(i) - 1;
  112. + if (b != 0) /* fixed number of arguments? */
  113. + L->top = ra + b; /* top signals number of arguments */
  114. + /* else previous instruction set top */
  115. + savepc(L); /* in case of errors */
  116. + if ((newci = luaD_precall(L, ra, nresults)) == NULL)
  117. + updatetrap(ci); /* C call; nothing else to be done */
  118. + else { /* Lua call: run function in this same C frame */
  119. + newci->callstatus = CIST_FRESH;
  120. + Protect(luaV_execute(L, newci));
  121. + }
  122. + vmbreak;
  123. + }
  124. +#else
  125. vmcase(OP_CALL) {
  126. CallInfo *newci;
  127. int b = GETARG_B(i);
  128. @@ -1630,6 +1661,44 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
  129. }
  130. vmbreak;
  131. }
  132. +#endif
  133. +
  134. +#if LUAOT
  135. + vmcase(OP_TAILCALL) {
  136. + int b = GETARG_B(i); /* number of arguments + 1 (function) */
  137. + int nparams1 = GETARG_C(i);
  138. + /* delta is virtual 'func' - real 'func' (vararg functions) */
  139. + int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
  140. + if (b != 0)
  141. + L->top = ra + b;
  142. + else /* previous instruction set top */
  143. + b = cast_int(L->top - ra);
  144. + savepc(ci); /* several calls here can raise errors */
  145. + if (TESTARG_k(i)) {
  146. + luaF_closeupval(L, base); /* close upvalues from current call */
  147. + lua_assert(L->tbclist < base); /* no pending tbc variables */
  148. + lua_assert(base == ci->func + 1);
  149. + }
  150. + while (!ttisfunction(s2v(ra))) { /* not a function? */
  151. + luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
  152. + b++; /* there is now one extra argument */
  153. + checkstackGCp(L, 1, ra);
  154. + }
  155. + if (!ttisLclosure(s2v(ra))) { /* C function? */
  156. + luaD_precall(L, ra, LUA_MULTRET); /* call it */
  157. + updatetrap(ci);
  158. + updatestack(ci); /* stack may have been relocated */
  159. + ci->func -= delta; /* restore 'func' (if vararg) */
  160. + luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */
  161. + updatetrap(ci); /* 'luaD_poscall' can change hooks */
  162. + goto ret; /* caller returns after the tail call */
  163. + }
  164. + ci->func -= delta; /* restore 'func' (if vararg) */
  165. + luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
  166. + return luaV_execute(L, ci); /* execute the callee */
  167. + vmbreak;
  168. + }
  169. +#else
  170. vmcase(OP_TAILCALL) {
  171. int b = GETARG_B(i); /* number of arguments + 1 (function) */
  172. int nparams1 = GETARG_C(i);
  173. @@ -1662,7 +1731,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
  174. ci->func -= delta; /* restore 'func' (if vararg) */
  175. luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
  176. goto startfunc; /* execute the callee */
  177. + vmbreak;
  178. }
  179. +#endif
  180. vmcase(OP_RETURN) {
  181. int n = GETARG_B(i) - 1; /* number of results */
  182. int nparams1 = GETARG_C(i);
  183. @@ -1719,12 +1790,17 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
  184. }
  185. }
  186. ret: /* return from a Lua function */
  187. +#if LUAOT
  188. + lua_assert(ci->callstatus & CIST_FRESH);
  189. + return;
  190. +#else
  191. if (ci->callstatus & CIST_FRESH)
  192. return; /* end this frame */
  193. else {
  194. ci = ci->previous;
  195. goto returning; /* continue running caller in this frame */
  196. }
  197. +#endif
  198. }
  199. vmcase(OP_FORLOOP) {
  200. if (ttisinteger(s2v(ra + 2))) { /* integer loop? */
  201. --
  202. 2.30.2