ldump.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. ** $Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp $
  3. ** save precompiled Lua chunks
  4. ** See Copyright Notice in lua.h
  5. */
  6. #define ldump_c
  7. #define LUA_CORE
  8. #include "lprefix.h"
  9. #include <stddef.h>
  10. #include "lua.h"
  11. #include "lobject.h"
  12. #include "lstate.h"
  13. #include "lundump.h"
  14. typedef struct
  15. {
  16. lua_State *L;
  17. lua_Writer writer;
  18. void *data;
  19. int strip;
  20. int status;
  21. } DumpState;
  22. /*
  23. ** All high-level dumps go through DumpVector; you can change it to
  24. ** change the endianness of the result
  25. */
  26. #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D)
  27. #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D)
  28. static void DumpBlock(const void *b, size_t size, DumpState *D)
  29. {
  30. if (D->status == 0 && size > 0)
  31. {
  32. lua_unlock(D->L);
  33. D->status = (*D->writer)(D->L, b, size, D->data);
  34. lua_lock(D->L);
  35. }
  36. }
  37. #define DumpVar(x,D) DumpVector(&x,1,D)
  38. static void DumpByte(int y, DumpState *D)
  39. {
  40. lu_byte x = (lu_byte)y;
  41. DumpVar(x, D);
  42. }
  43. static void DumpInt(int x, DumpState *D)
  44. {
  45. DumpVar(x, D);
  46. }
  47. static void DumpNumber(lua_Number x, DumpState *D)
  48. {
  49. DumpVar(x, D);
  50. }
  51. static void DumpInteger(lua_Integer x, DumpState *D)
  52. {
  53. DumpVar(x, D);
  54. }
  55. static void DumpString(const TString *s, DumpState *D)
  56. {
  57. if (s == NULL)
  58. DumpByte(0, D);
  59. else
  60. {
  61. size_t size = tsslen(s) + 1; /* include trailing '\0' */
  62. const char *str = getstr(s);
  63. if (size < 0xFF)
  64. DumpByte(cast_int(size), D);
  65. else
  66. {
  67. DumpByte(0xFF, D);
  68. DumpVar(size, D);
  69. }
  70. DumpVector(str, size - 1, D); /* no need to save '\0' */
  71. }
  72. }
  73. static void DumpCode(const Proto *f, DumpState *D)
  74. {
  75. DumpInt(f->sizecode, D);
  76. DumpVector(f->code, f->sizecode, D);
  77. }
  78. static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
  79. static void DumpConstants(const Proto *f, DumpState *D)
  80. {
  81. int i;
  82. int n = f->sizek;
  83. DumpInt(n, D);
  84. for (i = 0; i < n; i++)
  85. {
  86. const TValue *o = &f->k[i];
  87. DumpByte(ttype(o), D);
  88. switch (ttype(o))
  89. {
  90. case LUA_TNIL:
  91. break;
  92. case LUA_TBOOLEAN:
  93. DumpByte(bvalue(o), D);
  94. break;
  95. case LUA_TNUMFLT:
  96. DumpNumber(fltvalue(o), D);
  97. break;
  98. case LUA_TNUMINT:
  99. DumpInteger(ivalue(o), D);
  100. break;
  101. case LUA_TSHRSTR:
  102. case LUA_TLNGSTR:
  103. DumpString(tsvalue(o), D);
  104. break;
  105. default:
  106. lua_assert(0);
  107. }
  108. }
  109. }
  110. static void DumpProtos(const Proto *f, DumpState *D)
  111. {
  112. int i;
  113. int n = f->sizep;
  114. DumpInt(n, D);
  115. for (i = 0; i < n; i++)
  116. DumpFunction(f->p[i], f->source, D);
  117. }
  118. static void DumpUpvalues(const Proto *f, DumpState *D)
  119. {
  120. int i, n = f->sizeupvalues;
  121. DumpInt(n, D);
  122. for (i = 0; i < n; i++)
  123. {
  124. DumpByte(f->upvalues[i].instack, D);
  125. DumpByte(f->upvalues[i].idx, D);
  126. }
  127. }
  128. static void DumpDebug(const Proto *f, DumpState *D)
  129. {
  130. int i, n;
  131. n = (D->strip) ? 0 : f->sizelineinfo;
  132. DumpInt(n, D);
  133. DumpVector(f->lineinfo, n, D);
  134. n = (D->strip) ? 0 : f->sizelocvars;
  135. DumpInt(n, D);
  136. for (i = 0; i < n; i++)
  137. {
  138. DumpString(f->locvars[i].varname, D);
  139. DumpInt(f->locvars[i].startpc, D);
  140. DumpInt(f->locvars[i].endpc, D);
  141. }
  142. n = (D->strip) ? 0 : f->sizeupvalues;
  143. DumpInt(n, D);
  144. for (i = 0; i < n; i++)
  145. DumpString(f->upvalues[i].name, D);
  146. }
  147. static void DumpFunction(const Proto *f, TString *psource, DumpState *D)
  148. {
  149. if (D->strip || f->source == psource)
  150. DumpString(NULL, D); /* no debug info or same source as its parent */
  151. else
  152. DumpString(f->source, D);
  153. DumpInt(f->linedefined, D);
  154. DumpInt(f->lastlinedefined, D);
  155. DumpByte(f->numparams, D);
  156. DumpByte(f->is_vararg, D);
  157. DumpByte(f->maxstacksize, D);
  158. DumpCode(f, D);
  159. DumpConstants(f, D);
  160. DumpUpvalues(f, D);
  161. DumpProtos(f, D);
  162. DumpDebug(f, D);
  163. }
  164. static void DumpHeader(DumpState *D)
  165. {
  166. DumpLiteral(LUA_SIGNATURE, D);
  167. DumpByte(LUAC_VERSION, D);
  168. DumpByte(LUAC_FORMAT, D);
  169. DumpLiteral(LUAC_DATA, D);
  170. DumpByte(sizeof(int), D);
  171. DumpByte(sizeof(size_t), D);
  172. DumpByte(sizeof(Instruction), D);
  173. DumpByte(sizeof(lua_Integer), D);
  174. DumpByte(sizeof(lua_Number), D);
  175. DumpInteger(LUAC_INT, D);
  176. DumpNumber(LUAC_NUM, D);
  177. }
  178. /*
  179. ** dump Lua function as precompiled chunk
  180. */
  181. int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
  182. int strip)
  183. {
  184. DumpState D;
  185. D.L = L;
  186. D.writer = w;
  187. D.data = data;
  188. D.strip = strip;
  189. D.status = 0;
  190. DumpHeader(&D);
  191. DumpByte(f->sizeupvalues, &D);
  192. DumpFunction(f, NULL, &D);
  193. return D.status;
  194. }