diff options
Diffstat (limited to 'src/luac')
-rw-r--r-- | src/luac/Makefile | 24 | ||||
-rw-r--r-- | src/luac/dump.c | 247 | ||||
-rw-r--r-- | src/luac/luac.c | 104 | ||||
-rw-r--r-- | src/luac/luac.h | 24 | ||||
-rw-r--r-- | src/luac/print.c | 189 | ||||
-rw-r--r-- | src/luac/print.h | 76 |
6 files changed, 664 insertions, 0 deletions
diff --git a/src/luac/Makefile b/src/luac/Makefile new file mode 100644 index 00000000..813393e4 --- /dev/null +++ b/src/luac/Makefile @@ -0,0 +1,24 @@ +# makefile for lua distribution (compiler) + +LUA= ../.. + +include $(LUA)/config + +INCS= -I$(INC) $(EXTRA_INCS) -I.. +OBJS= dump.o luac.o print.o +SRCS= dump.c luac.c print.c luac.h print.h +T=$(BIN)/luac + +all: $T + +$T: $(OBJS) + $(CC) -o $@ $(OBJS) -L$(LIB) -llua + +clean: + rm -f $(OBJS) $T + +co: + co -f -M $(SRCS) + +klean: clean + rm -f $(SRCS) diff --git a/src/luac/dump.c b/src/luac/dump.c new file mode 100644 index 00000000..22db5e36 --- /dev/null +++ b/src/luac/dump.c @@ -0,0 +1,247 @@ +/* +** dump.c +** thread and save bytecodes to file +*/ + +char* rcs_dump="$Id: dump.c,v 1.12 1996/03/12 20:00:03 lhf Exp $"; + +#include <stdio.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); + VarLoc(i)=at; + return old; +} + +static int SawStr(int i, int at) +{ + int old=StrLoc(i); + StrLoc(i)=at; + return old; +} + +static void ThreadCode(Byte* code, Byte* end) +{ + Byte* p; + int i; + for (i=0; i<lua_ntable; i++) VarLoc(i)=0; + for (i=0; i<lua_nconstant; i++) StrLoc(i)=0; + for (p=code; p!=end;) + { + OpCode op=(OpCode)*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: + p+=2; + break; + case PUSHWORD: + case CREATEARRAY: + case ONTJMP: + case ONFJMP: + case JMP: + case UPJMP: + case IFFJMP: + case IFFUPJMP: + case SETLINE: + case STORELIST: + case CALLFUNC: + p+=3; + break; + case PUSHFLOAT: + p+=5; + break; + case PUSHSELF: + case PUSHSTRING: + { + CodeWord c; + p++; + get_word(c,p); + c.w=SawStr(c.w,at); + p[-2]=c.m.c1; + p[-1]=c.m.c2; + break; + } + case PUSHFUNCTION: + { + CodeCode c; + p++; + get_code(c,p); + c.tf->marked=at; + c.tf->next=NULL; /* TODO: remove? */ + lastF=lastF->next=c.tf; + break; + } + case PUSHGLOBAL: + case STOREGLOBAL: + { + CodeWord c; + p++; + get_word(c,p); + c.w=SawVar(c.w,at); + p[-2]=c.m.c1; + p[-1]=c.m.c2; + break; + } + case STORERECORD: + { + int n=*++p; + p++; + while (n--) + { + CodeWord c; + at=p-code; + get_word(c,p); + c.w=SawStr(c.w,at); + p[-2]=c.m.c1; + p[-1]=c.m.c2; + } + break; + } + default: + fprintf(stderr,"luac: cannot happen: opcode=%d",*p); + exit(1); + break; + } + } +} + +static void DumpWord(int i, FILE* D) +{ + Word w=i; + fwrite(&w,sizeof(w),1,D); +} + +static void DumpBlock(char* b, int size, FILE* D) +{ + fwrite(b,size,1,D); +} + +static void DumpSize(int i, FILE* D) +{ + Word lo=i&0x0FFFF; + Word hi=(i>>16)&0x0FFFF; + fwrite(&hi,sizeof(hi),1,D); + fwrite(&lo,sizeof(lo),1,D); + if (hi!=0) + fprintf(stderr, + "luac: warning: code too long for 16-bit machines (%d bytes)\n",i); +} + +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); + exit(1); + } + DumpWord(n,D); + DumpBlock(s,n,D); +} + +static void DumpStrings(FILE* D) +{ + int i; + for (i=0; i<lua_ntable; i++) + { + if (VarLoc(i)!=0) + { + fputc(ID_VAR,D); + DumpWord(VarLoc(i),D); + DumpString(VarStr(i),D); + } + VarLoc(i)=i; + } + for (i=0; i<lua_nconstant; i++) + { + if (StrLoc(i)!=0) + { + fputc(ID_STR,D); + DumpWord(StrLoc(i),D); + DumpString(StrStr(i),D); + } + StrLoc(i)=i; + } +} + +void DumpFunction(TFunc* tf, FILE* D) +{ + lastF=tf; + ThreadCode(tf->code,tf->code+tf->size); + fputc(ID_FUN,D); + DumpSize(tf->size,D); + DumpWord(tf->lineDefined,D); + if (IsMain(tf)) + DumpString(tf->fileName,D); + else + DumpWord(tf->marked,D); + DumpBlock(tf->code,tf->size,D); + DumpStrings(D); +} + +void DumpHeader(FILE* D) +{ + Word w=TEST_WORD; + float f=TEST_FLOAT; + fputc(ID_CHUNK,D); + fputs(SIGNATURE,D); + fputc(VERSION,D); + fwrite(&w,sizeof(w),1,D); + fwrite(&f,sizeof(f),1,D); +} diff --git a/src/luac/luac.c b/src/luac/luac.c new file mode 100644 index 00000000..aa71afcf --- /dev/null +++ b/src/luac/luac.c @@ -0,0 +1,104 @@ +/* +** luac.c +** lua compiler (saves bytecodes to files) +*/ + +char* rcs_luac="$Id: luac.c,v 1.16 1996/03/13 17:33:03 lhf Exp $"; + +#include <stdio.h> +#include <string.h> +#include "luac.h" + +static void compile(char* filename); + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static FILE* D; /* output file */ + +static void usage(void) +{ + fprintf(stderr,"usage: luac [-dlpv] [-o output] file ...\n"); + exit(0); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +int main(int argc, char* argv[]) +{ + char* d="luac.out"; /* default output file */ + int i; + for (i=1; i<argc; i++) + { + if (argv[i][0]!='-') /* end of options */ + break; + else if (IS("-")) /* use stdin */ + break; + else if (IS("-d")) /* debug */ + lua_debug=1; + else if (IS("-l")) /* list */ + listing=1; + else if (IS("-o")) /* output file */ + d=argv[++i]; + else if (IS("-p")) /* parse only (for timing purposes) */ + dumping=0; + else if (IS("-v")) /* show version */ + printf("%s %s\n(written by %s)\n\n",LUA_VERSION,LUA_COPYRIGHT,LUA_AUTHORS); + else /* unknown option */ + usage(); + } + --i; /* fake new argv[0] */ + argc-=i; + argv+=i; + if (argc<2) usage(); + for (i=1; i<argc; i++) + if (IS(d)) + { + fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d); + exit(1); + } + D=(dumping) ? fopen(d,"wb") : stdout; /* must open in binary mode */ + if (D==NULL) + { + fprintf(stderr,"luac: cannot open "); + perror(d); + exit(1); + } + 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 */ +{ + if (dumping) DumpHeader(D); + while (tf!=NULL) + { + TFunc* nf; + if (listing) PrintFunction(tf); + if (dumping) DumpFunction(tf,D); + nf=tf->next; /* list only built after first main */ + luaI_freefunc(tf); + tf=nf; + } +} + +static void do_compile(void) +{ + TFunc* tf=new(TFunc); + luaI_initTFunc(tf); + tf->fileName = lua_parsedfile; + lua_parse(tf); + do_dump(tf); +} + +static void compile(char* filename) +{ + if (lua_openfile(filename)==NULL) + { + fprintf(stderr,"luac: cannot open "); + perror(filename); + exit(1); + } + do_compile(); + lua_closefile(); +} diff --git a/src/luac/luac.h b/src/luac/luac.h new file mode 100644 index 00000000..ceb311b8 --- /dev/null +++ b/src/luac/luac.h @@ -0,0 +1,24 @@ +/* +** luac.h +** definitions for luac compiler +** $Id: luac.h,v 1.5 1996/03/08 21:41:47 lhf Exp $ +*/ + +#include "inout.h" +#include "mem.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 StrStr(i) (lua_constant[i]->str) +#define StrLoc(i) (lua_constant[i]->constindex) + +extern Word lua_ntable; +extern Word lua_nconstant; +extern int lua_debug; + +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 new file mode 100644 index 00000000..1b338931 --- /dev/null +++ b/src/luac/print.c @@ -0,0 +1,189 @@ +/* +** print.c +** print bytecodes +*/ + +char* rcs_print="$Id: print.c,v 1.6 1996/03/12 20:00:24 lhf Exp $"; + +#include <stdio.h> +#include <string.h> +#include "luac.h" +#include "print.h" + +static LocVar* V=NULL; + +static char* LocStr(int i) +{ + if (V==NULL) return ""; else return V[i].varname->str; +} + +static void PrintCode(Byte* code, Byte* end) +{ + Byte* p; + for (p=code; p!=end;) + { + OpCode op=(OpCode)*p; + if (op>SETLINE) op=SETLINE+1; + printf("%6d\t%s",p-code,OpCodeName[op]); + switch (op) + { + case PUSHNIL: + case PUSH0: + case PUSH1: + case PUSH2: + case PUSHINDEXED: + 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 PUSHLOCAL0: + case PUSHLOCAL1: + case PUSHLOCAL2: + case PUSHLOCAL3: + case PUSHLOCAL4: + case PUSHLOCAL5: + case PUSHLOCAL6: + case PUSHLOCAL7: + case PUSHLOCAL8: + case PUSHLOCAL9: + { + int i=op-PUSHLOCAL0; + printf("\t%d\t; %s",i,LocStr(i)); + p++; + break; + } + case STORELOCAL0: + case STORELOCAL1: + case STORELOCAL2: + case STORELOCAL3: + case STORELOCAL4: + case STORELOCAL5: + case STORELOCAL6: + case STORELOCAL7: + case STORELOCAL8: + case STORELOCAL9: + { + int i=op-STORELOCAL0; + printf("\t%d\t; %s",i,LocStr(i)); + p++; + break; + } + case PUSHLOCAL: + case STORELOCAL: + { + int i=*(p+1); + printf("\t%d\t; %s",i,LocStr(i)); + p+=2; + break; + } + case PUSHBYTE: + case STOREINDEXED: + case STORELIST0: + case ADJUST: + case RETCODE: + printf("\t%d",*(p+1)); + p+=2; + break; + case PUSHWORD: + case CREATEARRAY: + case ONTJMP: + case ONFJMP: + case JMP: + case UPJMP: + case IFFJMP: + case IFFUPJMP: + case SETLINE: + { + CodeWord c; + p++; + get_word(c,p); + printf("\t%d",c.w); + break; + } + case PUSHFLOAT: + { + CodeFloat c; + p++; + get_float(c,p); + printf("\t%g",c.f); + break; + } + case PUSHSELF: + case PUSHSTRING: + { + CodeWord c; + p++; + get_word(c,p); + printf("\t%d\t; \"%s\"",c.w,StrStr(c.w)); + break; + } + case PUSHFUNCTION: + { + CodeCode c; + p++; + get_code(c,p); + printf("\t%p\t; \"%s\":%d",c.tf,c.tf->fileName,c.tf->lineDefined); + break; + } + case PUSHGLOBAL: + case STOREGLOBAL: + { + CodeWord c; + p++; + get_word(c,p); + printf("\t%d\t; %s",c.w,VarStr(c.w)); + break; + } + case STORELIST: + case CALLFUNC: + printf("\t%d %d",*(p+1),*(p+2)); + p+=3; + break; + case STORERECORD: + { + int n=*++p; + printf("\t%d",n); + p++; + while (n--) + { + CodeWord c; + printf("\n%6d\t FIELD",p-code); + get_word(c,p); + printf("\t%d\t; \"%s\"",c.w,StrStr(c.w)); + } + break; + } + default: + printf("\tcannot happen: opcode=%d",*p); + exit(1); + break; + } + printf("\n"); + } +} + +void PrintFunction(TFunc* tf) +{ + 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", + tf->fileName,tf->lineDefined,tf->size,tf,tf->marked); + V=tf->locvars; + PrintCode(tf->code,tf->code+tf->size); +} diff --git a/src/luac/print.h b/src/luac/print.h new file mode 100644 index 00000000..31e2bb89 --- /dev/null +++ b/src/luac/print.h @@ -0,0 +1,76 @@ +/* +** print.h +** opcode names +** $Id: print.h,v 1.1 1996/02/23 19:04:13 lhf Exp $ +*/ + +static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */ + "PUSHNIL", + "PUSH0", + "PUSH1", + "PUSH2", + "PUSHBYTE", + "PUSHWORD", + "PUSHFLOAT", + "PUSHSTRING", + "PUSHFUNCTION", + "PUSHLOCAL0", + "PUSHLOCAL1", + "PUSHLOCAL2", + "PUSHLOCAL3", + "PUSHLOCAL4", + "PUSHLOCAL5", + "PUSHLOCAL6", + "PUSHLOCAL7", + "PUSHLOCAL8", + "PUSHLOCAL9", + "PUSHLOCAL", + "PUSHGLOBAL", + "PUSHINDEXED", + "PUSHSELF", + "STORELOCAL0", + "STORELOCAL1", + "STORELOCAL2", + "STORELOCAL3", + "STORELOCAL4", + "STORELOCAL5", + "STORELOCAL6", + "STORELOCAL7", + "STORELOCAL8", + "STORELOCAL9", + "STORELOCAL", + "STOREGLOBAL", + "STOREINDEXED0", + "STOREINDEXED", + "STORELIST0", + "STORELIST", + "STORERECORD", + "ADJUST0", + "ADJUST", + "CREATEARRAY", + "EQOP", + "LTOP", + "LEOP", + "GTOP", + "GEOP", + "ADDOP", + "SUBOP", + "MULTOP", + "DIVOP", + "POWOP", + "CONCOP", + "MINUSOP", + "NOTOP", + "ONTJMP", + "ONFJMP", + "JMP", + "UPJMP", + "IFFJMP", + "IFFUPJMP", + "POP", + "CALLFUNC", + "RETCODE0", + "RETCODE", + "SETLINE", + "" +}; |