LCOV - code coverage report
Current view: top level - src - lundump.c Coverage Total Hit
Test: Lua 5.3.6 Lines: 95.8 % 166 159
Test Date: 2024-04-28 10:23:15
Legend: Lines: hit not hit

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

Generated by: LCOV version 2.0-1