root/lib/lua/lundump.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. error
  2. LoadBlock
  3. LoadChar
  4. LoadInt
  5. LoadNumber
  6. LoadString
  7. LoadCode
  8. LoadConstants
  9. LoadDebug
  10. LoadFunction
  11. LoadHeader
  12. luaU_undump
  13. luaU_header

   1 /*
   2 ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
   3 ** load precompiled Lua chunks
   4 ** See Copyright Notice in lua.h
   5 */
   6 
   7 #include <string.h>
   8 
   9 #define lundump_c
  10 #define LUA_CORE
  11 
  12 #include "lua.h"
  13 
  14 #include "ldebug.h"
  15 #include "ldo.h"
  16 #include "lfunc.h"
  17 #include "lmem.h"
  18 #include "lobject.h"
  19 #include "lstring.h"
  20 #include "lundump.h"
  21 #include "lzio.h"
  22 
  23 typedef struct {
  24  lua_State* L;
  25  ZIO* Z;
  26  Mbuffer* b;
  27  const char* name;
  28 } LoadState;
  29 
  30 #ifdef LUAC_TRUST_BINARIES
  31 #define IF(c,s)
  32 #define error(S,s)
  33 #else
  34 #define IF(c,s)         if (c) error(S,s)
  35 
  36 static void error(LoadState* S, const char* why)
  37 {
  38  luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
  39  luaD_throw(S->L,LUA_ERRSYNTAX);
  40 }
  41 #endif
  42 
  43 #define LoadMem(S,b,n,size)     LoadBlock(S,b,(n)*(size))
  44 #define LoadByte(S)             (lu_byte)LoadChar(S)
  45 #define LoadVar(S,x)            LoadMem(S,&x,1,sizeof(x))
  46 #define LoadVector(S,b,n,size)  LoadMem(S,b,n,size)
  47 
  48 static void LoadBlock(LoadState* S, void* b, size_t size)
  49 {
  50  size_t r=luaZ_read(S->Z,b,size);
  51  IF (r!=0, "unexpected end");
  52 }
  53 
  54 static int LoadChar(LoadState* S)
  55 {
  56  char x;
  57  LoadVar(S,x);
  58  return x;
  59 }
  60 
  61 static int LoadInt(LoadState* S)
  62 {
  63  int x;
  64  LoadVar(S,x);
  65  IF (x<0, "bad integer");
  66  return x;
  67 }
  68 
  69 static lua_Number LoadNumber(LoadState* S)
  70 {
  71  lua_Number x;
  72  LoadVar(S,x);
  73  return x;
  74 }
  75 
  76 static TString* LoadString(LoadState* S)
  77 {
  78  size_t size;
  79  LoadVar(S,size);
  80  if (size==0)
  81   return NULL;
  82  else
  83  {
  84   char* s=luaZ_openspace(S->L,S->b,size);
  85   LoadBlock(S,s,size);
  86   return luaS_newlstr(S->L,s,size-1);           /* remove trailing '\0' */
  87  }
  88 }
  89 
  90 static void LoadCode(LoadState* S, Proto* f)
  91 {
  92  int n=LoadInt(S);
  93  f->code=luaM_newvector(S->L,n,Instruction);
  94  f->sizecode=n;
  95  LoadVector(S,f->code,n,sizeof(Instruction));
  96 }
  97 
  98 static Proto* LoadFunction(LoadState* S, TString* p);
  99 
 100 static void LoadConstants(LoadState* S, Proto* f)
 101 {
 102  int i,n;
 103  n=LoadInt(S);
 104  f->k=luaM_newvector(S->L,n,TValue);
 105  f->sizek=n;
 106  for (i=0; i<n; i++) setnilvalue(&f->k[i]);
 107  for (i=0; i<n; i++)
 108  {
 109   TValue* o=&f->k[i];
 110   int t=LoadChar(S);
 111   switch (t)
 112   {
 113    case LUA_TNIL:
 114         setnilvalue(o);
 115         break;
 116    case LUA_TBOOLEAN:
 117         setbvalue(o,LoadChar(S)!=0);
 118         break;
 119    case LUA_TNUMBER:
 120         setnvalue(o,LoadNumber(S));
 121         break;
 122    case LUA_TSTRING:
 123         setsvalue2n(S->L,o,LoadString(S));
 124         break;
 125    default:
 126         error(S,"bad constant");
 127         break;
 128   }
 129  }
 130  n=LoadInt(S);
 131  f->p=luaM_newvector(S->L,n,Proto*);
 132  f->sizep=n;
 133  for (i=0; i<n; i++) f->p[i]=NULL;
 134  for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
 135 }
 136 
 137 static void LoadDebug(LoadState* S, Proto* f)
 138 {
 139  int i,n;
 140  n=LoadInt(S);
 141  f->lineinfo=luaM_newvector(S->L,n,int);
 142  f->sizelineinfo=n;
 143  LoadVector(S,f->lineinfo,n,sizeof(int));
 144  n=LoadInt(S);
 145  f->locvars=luaM_newvector(S->L,n,LocVar);
 146  f->sizelocvars=n;
 147  for (i=0; i<n; i++) f->locvars[i].varname=NULL;
 148  for (i=0; i<n; i++)
 149  {
 150   f->locvars[i].varname=LoadString(S);
 151   f->locvars[i].startpc=LoadInt(S);
 152   f->locvars[i].endpc=LoadInt(S);
 153  }
 154  n=LoadInt(S);
 155  f->upvalues=luaM_newvector(S->L,n,TString*);
 156  f->sizeupvalues=n;
 157  for (i=0; i<n; i++) f->upvalues[i]=NULL;
 158  for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
 159 }
 160 
 161 static Proto* LoadFunction(LoadState* S, TString* p)
 162 {
 163  Proto* f;
 164  if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
 165  f=luaF_newproto(S->L);
 166  setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
 167  f->source=LoadString(S); if (f->source==NULL) f->source=p;
 168  f->linedefined=LoadInt(S);
 169  f->lastlinedefined=LoadInt(S);
 170  f->nups=LoadByte(S);
 171  f->numparams=LoadByte(S);
 172  f->is_vararg=LoadByte(S);
 173  f->maxstacksize=LoadByte(S);
 174  LoadCode(S,f);
 175  LoadConstants(S,f);
 176  LoadDebug(S,f);
 177  IF (!luaG_checkcode(f), "bad code");
 178  S->L->top--;
 179  S->L->nCcalls--;
 180  return f;
 181 }
 182 
 183 static void LoadHeader(LoadState* S)
 184 {
 185  char h[LUAC_HEADERSIZE];
 186  char s[LUAC_HEADERSIZE];
 187  luaU_header(h);
 188  LoadBlock(S,s,LUAC_HEADERSIZE);
 189  IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
 190 }
 191 
 192 /*
 193 ** load precompiled chunk
 194 */
 195 LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
 196 {
 197  LoadState S;
 198  if (*name=='@' || *name=='=')
 199   S.name=name+1;
 200  else if (*name==LUA_SIGNATURE[0])
 201   S.name="binary string";
 202  else
 203   S.name=name;
 204  S.L=L;
 205  S.Z=Z;
 206  S.b=buff;
 207  LoadHeader(&S);
 208  return LoadFunction(&S,luaS_newliteral(L,"=?"));
 209 }
 210 
 211 /*
 212 * make header
 213 */
 214 LUAI_FUNC void luaU_header (char* h)
 215 {
 216  int x=1;
 217  memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
 218  h+=sizeof(LUA_SIGNATURE)-1;
 219  *h++=(char)LUAC_VERSION;
 220  *h++=(char)LUAC_FORMAT;
 221  *h++=(char)*(char*)&x;                         /* endianness */
 222  *h++=(char)sizeof(int);
 223  *h++=(char)sizeof(size_t);
 224  *h++=(char)sizeof(Instruction);
 225  *h++=(char)sizeof(lua_Number);
 226  *h++=(char)(((lua_Number)0.5)==0);             /* is lua_Number integral? */
 227 }

/* [<][>][^][v][top][bottom][index][help] */