?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /*
  2. ** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $
  3. ** load precompiled Lua chunks
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7. #define lundump_c
  8. #define LUA_CORE
  9.  
  10. #include "lprefix.h"
  11.  
  12.  
  13. #include <string.h>
  14.  
  15. #include "lua.h"
  16.  
  17. #include "ldebug.h"
  18. #include "ldo.h"
  19. #include "lfunc.h"
  20. #include "lmem.h"
  21. #include "lobject.h"
  22. #include "lstring.h"
  23. #include "lundump.h"
  24. #include "lzio.h"
  25.  
  26.  
  27. #if !defined(luai_verifycode)
  28. #define luai_verifycode(L,b,f)  /* empty */
  29. #endif
  30.  
  31.  
  32. typedef struct {
  33.   lua_State *L;
  34.   ZIO *Z;
  35.   const char *name;
  36. } LoadState;
  37.  
  38.  
  39. static l_noret error(LoadState *S, const char *why) {
  40.   luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
  41.   luaD_throw(S->L, LUA_ERRSYNTAX);
  42. }
  43.  
  44.  
  45. /*
  46. ** All high-level loads go through LoadVector; you can change it to
  47. ** adapt to the endianness of the input
  48. */
  49. #define LoadVector(S,b,n)       LoadBlock(S,b,(n)*sizeof((b)[0]))
  50.  
  51. static void LoadBlock (LoadState *S, void *b, size_t size) {
  52.   if (luaZ_read(S->Z, b, size) != 0)
  53.     error(S, "truncated");
  54. }
  55.  
  56.  
  57. #define LoadVar(S,x)            LoadVector(S,&x,1)
  58.  
  59.  
  60. static lu_byte LoadByte (LoadState *S) {
  61.   lu_byte x;
  62.   LoadVar(S, x);
  63.   return x;
  64. }
  65.  
  66.  
  67. static int LoadInt (LoadState *S) {
  68.   int x;
  69.   LoadVar(S, x);
  70.   return x;
  71. }
  72.  
  73.  
  74. static lua_Number LoadNumber (LoadState *S) {
  75.   lua_Number x;
  76.   LoadVar(S, x);
  77.   return x;
  78. }
  79.  
  80.  
  81. static lua_Integer LoadInteger (LoadState *S) {
  82.   lua_Integer x;
  83.   LoadVar(S, x);
  84.   return x;
  85. }
  86.  
  87.  
  88. static TString *LoadString (LoadState *S, Proto *p) {
  89.   lua_State *L = S->L;
  90.   size_t size = LoadByte(S);
  91.   TString *ts;
  92.   if (size == 0xFF)
  93.     LoadVar(S, size);
  94.   if (size == 0)
  95.     return NULL;
  96.   else if (--size <= LUAI_MAXSHORTLEN) {  /* short string? */
  97.     char buff[LUAI_MAXSHORTLEN];
  98.     LoadVector(S, buff, size);
  99.     ts = luaS_newlstr(L, buff, size);
  100.   }
  101.   else {  /* long string */
  102.     ts = luaS_createlngstrobj(L, size);
  103.     setsvalue2s(L, L->top, ts);  /* anchor it ('loadVector' can GC) */
  104.     luaD_inctop(L);
  105.     LoadVector(S, getstr(ts), size);  /* load directly in final place */
  106.     L->top--;  /* pop string */
  107.   }
  108.   luaC_objbarrier(L, p, ts);
  109.   return ts;
  110. }
  111.  
  112.  
  113. static void LoadCode (LoadState *S, Proto *f) {
  114.   int n = LoadInt(S);
  115.   f->code = luaM_newvector(S->L, n, Instruction);
  116.   f->sizecode = n;
  117.   LoadVector(S, f->code, n);
  118. }
  119.  
  120.  
  121. static void LoadFunction(LoadState *S, Proto *f, TString *psource);
  122.  
  123.  
  124. static void LoadConstants (LoadState *S, Proto *f) {
  125.   int i;
  126.   int n = LoadInt(S);
  127.   f->k = luaM_newvector(S->L, n, TValue);
  128.   f->sizek = n;
  129.   for (i = 0; i < n; i++)
  130.     setnilvalue(&f->k[i]);
  131.   for (i = 0; i < n; i++) {
  132.     TValue *o = &f->k[i];
  133.     int t = LoadByte(S);
  134.     switch (t) {
  135.     case LUA_TNIL:
  136.       setnilvalue(o);
  137.       break;
  138.     case LUA_TBOOLEAN:
  139.       setbvalue(o, LoadByte(S));
  140.       break;
  141.     case LUA_TNUMFLT:
  142.       setfltvalue(o, LoadNumber(S));
  143.       break;
  144.     case LUA_TNUMINT:
  145.       setivalue(o, LoadInteger(S));
  146.       break;
  147.     case LUA_TSHRSTR:
  148.     case LUA_TLNGSTR:
  149.       setsvalue2n(S->L, o, LoadString(S, f));
  150.       break;
  151.     default:
  152.       lua_assert(0);
  153.     }
  154.   }
  155. }
  156.  
  157.  
  158. static void LoadProtos (LoadState *S, Proto *f) {
  159.   int i;
  160.   int n = LoadInt(S);
  161.   f->p = luaM_newvector(S->L, n, Proto *);
  162.   f->sizep = n;
  163.   for (i = 0; i < n; i++)
  164.     f->p[i] = NULL;
  165.   for (i = 0; i < n; i++) {
  166.     f->p[i] = luaF_newproto(S->L);
  167.     luaC_objbarrier(S->L, f, f->p[i]);
  168.     LoadFunction(S, f->p[i], f->source);
  169.   }
  170. }
  171.  
  172.  
  173. static void LoadUpvalues (LoadState *S, Proto *f) {
  174.   int i, n;
  175.   n = LoadInt(S);
  176.   f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
  177.   f->sizeupvalues = n;
  178.   for (i = 0; i < n; i++)
  179.     f->upvalues[i].name = NULL;
  180.   for (i = 0; i < n; i++) {
  181.     f->upvalues[i].instack = LoadByte(S);
  182.     f->upvalues[i].idx = LoadByte(S);
  183.   }
  184. }
  185.  
  186.  
  187. static void LoadDebug (LoadState *S, Proto *f) {
  188.   int i, n;
  189.   n = LoadInt(S);
  190.   f->lineinfo = luaM_newvector(S->L, n, int);
  191.   f->sizelineinfo = n;
  192.   LoadVector(S, f->lineinfo, n);
  193.   n = LoadInt(S);
  194.   f->locvars = luaM_newvector(S->L, n, LocVar);
  195.   f->sizelocvars = n;
  196.   for (i = 0; i < n; i++)
  197.     f->locvars[i].varname = NULL;
  198.   for (i = 0; i < n; i++) {
  199.     f->locvars[i].varname = LoadString(S, f);
  200.     f->locvars[i].startpc = LoadInt(S);
  201.     f->locvars[i].endpc = LoadInt(S);
  202.   }
  203.   n = LoadInt(S);
  204.   for (i = 0; i < n; i++)
  205.     f->upvalues[i].name = LoadString(S, f);
  206. }
  207.  
  208.  
  209. static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
  210.   f->source = LoadString(S, f);
  211.   if (f->source == NULL)  /* no source in dump? */
  212.     f->source = psource;  /* reuse parent's source */
  213.   f->linedefined = LoadInt(S);
  214.   f->lastlinedefined = LoadInt(S);
  215.   f->numparams = LoadByte(S);
  216.   f->is_vararg = LoadByte(S);
  217.   f->maxstacksize = LoadByte(S);
  218.   LoadCode(S, f);
  219.   LoadConstants(S, f);
  220.   LoadUpvalues(S, f);
  221.   LoadProtos(S, f);
  222.   LoadDebug(S, f);
  223. }
  224.  
  225.  
  226. static void checkliteral (LoadState *S, const char *s, const char *msg) {
  227.   char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
  228.   size_t len = strlen(s);
  229.   LoadVector(S, buff, len);
  230.   if (memcmp(s, buff, len) != 0)
  231.     error(S, msg);
  232. }
  233.  
  234.  
  235. static void fchecksize (LoadState *S, size_t size, const char *tname) {
  236.   if (LoadByte(S) != size)
  237.     error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
  238. }
  239.  
  240.  
  241. #define checksize(S,t)  fchecksize(S,sizeof(t),#t)
  242.  
  243. static void checkHeader (LoadState *S) {
  244.   checkliteral(S, LUA_SIGNATURE + 1, "not a");  /* 1st char already checked */
  245.   if (LoadByte(S) != LUAC_VERSION)
  246.     error(S, "version mismatch in");
  247.   if (LoadByte(S) != LUAC_FORMAT)
  248.     error(S, "format mismatch in");
  249.   checkliteral(S, LUAC_DATA, "corrupted");
  250.   checksize(S, int);
  251.   checksize(S, size_t);
  252.   checksize(S, Instruction);
  253.   checksize(S, lua_Integer);
  254.   checksize(S, lua_Number);
  255.   if (LoadInteger(S) != LUAC_INT)
  256.     error(S, "endianness mismatch in");
  257.   if (LoadNumber(S) != LUAC_NUM)
  258.     error(S, "float format mismatch in");
  259. }
  260.  
  261.  
  262. /*
  263. ** load precompiled chunk
  264. */
  265. LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
  266.   LoadState S;
  267.   LClosure *cl;
  268.   if (*name == '@' || *name == '=')
  269.     S.name = name + 1;
  270.   else if (*name == LUA_SIGNATURE[0])
  271.     S.name = "binary string";
  272.   else
  273.     S.name = name;
  274.   S.L = L;
  275.   S.Z = Z;
  276.   checkHeader(&S);
  277.   cl = luaF_newLclosure(L, LoadByte(&S));
  278.   setclLvalue(L, L->top, cl);
  279.   luaD_inctop(L);
  280.   cl->p = luaF_newproto(L);
  281.   luaC_objbarrier(L, cl, cl->p);
  282.   LoadFunction(&S, cl->p, NULL);
  283.   lua_assert(cl->nupvalues == cl->p->sizeupvalues);
  284.   luai_verifycode(L, buff, cl->p);
  285.   return cl;
  286. }
  287.  
  288.