00001 /* 00002 ** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ 00003 ** print bytecodes 00004 ** See Copyright Notice in lua.h 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: /* cannot happen */ 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 }
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1