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