?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /*
  2. ** $Id: ldump.c $
  3. ** save precompiled Lua chunks
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7. #define ldump_c
  8. #define LUA_CORE
  9.  
  10. #include "lprefix.h"
  11.  
  12.  
  13. #include <stddef.h>
  14.  
  15. #include "lua.h"
  16.  
  17. #include "lobject.h"
  18. #include "lstate.h"
  19. #include "lundump.h"
  20.  
  21.  
  22. typedef struct {
  23.   lua_State *L;
  24.   lua_Writer writer;
  25.   void *data;
  26.   int strip;
  27.   int status;
  28. } DumpState;
  29.  
  30.  
  31. /*
  32. ** All high-level dumps go through dumpVector; you can change it to
  33. ** change the endianness of the result
  34. */
  35. #define dumpVector(D,v,n)       dumpBlock(D,v,(n)*sizeof((v)[0]))
  36.  
  37. #define dumpLiteral(D, s)       dumpBlock(D,s,sizeof(s) - sizeof(char))
  38.  
  39.  
  40. static void dumpBlock (DumpState *D, const void *b, size_t size) {
  41.   if (D->status == 0 && size > 0) {
  42.     lua_unlock(D->L);
  43.     D->status = (*D->writer)(D->L, b, size, D->data);
  44.     lua_lock(D->L);
  45.   }
  46. }
  47.  
  48.  
  49. #define dumpVar(D,x)            dumpVector(D,&x,1)
  50.  
  51.  
  52. static void dumpByte (DumpState *D, int y) {
  53.   lu_byte x = (lu_byte)y;
  54.   dumpVar(D, x);
  55. }
  56.  
  57.  
  58. /* dumpInt Buff Size */
  59. #define DIBS    ((sizeof(size_t) * 8 / 7) + 1)
  60.  
  61. static void dumpSize (DumpState *D, size_t x) {
  62.   lu_byte buff[DIBS];
  63.   int n = 0;
  64.   do {
  65.     buff[DIBS - (++n)] = x & 0x7f;  /* fill buffer in reverse order */
  66.     x >>= 7;
  67.   } while (x != 0);
  68.   buff[DIBS - 1] |= 0x80;  /* mark last byte */
  69.   dumpVector(D, buff + DIBS - n, n);
  70. }
  71.  
  72.  
  73. static void dumpInt (DumpState *D, int x) {
  74.   dumpSize(D, x);
  75. }
  76.  
  77.  
  78. static void dumpNumber (DumpState *D, lua_Number x) {
  79.   dumpVar(D, x);
  80. }
  81.  
  82.  
  83. static void dumpInteger (DumpState *D, lua_Integer x) {
  84.   dumpVar(D, x);
  85. }
  86.  
  87.  
  88. static void dumpString (DumpState *D, const TString *s) {
  89.   if (s == NULL)
  90.     dumpSize(D, 0);
  91.   else {
  92.     size_t size = tsslen(s);
  93.     const char *str = getstr(s);
  94.     dumpSize(D, size + 1);
  95.     dumpVector(D, str, size);
  96.   }
  97. }
  98.  
  99.  
  100. static void dumpCode (DumpState *D, const Proto *f) {
  101.   dumpInt(D, f->sizecode);
  102.   dumpVector(D, f->code, f->sizecode);
  103. }
  104.  
  105.  
  106. static void dumpFunction(DumpState *D, const Proto *f, TString *psource);
  107.  
  108. static void dumpConstants (DumpState *D, const Proto *f) {
  109.   int i;
  110.   int n = f->sizek;
  111.   dumpInt(D, n);
  112.   for (i = 0; i < n; i++) {
  113.     const TValue *o = &f->k[i];
  114.     int tt = ttypetag(o);
  115.     dumpByte(D, tt);
  116.     switch (tt) {
  117.       case LUA_VNUMFLT:
  118.         dumpNumber(D, fltvalue(o));
  119.         break;
  120.       case LUA_VNUMINT:
  121.         dumpInteger(D, ivalue(o));
  122.         break;
  123.       case LUA_VSHRSTR:
  124.       case LUA_VLNGSTR:
  125.         dumpString(D, tsvalue(o));
  126.         break;
  127.       default:
  128.         lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE);
  129.     }
  130.   }
  131. }
  132.  
  133.  
  134. static void dumpProtos (DumpState *D, const Proto *f) {
  135.   int i;
  136.   int n = f->sizep;
  137.   dumpInt(D, n);
  138.   for (i = 0; i < n; i++)
  139.     dumpFunction(D, f->p[i], f->source);
  140. }
  141.  
  142.  
  143. static void dumpUpvalues (DumpState *D, const Proto *f) {
  144.   int i, n = f->sizeupvalues;
  145.   dumpInt(D, n);
  146.   for (i = 0; i < n; i++) {
  147.     dumpByte(D, f->upvalues[i].instack);
  148.     dumpByte(D, f->upvalues[i].idx);
  149.     dumpByte(D, f->upvalues[i].kind);
  150.   }
  151. }
  152.  
  153.  
  154. static void dumpDebug (DumpState *D, const Proto *f) {
  155.   int i, n;
  156.   n = (D->strip) ? 0 : f->sizelineinfo;
  157.   dumpInt(D, n);
  158.   dumpVector(D, f->lineinfo, n);
  159.   n = (D->strip) ? 0 : f->sizeabslineinfo;
  160.   dumpInt(D, n);
  161.   for (i = 0; i < n; i++) {
  162.     dumpInt(D, f->abslineinfo[i].pc);
  163.     dumpInt(D, f->abslineinfo[i].line);
  164.   }
  165.   n = (D->strip) ? 0 : f->sizelocvars;
  166.   dumpInt(D, n);
  167.   for (i = 0; i < n; i++) {
  168.     dumpString(D, f->locvars[i].varname);
  169.     dumpInt(D, f->locvars[i].startpc);
  170.     dumpInt(D, f->locvars[i].endpc);
  171.   }
  172.   n = (D->strip) ? 0 : f->sizeupvalues;
  173.   dumpInt(D, n);
  174.   for (i = 0; i < n; i++)
  175.     dumpString(D, f->upvalues[i].name);
  176. }
  177.  
  178.  
  179. static void dumpFunction (DumpState *D, const Proto *f, TString *psource) {
  180.   if (D->strip || f->source == psource)
  181.     dumpString(D, NULL);  /* no debug info or same source as its parent */
  182.   else
  183.     dumpString(D, f->source);
  184.   dumpInt(D, f->linedefined);
  185.   dumpInt(D, f->lastlinedefined);
  186.   dumpByte(D, f->numparams);
  187.   dumpByte(D, f->is_vararg);
  188.   dumpByte(D, f->maxstacksize);
  189.   dumpCode(D, f);
  190.   dumpConstants(D, f);
  191.   dumpUpvalues(D, f);
  192.   dumpProtos(D, f);
  193.   dumpDebug(D, f);
  194. }
  195.  
  196.  
  197. static void dumpHeader (DumpState *D) {
  198.   dumpLiteral(D, LUA_SIGNATURE);
  199.   dumpByte(D, LUAC_VERSION);
  200.   dumpByte(D, LUAC_FORMAT);
  201.   dumpLiteral(D, LUAC_DATA);
  202.   dumpByte(D, sizeof(Instruction));
  203.   dumpByte(D, sizeof(lua_Integer));
  204.   dumpByte(D, sizeof(lua_Number));
  205.   dumpInteger(D, LUAC_INT);
  206.   dumpNumber(D, LUAC_NUM);
  207. }
  208.  
  209.  
  210. /*
  211. ** dump Lua function as precompiled chunk
  212. */
  213. int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
  214.               int strip) {
  215.   DumpState D;
  216.   D.L = L;
  217.   D.writer = w;
  218.   D.data = data;
  219.   D.strip = strip;
  220.   D.status = 0;
  221.   dumpHeader(&D);
  222.   dumpByte(&D, f->sizeupvalues);
  223.   dumpFunction(&D, f, NULL);
  224.   return D.status;
  225. }
  226.  
  227.