summaryrefslogtreecommitdiff
path: root/src/luac
diff options
context:
space:
mode:
Diffstat (limited to 'src/luac')
-rw-r--r--src/luac/Makefile24
-rw-r--r--src/luac/dump.c247
-rw-r--r--src/luac/luac.c104
-rw-r--r--src/luac/luac.h24
-rw-r--r--src/luac/print.c189
-rw-r--r--src/luac/print.h76
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",
+ ""
+};