diff options
| author | Lua Team <team@lua.org> | 1997-07-01 12:00:00 +0000 |
|---|---|---|
| committer | repogen <> | 1997-07-01 12:00:00 +0000 |
| commit | 4f8c5d0f284e1f4da717aea5008915f185cd2e05 (patch) | |
| tree | 5671acf8a2cacf0c0524ce96d22959590a3aa5af /src/luac | |
| parent | 47a298a24ad3a8202440051de5938618502302a0 (diff) | |
| download | lua-github-3.0.tar.gz | |
Lua 3.03.0
Diffstat (limited to 'src/luac')
| -rw-r--r-- | src/luac/dump.c | 30 | ||||
| -rw-r--r-- | src/luac/luac.c | 139 | ||||
| -rw-r--r-- | src/luac/luac.h | 11 | ||||
| -rw-r--r-- | src/luac/print.c | 233 | ||||
| -rw-r--r-- | src/luac/print.h | 9 |
5 files changed, 348 insertions, 74 deletions
diff --git a/src/luac/dump.c b/src/luac/dump.c index 656cc293..73839f38 100644 --- a/src/luac/dump.c +++ b/src/luac/dump.c @@ -3,15 +3,13 @@ ** thread and save bytecodes to file */ -char* rcs_dump="$Id: dump.c,v 1.17 1996/11/18 11:18:29 lhf Exp $"; +char* rcs_dump="$Id: dump.c,v 1.20 1997/06/19 14:56:04 lhf Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> #include "luac.h" -static TFunc* lastF=NULL; /* list of functions seen in code */ - static int SawVar(int i, int at) { int old=VarLoc(i); @@ -34,7 +32,7 @@ static void ThreadCode(Byte* code, Byte* end) for (i=0; i<lua_nconstant; i++) StrLoc(i)=0; for (p=code; p!=end;) { - OpCode op=(OpCode)*p; + int op=*p; int at=p-code+1; switch (op) { @@ -89,6 +87,8 @@ static void ThreadCode(Byte* code, Byte* end) case STORELIST0: case ADJUST: case RETCODE: + case VARARGS: + case STOREMAP: p+=2; break; case PUSHWORD: @@ -107,8 +107,11 @@ static void ThreadCode(Byte* code, Byte* end) case PUSHFLOAT: p+=5; /* assumes sizeof(float)==4 */ break; - case PUSHSELF: + case PUSHFUNCTION: + p+=sizeof(TFunc*)+1; + break; case PUSHSTRING: + case PUSHSELF: { Word w; p++; @@ -117,16 +120,6 @@ static void ThreadCode(Byte* code, Byte* end) memcpy(p-2,&w,sizeof(w)); break; } - case PUSHFUNCTION: - { - TFunc* tf; - p++; - get_code(tf,p); - tf->marked=at; - tf->next=NULL; /* TODO: remove? */ - lastF=lastF->next=tf; - break; - } case PUSHGLOBAL: case STOREGLOBAL: { @@ -151,8 +144,8 @@ static void ThreadCode(Byte* code, Byte* end) } break; } - default: - fprintf(stderr,"luac: cannot happen: opcode=%d",*p); + default: /* cannot happen */ + fprintf(stderr,"luac: bad opcode %d at %d\n",*p,(int)(p-code)); exit(1); break; } @@ -186,7 +179,7 @@ static void DumpString(char* s, FILE* D) int n=strlen(s)+1; if ((Word)n != n) { - fprintf(stderr,"luac: string too long: \"%.32s...\"\n",s); + fprintf(stderr,"luac: string too long (%d bytes): \"%.32s...\"\n",n,s); exit(1); } DumpWord(n,D); @@ -220,7 +213,6 @@ static void DumpStrings(FILE* D) void DumpFunction(TFunc* tf, FILE* D) { - lastF=tf; ThreadCode(tf->code,tf->code+tf->size); fputc(ID_FUN,D); DumpSize(tf->size,D); diff --git a/src/luac/luac.c b/src/luac/luac.c index 7546c1bb..713da1fb 100644 --- a/src/luac/luac.c +++ b/src/luac/luac.c @@ -1,25 +1,39 @@ /* ** luac.c -** lua compiler (saves bytecodes to files) +** lua compiler (saves bytecodes to files; also list binary files) */ -char* rcs_luac="$Id: luac.c,v 1.18 1996/11/16 20:14:23 lhf Exp $"; +char* rcs_luac="$Id: luac.c,v 1.23 1997/06/20 20:34:04 lhf Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> #include "luac.h" +#include "lex.h" +#include "zio.h" static void compile(char* filename); +static void undump(char* filename); static int listing=0; /* list bytecodes? */ static int dumping=1; /* dump bytecodes? */ +static int undumping=0; /* undump bytecodes? */ static FILE* D; /* output file */ static void usage(void) { - fprintf(stderr,"usage: luac [-dlpv] [-o output] file ...\n"); - exit(0); + fprintf(stderr, + "usage: luac [-c | -u] [-d] [-l] [-p] [-q] [-v] [-o output] file ...\n" + " -c\tcompile (default)\n" + " -u\tundump\n" + " -d\tgenerate debugging information\n" + " -l\tlist (default for -u)\n" + " -o\toutput file for -c (default \"luac.out\")\n" + " -p\tparse only\n" + " -q\tquiet (default for -c)\n" + " -v\tshow version information\n" + ); + exit(1); } #define IS(s) (strcmp(argv[i],s)==0) @@ -34,6 +48,11 @@ int main(int argc, char* argv[]) break; else if (IS("-")) /* use stdin */ break; + else if (IS("-c")) /* compile (and dump) */ + { + dumping=1; + undumping=0; + } else if (IS("-d")) /* debug */ lua_debug=1; else if (IS("-l")) /* list */ @@ -42,6 +61,14 @@ int main(int argc, char* argv[]) d=argv[++i]; else if (IS("-p")) /* parse only (for timing purposes) */ dumping=0; + else if (IS("-q")) /* quiet */ + listing=0; + else if (IS("-u")) /* undump */ + { + dumping=0; + undumping=1; + listing=1; + } else if (IS("-v")) /* show version */ printf("%s %s\n(written by %s)\n\n",LUA_VERSION,LUA_COPYRIGHT,LUA_AUTHORS); else /* unknown option */ @@ -50,56 +77,114 @@ int main(int argc, char* argv[]) --i; /* fake new argv[0] */ argc-=i; argv+=i; - if (argc<2) usage(); - for (i=1; i<argc; i++) - if (IS(d)) + if (dumping) + { + if (argc<2) usage(); + for (i=1; i<argc; i++) /* play safe with output file */ + if (IS(d)) + { + fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d); + exit(1); + } + D=fopen(d,"wb"); /* must open in binary mode */ + if (D==NULL) { - fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d); + fprintf(stderr,"luac: cannot open "); + perror(d); exit(1); } - D=(dumping) ? fopen(d,"wb") : stdout; /* must open in binary mode */ - if (D==NULL) + for (i=1; i<argc; i++) compile(IS("-")? NULL : argv[i]); + fclose(D); + } + if (undumping) { - fprintf(stderr,"luac: cannot open "); - perror(d); - exit(1); + if (argc<2) + undump("luac.out"); + else + for (i=1; i<argc; i++) undump(IS("-")? NULL : argv[i]); } - for (i=1; i<argc; i++) compile(IS("-")? NULL : argv[i]); - fclose(D); return 0; } -static void do_dump(TFunc* tf) /* only for tf==main */ +static void do_dump(TFunc* Main) { - if (dumping) DumpHeader(D); - while (tf!=NULL) + TFunc* tf; + LinkFunctions(Main); + if (listing) + { + for (tf=Main; tf!=NULL; tf=tf->next) PrintFunction(tf,Main); + } + if (dumping) { - TFunc* nf; - if (listing) PrintFunction(tf); - if (dumping) DumpFunction(tf,D); - nf=tf->next; /* list only built after first main */ + DumpHeader(D); + for (tf=Main; tf!=NULL; tf=tf->next) DumpFunction(tf,D); + } + for (tf=Main; tf!=NULL; ) + { + TFunc* nf=tf->next; luaI_freefunc(tf); tf=nf; } } -static void do_compile(void) +static void do_compile(ZIO* z) { TFunc* tf=new(TFunc); + lua_setinput(z); luaI_initTFunc(tf); - tf->fileName = lua_parsedfile; + tf->fileName=lua_parsedfile; lua_parse(tf); do_dump(tf); } static void compile(char* filename) { - if (lua_openfile(filename)==NULL) + FILE* f= (filename==NULL) ? stdin : fopen(filename, "r"); + if (f==NULL) + { + fprintf(stderr,"luac: cannot open "); + perror(filename); + exit(1); + } + else + { + ZIO z; + zFopen(&z,f); + luaI_setparsedfile(filename?filename:"(stdin)"); + do_compile(&z); + fclose(f); + } +} + +static void do_undump(ZIO* z) +{ + TFunc* Main; + while ((Main=luaI_undump1(z))) + { + if (listing) + { + TFunc* tf; + for (tf=Main; tf!=NULL; tf=tf->next) + PrintFunction(tf,Main); + } + luaI_freefunc(Main); /* TODO: free others */ + } +} + +static void undump(char* filename) +{ + FILE* f= (filename==NULL) ? stdin : fopen(filename, "rb"); + if (f==NULL) { fprintf(stderr,"luac: cannot open "); perror(filename); exit(1); } - do_compile(); - lua_closefile(); + else + { + ZIO z; + zFopen(&z,f); + do_undump(&z); + fclose(f); + } } diff --git a/src/luac/luac.h b/src/luac/luac.h index ceb311b8..815824ca 100644 --- a/src/luac/luac.h +++ b/src/luac/luac.h @@ -1,24 +1,25 @@ /* ** luac.h ** definitions for luac compiler -** $Id: luac.h,v 1.5 1996/03/08 21:41:47 lhf Exp $ +** $Id: luac.h,v 1.8 1997/06/19 17:32:08 lhf Exp $ */ #include "inout.h" -#include "mem.h" +#include "luamem.h" #include "opcode.h" #include "table.h" #include "undump.h" #define VarStr(i) (lua_table[i].varname->str) -#define VarLoc(i) (lua_table[i].varname->varindex) +#define VarLoc(i) (lua_table[i].varname->u.s.varindex) #define StrStr(i) (lua_constant[i]->str) -#define StrLoc(i) (lua_constant[i]->constindex) +#define StrLoc(i) (lua_constant[i]->u.s.constindex) extern Word lua_ntable; extern Word lua_nconstant; extern int lua_debug; +void LinkFunctions(TFunc* tf); +void PrintFunction(TFunc* tf, TFunc* Main); void DumpHeader(FILE* D); void DumpFunction(TFunc* tf, FILE* D); -void PrintFunction(TFunc* tf); diff --git a/src/luac/print.c b/src/luac/print.c index 0e1d2569..fb7bf8a7 100644 --- a/src/luac/print.c +++ b/src/luac/print.c @@ -3,7 +3,7 @@ ** print bytecodes */ -char* rcs_print="$Id: print.c,v 1.11 1996/11/18 11:24:16 lhf Exp $"; +char* rcs_print="$Id: print.c,v 1.17 1997/06/25 17:07:28 lhf Exp $"; #include <stdio.h> #include <stdlib.h> @@ -11,20 +11,134 @@ char* rcs_print="$Id: print.c,v 1.11 1996/11/18 11:24:16 lhf Exp $"; #include "luac.h" #include "print.h" -static LocVar* V=NULL; - -static char* LocStr(int i) +void LinkFunctions(TFunc* m) { - if (V==NULL) return ""; else return V[i].varname->str; + static TFunc* lastF; /* list of functions seen in code */ + Byte* code=m->code; + Byte* end=code+m->size; + Byte* p; + if (IsMain(m)) lastF=m; + for (p=code; p!=end;) + { + int op=*p; + int at=p-code+1; + switch (op) + { + case PUSHNIL: + case PUSH0: + case PUSH1: + case PUSH2: + case PUSHLOCAL0: + case PUSHLOCAL1: + case PUSHLOCAL2: + case PUSHLOCAL3: + case PUSHLOCAL4: + case PUSHLOCAL5: + case PUSHLOCAL6: + case PUSHLOCAL7: + case PUSHLOCAL8: + case PUSHLOCAL9: + case PUSHINDEXED: + case STORELOCAL0: + case STORELOCAL1: + case STORELOCAL2: + case STORELOCAL3: + case STORELOCAL4: + case STORELOCAL5: + case STORELOCAL6: + case STORELOCAL7: + case STORELOCAL8: + case STORELOCAL9: + case STOREINDEXED0: + case ADJUST0: + case EQOP: + case LTOP: + case LEOP: + case GTOP: + case GEOP: + case ADDOP: + case SUBOP: + case MULTOP: + case DIVOP: + case POWOP: + case CONCOP: + case MINUSOP: + case NOTOP: + case POP: + case RETCODE0: + p++; + break; + case PUSHBYTE: + case PUSHLOCAL: + case STORELOCAL: + case STOREINDEXED: + case STORELIST0: + case ADJUST: + case RETCODE: + case VARARGS: + case STOREMAP: + p+=2; + break; + case PUSHWORD: + case PUSHSTRING: + case PUSHGLOBAL: + case PUSHSELF: + case STOREGLOBAL: + case CREATEARRAY: + case ONTJMP: + case ONFJMP: + case JMP: + case UPJMP: + case IFFJMP: + case IFFUPJMP: + case CALLFUNC: + case SETLINE: + case STORELIST: + p+=3; + break; + case PUSHFLOAT: + p+=5; /* assumes sizeof(float)==4 */ + break; + case PUSHFUNCTION: + { + TFunc* tf; + p++; + get_code(tf,p); + tf->marked=at; + tf->next=NULL; /* TODO: remove? */ + lastF=lastF->next=tf; + break; + } + case STORERECORD: + { + int n=*++p; + p+=2*n+1; + break; + } + default: /* cannot happen */ + fprintf(stderr,"luac: bad opcode %d at %d\n",*p,(int)(p-code)); + exit(1); + break; + } + } } -static void PrintCode(Byte* code, Byte* end) +#define LocStr(i) luaI_getlocalname(tf,i+1,line) + +static void PrintCode(TFunc* tf) { + Byte* code=tf->code; + Byte* end=code+tf->size; Byte* p; + int line=0; for (p=code; p!=end;) { - OpCode op=(OpCode)*p; - if (op>SETLINE) op=SETLINE+1; + int op=*p; + if (op>=NOPCODES) + { + fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code)); + exit(1); + } printf("%6d\t%s",(int)(p-code),OpCodeName[op]); switch (op) { @@ -64,7 +178,7 @@ static void PrintCode(Byte* code, Byte* end) case PUSHLOCAL9: { int i=op-PUSHLOCAL0; - printf("\t%d\t; %s",i,LocStr(i)); + if (tf->locvars) printf("\t\t; %s",LocStr(i)); p++; break; } @@ -80,7 +194,7 @@ static void PrintCode(Byte* code, Byte* end) case STORELOCAL9: { int i=op-STORELOCAL0; - printf("\t%d\t; %s",i,LocStr(i)); + if (tf->locvars) printf("\t\t; %s",LocStr(i)); p++; break; } @@ -88,7 +202,7 @@ static void PrintCode(Byte* code, Byte* end) case STORELOCAL: { int i=*(p+1); - printf("\t%d\t; %s",i,LocStr(i)); + if (tf->locvars) printf("\t%d\t; %s",i,LocStr(i)); p+=2; break; } @@ -97,23 +211,40 @@ static void PrintCode(Byte* code, Byte* end) case STORELIST0: case ADJUST: case RETCODE: + case VARARGS: + case STOREMAP: printf("\t%d",*(p+1)); p+=2; break; case PUSHWORD: case CREATEARRAY: + case SETLINE: + { + Word w; + p++; + get_word(w,p); + printf("\t%d",w); + if (op==SETLINE) line=w; + break; + } case ONTJMP: case ONFJMP: case JMP: - case UPJMP: case IFFJMP: + { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */ + Word w; + p++; + get_word(w,p); + printf("\t%d\t\t; to %d",w,(int)(p-code)+w); + break; + } + case UPJMP: case IFFUPJMP: - case SETLINE: - { + { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */ Word w; p++; get_word(w,p); - printf("\t%d",w); + printf("\t%d\t\t; to %d",w,(int)(p-code)-w); break; } case PUSHFLOAT: @@ -170,7 +301,8 @@ static void PrintCode(Byte* code, Byte* end) break; } default: - printf("\tcannot happen: opcode=%d",*p); + printf("\tcannot happen: opcode=%d\n",*p); + fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code)); exit(1); break; } @@ -178,13 +310,74 @@ static void PrintCode(Byte* code, Byte* end) } } -void PrintFunction(TFunc* tf) +#undef LocStr + +static void PrintLocals(LocVar* v, int n) { + int i=0; + if (v==NULL || v->varname==NULL) return; + if (n>0) + { + printf("parameters:"); + for (i=0; i<n; v++,i++) printf(" %s[%d@%d]",v->varname->str,i,v->line); + printf("\n"); + } + if (v->varname!=NULL) + { + printf("locals:"); + for (; v->line>=0; v++) + { + if (v->varname==NULL) +#if 0 + printf(" %s[%d@%d]","*",--i,v->line); +#else + --i; +#endif + else + printf(" %s[%d@%d]",v->varname->str,i++,v->line); + } + printf("\n"); + } +} + +void PrintFunction(TFunc* tf, TFunc* Main) +{ + int n=0; if (IsMain(tf)) printf("\nmain of \"%s\" (%d bytes at %p)\n",tf->fileName,tf->size,tf); else - printf("\nfunction \"%s\":%d (%d bytes at %p); used at main+%d\n", + { + Byte* p; + p=tf->code; /* get number of parameters */ + while (*p==SETLINE) p+=3; + if (*p==ADJUST) n=p[1]; + p=Main->code+tf->marked+sizeof(TFunc*); + printf("\nfunction "); + switch (*p) /* try to get name */ + { + case STOREGLOBAL: + { + Word w; + p++; get_word(w,p); printf("%s defined at ",VarStr(w)); + break; + } + case STOREINDEXED0: /* try method definition */ + { + if (p[-11]==PUSHGLOBAL && p[-8]==PUSHSTRING) + { + Word w; + Byte* op=p; + int c=(tf->locvars && n>0 && strcmp(tf->locvars->varname->str,"self")==0) + ? ':' : '.'; + p=op-11; p++; get_word(w,p); printf("%s%c",VarStr(w),c); + p=op-8; p++; get_word(w,p); printf("%s defined at ",StrStr(w)); + } + break; + } + } + printf("\"%s\":%d (%d bytes at %p); used at main+%d\n", tf->fileName,tf->lineDefined,tf->size,tf,tf->marked); - V=tf->locvars; - PrintCode(tf->code,tf->code+tf->size); + } + PrintLocals(tf->locvars,n); + PrintCode(tf); } diff --git a/src/luac/print.h b/src/luac/print.h index 31e2bb89..00e344ca 100644 --- a/src/luac/print.h +++ b/src/luac/print.h @@ -1,10 +1,10 @@ /* ** print.h ** opcode names -** $Id: print.h,v 1.1 1996/02/23 19:04:13 lhf Exp $ +** $Id: print.h,v 1.3 1997/04/14 14:42:50 lhf Exp $ */ -static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */ +static char* OpCodeName[]={ /* ATTENTION: same order as enum in opcode.h */ "PUSHNIL", "PUSH0", "PUSH1", @@ -72,5 +72,8 @@ static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */ "RETCODE0", "RETCODE", "SETLINE", - "" + "VARARGS", + "STOREMAP" }; + +#define NOPCODES (sizeof(OpCodeName)/sizeof(OpCodeName[0])) |
