summaryrefslogtreecommitdiff
path: root/src/luac
diff options
context:
space:
mode:
authorLua Team <team@lua.org>1997-07-01 12:00:00 +0000
committerrepogen <>1997-07-01 12:00:00 +0000
commit4f8c5d0f284e1f4da717aea5008915f185cd2e05 (patch)
tree5671acf8a2cacf0c0524ce96d22959590a3aa5af /src/luac
parent47a298a24ad3a8202440051de5938618502302a0 (diff)
downloadlua-github-3.0.tar.gz
Lua 3.03.0
Diffstat (limited to 'src/luac')
-rw-r--r--src/luac/dump.c30
-rw-r--r--src/luac/luac.c139
-rw-r--r--src/luac/luac.h11
-rw-r--r--src/luac/print.c233
-rw-r--r--src/luac/print.h9
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]))