00001
00002
00003
00004
00005
00006
00007 #include <ctype.h>
00008 #include <stdio.h>
00009
00010 #define luac_c
00011 #define LUA_CORE
00012
00013 #include "ldebug.h"
00014 #include "lobject.h"
00015 #include "lopcodes.h"
00016 #include "lundump.h"
00017
00018 #define PrintFunction luaU_print
00019
00020 #define Sizeof(x) ((int)sizeof(x))
00021 #define VOID(p) ((const void*)(p))
00022
00023 static void PrintString(const TString* ts)
00024 {
00025 const char* s=getstr(ts);
00026 size_t i,n=ts->tsv.len;
00027 putchar('"');
00028 for (i=0; i<n; i++)
00029 {
00030 int c=s[i];
00031 switch (c)
00032 {
00033 case '"': printf("\\\""); break;
00034 case '\\': printf("\\\\"); break;
00035 case '\a': printf("\\a"); break;
00036 case '\b': printf("\\b"); break;
00037 case '\f': printf("\\f"); break;
00038 case '\n': printf("\\n"); break;
00039 case '\r': printf("\\r"); break;
00040 case '\t': printf("\\t"); break;
00041 case '\v': printf("\\v"); break;
00042 default: if (isprint((unsigned char)c))
00043 putchar(c);
00044 else
00045 printf("\\%03u",(unsigned char)c);
00046 }
00047 }
00048 putchar('"');
00049 }
00050
00051 static void PrintConstant(const Proto* f, int i)
00052 {
00053 const TValue* o=&f->k[i];
00054 switch (ttype(o))
00055 {
00056 case LUA_TNIL:
00057 printf("nil");
00058 break;
00059 case LUA_TBOOLEAN:
00060 printf(bvalue(o) ? "true" : "false");
00061 break;
00062 case LUA_TNUMBER:
00063 printf(LUA_NUMBER_FMT,nvalue(o));
00064 break;
00065 case LUA_TSTRING:
00066 PrintString(rawtsvalue(o));
00067 break;
00068 default:
00069 printf("? type=%d",ttype(o));
00070 break;
00071 }
00072 }
00073
00074 static void PrintCode(const Proto* f)
00075 {
00076 const Instruction* code=f->code;
00077 int pc,n=f->sizecode;
00078 for (pc=0; pc<n; pc++)
00079 {
00080 Instruction i=code[pc];
00081 OpCode o=GET_OPCODE(i);
00082 int a=GETARG_A(i);
00083 int b=GETARG_B(i);
00084 int c=GETARG_C(i);
00085 int bx=GETARG_Bx(i);
00086 int sbx=GETARG_sBx(i);
00087 int line=getline(f,pc);
00088 printf("\t%d\t",pc+1);
00089 if (line>0) printf("[%d]\t",line); else printf("[-]\t");
00090 printf("%-9s\t",luaP_opnames[o]);
00091 switch (getOpMode(o))
00092 {
00093 case iABC:
00094 printf("%d",a);
00095 if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
00096 if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
00097 break;
00098 case iABx:
00099 if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
00100 break;
00101 case iAsBx:
00102 if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
00103 break;
00104 }
00105 switch (o)
00106 {
00107 case OP_LOADK:
00108 printf("\t; "); PrintConstant(f,bx);
00109 break;
00110 case OP_GETUPVAL:
00111 case OP_SETUPVAL:
00112 printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
00113 break;
00114 case OP_GETGLOBAL:
00115 case OP_SETGLOBAL:
00116 printf("\t; %s",svalue(&f->k[bx]));
00117 break;
00118 case OP_GETTABLE:
00119 case OP_SELF:
00120 if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
00121 break;
00122 case OP_SETTABLE:
00123 case OP_ADD:
00124 case OP_SUB:
00125 case OP_MUL:
00126 case OP_DIV:
00127 case OP_POW:
00128 case OP_EQ:
00129 case OP_LT:
00130 case OP_LE:
00131 if (ISK(b) || ISK(c))
00132 {
00133 printf("\t; ");
00134 if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
00135 printf(" ");
00136 if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
00137 }
00138 break;
00139 case OP_JMP:
00140 case OP_FORLOOP:
00141 case OP_FORPREP:
00142 printf("\t; to %d",sbx+pc+2);
00143 break;
00144 case OP_CLOSURE:
00145 printf("\t; %p",VOID(f->p[bx]));
00146 break;
00147 case OP_SETLIST:
00148 if (c==0) printf("\t; %d",(int)code[++pc]);
00149 else printf("\t; %d",c);
00150 break;
00151 default:
00152 break;
00153 }
00154 printf("\n");
00155 }
00156 }
00157
00158 #define SS(x) (x==1)?"":"s"
00159 #define S(x) x,SS(x)
00160
00161 static void PrintHeader(const Proto* f)
00162 {
00163 const char* s=getstr(f->source);
00164 if (*s=='@' || *s=='=')
00165 s++;
00166 else if (*s==LUA_SIGNATURE[0])
00167 s="(bstring)";
00168 else
00169 s="(string)";
00170 printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
00171 (f->linedefined==0)?"main":"function",s,
00172 f->linedefined,f->lastlinedefined,
00173 S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
00174 printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
00175 f->numparams,f->is_vararg?"+":"",SS(f->numparams),
00176 S(f->maxstacksize),S(f->nups));
00177 printf("%d local%s, %d constant%s, %d function%s\n",
00178 S(f->sizelocvars),S(f->sizek),S(f->sizep));
00179 }
00180
00181 static void PrintConstants(const Proto* f)
00182 {
00183 int i,n=f->sizek;
00184 printf("constants (%d) for %p:\n",n,VOID(f));
00185 for (i=0; i<n; i++)
00186 {
00187 printf("\t%d\t",i+1);
00188 PrintConstant(f,i);
00189 printf("\n");
00190 }
00191 }
00192
00193 static void PrintLocals(const Proto* f)
00194 {
00195 int i,n=f->sizelocvars;
00196 printf("locals (%d) for %p:\n",n,VOID(f));
00197 for (i=0; i<n; i++)
00198 {
00199 printf("\t%d\t%s\t%d\t%d\n",
00200 i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
00201 }
00202 }
00203
00204 static void PrintUpvalues(const Proto* f)
00205 {
00206 int i,n=f->sizeupvalues;
00207 printf("upvalues (%d) for %p:\n",n,VOID(f));
00208 if (f->upvalues==NULL) return;
00209 for (i=0; i<n; i++)
00210 {
00211 printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
00212 }
00213 }
00214
00215 void PrintFunction(const Proto* f, int full)
00216 {
00217 int i,n=f->sizep;
00218 PrintHeader(f);
00219 PrintCode(f);
00220 if (full)
00221 {
00222 PrintConstants(f);
00223 PrintLocals(f);
00224 PrintUpvalues(f);
00225 }
00226 for (i=0; i<n; i++) PrintFunction(f->p[i],full);
00227 }