/src/middleware/lua/print.c

https://bitbucket.org/vivkin/gam3b00bs/ · C · 227 lines · 216 code · 6 blank · 5 comment · 4 complexity · a866cf686914f35a76fff22587fb9f66 MD5 · raw file

  1. /*
  2. ** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $
  3. ** print bytecodes
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <ctype.h>
  7. #include <stdio.h>
  8. #define luac_c
  9. #define LUA_CORE
  10. #include "ldebug.h"
  11. #include "lobject.h"
  12. #include "lopcodes.h"
  13. #include "lundump.h"
  14. #define PrintFunction luaU_print
  15. #define Sizeof(x) ((int)sizeof(x))
  16. #define VOID(p) ((const void*)(p))
  17. static void PrintString(const TString* ts)
  18. {
  19. const char* s=getstr(ts);
  20. size_t i,n=ts->tsv.len;
  21. putchar('"');
  22. for (i=0; i<n; i++)
  23. {
  24. int c=s[i];
  25. switch (c)
  26. {
  27. case '"': printf("\\\""); break;
  28. case '\\': printf("\\\\"); break;
  29. case '\a': printf("\\a"); break;
  30. case '\b': printf("\\b"); break;
  31. case '\f': printf("\\f"); break;
  32. case '\n': printf("\\n"); break;
  33. case '\r': printf("\\r"); break;
  34. case '\t': printf("\\t"); break;
  35. case '\v': printf("\\v"); break;
  36. default: if (isprint((unsigned char)c))
  37. putchar(c);
  38. else
  39. printf("\\%03u",(unsigned char)c);
  40. }
  41. }
  42. putchar('"');
  43. }
  44. static void PrintConstant(const Proto* f, int i)
  45. {
  46. const TValue* o=&f->k[i];
  47. switch (ttype(o))
  48. {
  49. case LUA_TNIL:
  50. printf("nil");
  51. break;
  52. case LUA_TBOOLEAN:
  53. printf(bvalue(o) ? "true" : "false");
  54. break;
  55. case LUA_TNUMBER:
  56. printf(LUA_NUMBER_FMT,nvalue(o));
  57. break;
  58. case LUA_TSTRING:
  59. PrintString(rawtsvalue(o));
  60. break;
  61. default: /* cannot happen */
  62. printf("? type=%d",ttype(o));
  63. break;
  64. }
  65. }
  66. static void PrintCode(const Proto* f)
  67. {
  68. const Instruction* code=f->code;
  69. int pc,n=f->sizecode;
  70. for (pc=0; pc<n; pc++)
  71. {
  72. Instruction i=code[pc];
  73. OpCode o=GET_OPCODE(i);
  74. int a=GETARG_A(i);
  75. int b=GETARG_B(i);
  76. int c=GETARG_C(i);
  77. int bx=GETARG_Bx(i);
  78. int sbx=GETARG_sBx(i);
  79. int line=getline(f,pc);
  80. printf("\t%d\t",pc+1);
  81. if (line>0) printf("[%d]\t",line); else printf("[-]\t");
  82. printf("%-9s\t",luaP_opnames[o]);
  83. switch (getOpMode(o))
  84. {
  85. case iABC:
  86. printf("%d",a);
  87. if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
  88. if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
  89. break;
  90. case iABx:
  91. if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
  92. break;
  93. case iAsBx:
  94. if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
  95. break;
  96. }
  97. switch (o)
  98. {
  99. case OP_LOADK:
  100. printf("\t; "); PrintConstant(f,bx);
  101. break;
  102. case OP_GETUPVAL:
  103. case OP_SETUPVAL:
  104. printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
  105. break;
  106. case OP_GETGLOBAL:
  107. case OP_SETGLOBAL:
  108. printf("\t; %s",svalue(&f->k[bx]));
  109. break;
  110. case OP_GETTABLE:
  111. case OP_SELF:
  112. if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
  113. break;
  114. case OP_SETTABLE:
  115. case OP_ADD:
  116. case OP_SUB:
  117. case OP_MUL:
  118. case OP_DIV:
  119. case OP_POW:
  120. case OP_EQ:
  121. case OP_LT:
  122. case OP_LE:
  123. if (ISK(b) || ISK(c))
  124. {
  125. printf("\t; ");
  126. if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
  127. printf(" ");
  128. if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
  129. }
  130. break;
  131. case OP_JMP:
  132. case OP_FORLOOP:
  133. case OP_FORPREP:
  134. printf("\t; to %d",sbx+pc+2);
  135. break;
  136. case OP_CLOSURE:
  137. printf("\t; %p",VOID(f->p[bx]));
  138. break;
  139. case OP_SETLIST:
  140. if (c==0) printf("\t; %d",(int)code[++pc]);
  141. else printf("\t; %d",c);
  142. break;
  143. default:
  144. break;
  145. }
  146. printf("\n");
  147. }
  148. }
  149. #define SS(x) (x==1)?"":"s"
  150. #define S(x) x,SS(x)
  151. static void PrintHeader(const Proto* f)
  152. {
  153. const char* s=getstr(f->source);
  154. if (*s=='@' || *s=='=')
  155. s++;
  156. else if (*s==LUA_SIGNATURE[0])
  157. s="(bstring)";
  158. else
  159. s="(string)";
  160. printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
  161. (f->linedefined==0)?"main":"function",s,
  162. f->linedefined,f->lastlinedefined,
  163. S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
  164. printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
  165. f->numparams,f->is_vararg?"+":"",SS(f->numparams),
  166. S(f->maxstacksize),S(f->nups));
  167. printf("%d local%s, %d constant%s, %d function%s\n",
  168. S(f->sizelocvars),S(f->sizek),S(f->sizep));
  169. }
  170. static void PrintConstants(const Proto* f)
  171. {
  172. int i,n=f->sizek;
  173. printf("constants (%d) for %p:\n",n,VOID(f));
  174. for (i=0; i<n; i++)
  175. {
  176. printf("\t%d\t",i+1);
  177. PrintConstant(f,i);
  178. printf("\n");
  179. }
  180. }
  181. static void PrintLocals(const Proto* f)
  182. {
  183. int i,n=f->sizelocvars;
  184. printf("locals (%d) for %p:\n",n,VOID(f));
  185. for (i=0; i<n; i++)
  186. {
  187. printf("\t%d\t%s\t%d\t%d\n",
  188. i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
  189. }
  190. }
  191. static void PrintUpvalues(const Proto* f)
  192. {
  193. int i,n=f->sizeupvalues;
  194. printf("upvalues (%d) for %p:\n",n,VOID(f));
  195. if (f->upvalues==NULL) return;
  196. for (i=0; i<n; i++)
  197. {
  198. printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
  199. }
  200. }
  201. void PrintFunction(const Proto* f, int full)
  202. {
  203. int i,n=f->sizep;
  204. PrintHeader(f);
  205. PrintCode(f);
  206. if (full)
  207. {
  208. PrintConstants(f);
  209. PrintLocals(f);
  210. PrintUpvalues(f);
  211. }
  212. for (i=0; i<n; i++) PrintFunction(f->p[i],full);
  213. }