"Fossies" - the Fresh Open Source Software Archive

Member "memcached-1.6.15/vendor/lua/src/lundump.c" (1 Oct 2021, 7865 Bytes) of package /linux/www/memcached-1.6.15.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2 ** $Id: lundump.c $
    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 <limits.h>
   14 #include <string.h>
   15 
   16 #include "lua.h"
   17 
   18 #include "ldebug.h"
   19 #include "ldo.h"
   20 #include "lfunc.h"
   21 #include "lmem.h"
   22 #include "lobject.h"
   23 #include "lstring.h"
   24 #include "lundump.h"
   25 #include "lzio.h"
   26 
   27 
   28 #if !defined(luai_verifycode)
   29 #define luai_verifycode(L,f)  /* empty */
   30 #endif
   31 
   32 
   33 typedef struct {
   34   lua_State *L;
   35   ZIO *Z;
   36   const char *name;
   37 } LoadState;
   38 
   39 
   40 static l_noret error (LoadState *S, const char *why) {
   41   luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why);
   42   luaD_throw(S->L, LUA_ERRSYNTAX);
   43 }
   44 
   45 
   46 /*
   47 ** All high-level loads go through loadVector; you can change it to
   48 ** adapt to the endianness of the input
   49 */
   50 #define loadVector(S,b,n)   loadBlock(S,b,(n)*sizeof((b)[0]))
   51 
   52 static void loadBlock (LoadState *S, void *b, size_t size) {
   53   if (luaZ_read(S->Z, b, size) != 0)
   54     error(S, "truncated chunk");
   55 }
   56 
   57 
   58 #define loadVar(S,x)        loadVector(S,&x,1)
   59 
   60 
   61 static lu_byte loadByte (LoadState *S) {
   62   int b = zgetc(S->Z);
   63   if (b == EOZ)
   64     error(S, "truncated chunk");
   65   return cast_byte(b);
   66 }
   67 
   68 
   69 static size_t loadUnsigned (LoadState *S, size_t limit) {
   70   size_t x = 0;
   71   int b;
   72   limit >>= 7;
   73   do {
   74     b = loadByte(S);
   75     if (x >= limit)
   76       error(S, "integer overflow");
   77     x = (x << 7) | (b & 0x7f);
   78   } while ((b & 0x80) == 0);
   79   return x;
   80 }
   81 
   82 
   83 static size_t loadSize (LoadState *S) {
   84   return loadUnsigned(S, ~(size_t)0);
   85 }
   86 
   87 
   88 static int loadInt (LoadState *S) {
   89   return cast_int(loadUnsigned(S, INT_MAX));
   90 }
   91 
   92 
   93 static lua_Number loadNumber (LoadState *S) {
   94   lua_Number x;
   95   loadVar(S, x);
   96   return x;
   97 }
   98 
   99 
  100 static lua_Integer loadInteger (LoadState *S) {
  101   lua_Integer x;
  102   loadVar(S, x);
  103   return x;
  104 }
  105 
  106 
  107 /*
  108 ** Load a nullable string into prototype 'p'.
  109 */
  110 static TString *loadStringN (LoadState *S, Proto *p) {
  111   lua_State *L = S->L;
  112   TString *ts;
  113   size_t size = loadSize(S);
  114   if (size == 0)  /* no string? */
  115     return NULL;
  116   else if (--size <= LUAI_MAXSHORTLEN) {  /* short string? */
  117     char buff[LUAI_MAXSHORTLEN];
  118     loadVector(S, buff, size);  /* load string into buffer */
  119     ts = luaS_newlstr(L, buff, size);  /* create string */
  120   }
  121   else {  /* long string */
  122     ts = luaS_createlngstrobj(L, size);  /* create string */
  123     setsvalue2s(L, L->top, ts);  /* anchor it ('loadVector' can GC) */
  124     luaD_inctop(L);
  125     loadVector(S, getstr(ts), size);  /* load directly in final place */
  126     L->top--;  /* pop string */
  127   }
  128   luaC_objbarrier(L, p, ts);
  129   return ts;
  130 }
  131 
  132 
  133 /*
  134 ** Load a non-nullable string into prototype 'p'.
  135 */
  136 static TString *loadString (LoadState *S, Proto *p) {
  137   TString *st = loadStringN(S, p);
  138   if (st == NULL)
  139     error(S, "bad format for constant string");
  140   return st;
  141 }
  142 
  143 
  144 static void loadCode (LoadState *S, Proto *f) {
  145   int n = loadInt(S);
  146   f->code = luaM_newvectorchecked(S->L, n, Instruction);
  147   f->sizecode = n;
  148   loadVector(S, f->code, n);
  149 }
  150 
  151 
  152 static void loadFunction(LoadState *S, Proto *f, TString *psource);
  153 
  154 
  155 static void loadConstants (LoadState *S, Proto *f) {
  156   int i;
  157   int n = loadInt(S);
  158   f->k = luaM_newvectorchecked(S->L, n, TValue);
  159   f->sizek = n;
  160   for (i = 0; i < n; i++)
  161     setnilvalue(&f->k[i]);
  162   for (i = 0; i < n; i++) {
  163     TValue *o = &f->k[i];
  164     int t = loadByte(S);
  165     switch (t) {
  166       case LUA_VNIL:
  167         setnilvalue(o);
  168         break;
  169       case LUA_VFALSE:
  170         setbfvalue(o);
  171         break;
  172       case LUA_VTRUE:
  173         setbtvalue(o);
  174         break;
  175       case LUA_VNUMFLT:
  176         setfltvalue(o, loadNumber(S));
  177         break;
  178       case LUA_VNUMINT:
  179         setivalue(o, loadInteger(S));
  180         break;
  181       case LUA_VSHRSTR:
  182       case LUA_VLNGSTR:
  183         setsvalue2n(S->L, o, loadString(S, f));
  184         break;
  185       default: lua_assert(0);
  186     }
  187   }
  188 }
  189 
  190 
  191 static void loadProtos (LoadState *S, Proto *f) {
  192   int i;
  193   int n = loadInt(S);
  194   f->p = luaM_newvectorchecked(S->L, n, Proto *);
  195   f->sizep = n;
  196   for (i = 0; i < n; i++)
  197     f->p[i] = NULL;
  198   for (i = 0; i < n; i++) {
  199     f->p[i] = luaF_newproto(S->L);
  200     luaC_objbarrier(S->L, f, f->p[i]);
  201     loadFunction(S, f->p[i], f->source);
  202   }
  203 }
  204 
  205 
  206 /*
  207 ** Load the upvalues for a function. The names must be filled first,
  208 ** because the filling of the other fields can raise read errors and
  209 ** the creation of the error message can call an emergency collection;
  210 ** in that case all prototypes must be consistent for the GC.
  211 */
  212 static void loadUpvalues (LoadState *S, Proto *f) {
  213   int i, n;
  214   n = loadInt(S);
  215   f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc);
  216   f->sizeupvalues = n;
  217   for (i = 0; i < n; i++)  /* make array valid for GC */
  218     f->upvalues[i].name = NULL;
  219   for (i = 0; i < n; i++) {  /* following calls can raise errors */
  220     f->upvalues[i].instack = loadByte(S);
  221     f->upvalues[i].idx = loadByte(S);
  222     f->upvalues[i].kind = loadByte(S);
  223   }
  224 }
  225 
  226 
  227 static void loadDebug (LoadState *S, Proto *f) {
  228   int i, n;
  229   n = loadInt(S);
  230   f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte);
  231   f->sizelineinfo = n;
  232   loadVector(S, f->lineinfo, n);
  233   n = loadInt(S);
  234   f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo);
  235   f->sizeabslineinfo = n;
  236   for (i = 0; i < n; i++) {
  237     f->abslineinfo[i].pc = loadInt(S);
  238     f->abslineinfo[i].line = loadInt(S);
  239   }
  240   n = loadInt(S);
  241   f->locvars = luaM_newvectorchecked(S->L, n, LocVar);
  242   f->sizelocvars = n;
  243   for (i = 0; i < n; i++)
  244     f->locvars[i].varname = NULL;
  245   for (i = 0; i < n; i++) {
  246     f->locvars[i].varname = loadStringN(S, f);
  247     f->locvars[i].startpc = loadInt(S);
  248     f->locvars[i].endpc = loadInt(S);
  249   }
  250   n = loadInt(S);
  251   for (i = 0; i < n; i++)
  252     f->upvalues[i].name = loadStringN(S, f);
  253 }
  254 
  255 
  256 static void loadFunction (LoadState *S, Proto *f, TString *psource) {
  257   f->source = loadStringN(S, f);
  258   if (f->source == NULL)  /* no source in dump? */
  259     f->source = psource;  /* reuse parent's source */
  260   f->linedefined = loadInt(S);
  261   f->lastlinedefined = loadInt(S);
  262   f->numparams = loadByte(S);
  263   f->is_vararg = loadByte(S);
  264   f->maxstacksize = loadByte(S);
  265   loadCode(S, f);
  266   loadConstants(S, f);
  267   loadUpvalues(S, f);
  268   loadProtos(S, f);
  269   loadDebug(S, f);
  270 }
  271 
  272 
  273 static void checkliteral (LoadState *S, const char *s, const char *msg) {
  274   char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
  275   size_t len = strlen(s);
  276   loadVector(S, buff, len);
  277   if (memcmp(s, buff, len) != 0)
  278     error(S, msg);
  279 }
  280 
  281 
  282 static void fchecksize (LoadState *S, size_t size, const char *tname) {
  283   if (loadByte(S) != size)
  284     error(S, luaO_pushfstring(S->L, "%s size mismatch", tname));
  285 }
  286 
  287 
  288 #define checksize(S,t)  fchecksize(S,sizeof(t),#t)
  289 
  290 static void checkHeader (LoadState *S) {
  291   /* skip 1st char (already read and checked) */
  292   checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk");
  293   if (loadByte(S) != LUAC_VERSION)
  294     error(S, "version mismatch");
  295   if (loadByte(S) != LUAC_FORMAT)
  296     error(S, "format mismatch");
  297   checkliteral(S, LUAC_DATA, "corrupted chunk");
  298   checksize(S, Instruction);
  299   checksize(S, lua_Integer);
  300   checksize(S, lua_Number);
  301   if (loadInteger(S) != LUAC_INT)
  302     error(S, "integer format mismatch");
  303   if (loadNumber(S) != LUAC_NUM)
  304     error(S, "float format mismatch");
  305 }
  306 
  307 
  308 /*
  309 ** Load precompiled chunk.
  310 */
  311 LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
  312   LoadState S;
  313   LClosure *cl;
  314   if (*name == '@' || *name == '=')
  315     S.name = name + 1;
  316   else if (*name == LUA_SIGNATURE[0])
  317     S.name = "binary string";
  318   else
  319     S.name = name;
  320   S.L = L;
  321   S.Z = Z;
  322   checkHeader(&S);
  323   cl = luaF_newLclosure(L, loadByte(&S));
  324   setclLvalue2s(L, L->top, cl);
  325   luaD_inctop(L);
  326   cl->p = luaF_newproto(L);
  327   luaC_objbarrier(L, cl, cl->p);
  328   loadFunction(&S, cl->p, NULL);
  329   lua_assert(cl->nupvalues == cl->p->sizeupvalues);
  330   luai_verifycode(L, cl->p);
  331   return cl;
  332 }
  333