summaryrefslogtreecommitdiff
path: root/src/luac
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2003-04-11 12:00:00 +0000
committerrepogen <>2003-04-11 12:00:00 +0000
commitf0e4e22f5c119865eb5a8d3844a40df2d5980b3b (patch)
treec4df063a747e9c99f8aba1678588a030993780a9 /src/luac
parent1981b7c90eb09e956e969cda5c473be4560af573 (diff)
downloadlua-github-5.0.tar.gz
Lua 5.05.0
Diffstat (limited to 'src/luac')
-rw-r--r--src/luac/Makefile19
-rw-r--r--src/luac/README12
-rw-r--r--src/luac/dump.c121
-rw-r--r--src/luac/luac.c224
-rw-r--r--src/luac/luac.h31
-rw-r--r--src/luac/opt.c127
-rw-r--r--src/luac/print.c224
-rw-r--r--src/luac/print.h55
-rw-r--r--src/luac/stubs.c127
9 files changed, 294 insertions, 646 deletions
diff --git a/src/luac/Makefile b/src/luac/Makefile
index 4517d82b..7a620826 100644
--- a/src/luac/Makefile
+++ b/src/luac/Makefile
@@ -4,20 +4,27 @@ LUA= ../..
include $(LUA)/config
-INCS= -I$(INC) $(EXTRA_INCS) -I..
-OBJS= dump.o luac.o opt.o print.o stubs.o
-SRCS= dump.c luac.c opt.c print.c stubs.c luac.h print.h
+INCS= -I$(INC) -I.. $(EXTRA_INCS)
+OBJS= luac.o print.o lopcodes.o
+SRCS= luac.c print.c
T= $(BIN)/luac
-all: $T
+all: $T
-$T: $(OBJS) $(LIB)/liblua.a
- $(CC) -o $@ $(OBJS) -L$(LIB) -llua
+$T: $(OBJS) $(LIB)/liblua.a $(LIB)/liblualib.a
+ $(CC) -o $@ $(MYLDFLAGS) $(OBJS) -L$(LIB) -llua -llualib $(EXTRA_LIBS)
+
+# print.c needs opcode names from lopcodes.c
+lopcodes.o: ../lopcodes.c ../lopcodes.h
+ $(CC) -o $@ -c $(CFLAGS) -DLUA_OPNAMES ../lopcodes.c
$(LIB)/liblua.a:
cd ..; $(MAKE)
+$(LIB)/liblualib.a:
+ cd ../lib; $(MAKE)
+
clean:
rm -f $(OBJS) $T
diff --git a/src/luac/README b/src/luac/README
index 8d8bb491..ada7bc4b 100644
--- a/src/luac/README
+++ b/src/luac/README
@@ -1,22 +1,18 @@
This is luac, the Lua compiler.
There are man pages for it in both nroff and html in ../../doc.
-luac translates Lua programs into binary files that can be loaded and executed
-with lua_dofile in C or with dofile in Lua.
+luac translates Lua programs into binary files that can be loaded latter.
The main advantages of pre-compiling chunks are: faster loading, protecting
source code from user changes, and off-line syntax error detection.
luac can also be used to learn about the Lua virtual machine.
-Here are the options that luac understands:
-
+Usage: /l/luac/luac [options] [filenames]. Available options are:
- process stdin
-l list
- -o file output file (default is "luac.out")
+ -o name output to file `name' (default is "luac.out")
-p parse only
-s strip debug information
- -t test code integrity
-v show version information
+ -- stop handling options
luac is also an example of how to use the internals of Lua (politely).
-Finally, luac does not need the runtime code, and stubs.c makes sure it is not
-linked into luac. This file also shows how to avoid linking the parser.
diff --git a/src/luac/dump.c b/src/luac/dump.c
deleted file mode 100644
index 149469ba..00000000
--- a/src/luac/dump.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-** $Id: dump.c,v 1.30 2000/10/31 16:57:23 lhf Exp $
-** save bytecodes to file
-** See Copyright Notice in lua.h
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "luac.h"
-
-#define DumpVector(b,n,size,D) fwrite(b,size,n,D)
-#define DumpBlock(b,size,D) fwrite(b,size,1,D)
-#define DumpByte fputc
-
-static void DumpInt(int x, FILE* D)
-{
- DumpBlock(&x,sizeof(x),D);
-}
-
-static void DumpSize(size_t x, FILE* D)
-{
- DumpBlock(&x,sizeof(x),D);
-}
-
-static void DumpNumber(Number x, FILE* D)
-{
- DumpBlock(&x,sizeof(x),D);
-}
-
-static void DumpString(const TString* s, FILE* D)
-{
- if (s==NULL || s->str==NULL)
- DumpSize(0,D);
- else
- {
- size_t size=s->len+1; /* include trailing '\0' */
- DumpSize(size,D);
- DumpBlock(s->str,size,D);
- }
-}
-
-static void DumpCode(const Proto* tf, FILE* D)
-{
- DumpInt(tf->ncode,D);
- DumpVector(tf->code,tf->ncode,sizeof(*tf->code),D);
-}
-
-static void DumpLocals(const Proto* tf, FILE* D)
-{
- int i,n=tf->nlocvars;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- DumpString(tf->locvars[i].varname,D);
- DumpInt(tf->locvars[i].startpc,D);
- DumpInt(tf->locvars[i].endpc,D);
- }
-}
-
-static void DumpLines(const Proto* tf, FILE* D)
-{
- DumpInt(tf->nlineinfo,D);
- DumpVector(tf->lineinfo,tf->nlineinfo,sizeof(*tf->lineinfo),D);
-}
-
-static void DumpFunction(const Proto* tf, FILE* D);
-
-static void DumpConstants(const Proto* tf, FILE* D)
-{
- int i,n;
- DumpInt(n=tf->nkstr,D);
- for (i=0; i<n; i++)
- DumpString(tf->kstr[i],D);
- DumpInt(tf->nknum,D);
- DumpVector(tf->knum,tf->nknum,sizeof(*tf->knum),D);
- DumpInt(n=tf->nkproto,D);
- for (i=0; i<n; i++)
- DumpFunction(tf->kproto[i],D);
-}
-
-static void DumpFunction(const Proto* tf, FILE* D)
-{
- DumpString(tf->source,D);
- DumpInt(tf->lineDefined,D);
- DumpInt(tf->numparams,D);
- DumpByte(tf->is_vararg,D);
- DumpInt(tf->maxstacksize,D);
- DumpLocals(tf,D);
- DumpLines(tf,D);
- DumpConstants(tf,D);
- DumpCode(tf,D);
- if (ferror(D))
- {
- perror("luac: write error");
- exit(1);
- }
-}
-
-static void DumpHeader(FILE* D)
-{
- DumpByte(ID_CHUNK,D);
- fputs(SIGNATURE,D);
- DumpByte(VERSION,D);
- DumpByte(luaU_endianess(),D);
- DumpByte(sizeof(int),D);
- DumpByte(sizeof(size_t),D);
- DumpByte(sizeof(Instruction),D);
- DumpByte(SIZE_INSTRUCTION,D);
- DumpByte(SIZE_OP,D);
- DumpByte(SIZE_B,D);
- DumpByte(sizeof(Number),D);
- DumpNumber(TEST_NUMBER,D);
-}
-
-void luaU_dumpchunk(const Proto* Main, FILE* D)
-{
- DumpHeader(D);
- DumpFunction(Main,D);
-}
diff --git a/src/luac/luac.c b/src/luac/luac.c
index 8832de62..9ea23342 100644
--- a/src/luac/luac.c
+++ b/src/luac/luac.c
@@ -1,6 +1,6 @@
/*
-** $Id: luac.c,v 1.28 2000/11/06 20:06:27 lhf Exp $
-** lua compiler (saves bytecodes to files; also list binary files)
+** $Id: luac.c,v 1.44 2003/04/07 20:34:20 lhf Exp $
+** Lua compiler (saves bytecodes to files; also list bytecodes)
** See Copyright Notice in lua.h
*/
@@ -8,78 +8,80 @@
#include <stdlib.h>
#include <string.h>
-#include "lparser.h"
-#include "lstate.h"
-#include "lzio.h"
-#include "luac.h"
+#include "lua.h"
+#include "lauxlib.h"
-#define OUTPUT "luac.out" /* default output file */
+#include "lfunc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstring.h"
+#include "lundump.h"
-static void usage(const char* message, const char* arg);
-static int doargs(int argc, const char* argv[]);
-static Proto* load(const char* filename);
-static FILE* efopen(const char* name, const char* mode);
-static void strip(Proto* tf);
-static Proto* combine(Proto** P, int n);
+#ifndef LUA_DEBUG
+#define luaB_opentests(L)
+#endif
-lua_State* lua_state=NULL; /* lazy! */
+#ifndef PROGNAME
+#define PROGNAME "luac" /* program name */
+#endif
+
+#define OUTPUT "luac.out" /* default output file */
static int listing=0; /* list bytecodes? */
static int dumping=1; /* dump bytecodes? */
static int stripping=0; /* strip debug information? */
-static int testing=0; /* test integrity? */
-static const char* output=OUTPUT; /* output file name */
+static char Output[]={ OUTPUT }; /* default output file name */
+static const char* output=Output; /* output file name */
+static const char* progname=PROGNAME; /* actual program name */
-#define IS(s) (strcmp(argv[i],s)==0)
+static void fatal(const char* message)
+{
+ fprintf(stderr,"%s: %s\n",progname,message);
+ exit(EXIT_FAILURE);
+}
-int main(int argc, const char* argv[])
+static void cannot(const char* name, const char* what, const char* mode)
{
- Proto** P,*tf;
- int i=doargs(argc,argv);
- argc-=i; argv+=i;
- if (argc<=0) usage("no input files given",NULL);
- L=lua_open(0);
- P=luaM_newvector(L,argc,Proto*);
- for (i=0; i<argc; i++)
- P[i]=load(IS("-")? NULL : argv[i]);
- tf=combine(P,argc);
- if (dumping) luaU_optchunk(tf);
- if (listing) luaU_printchunk(tf);
- if (testing) luaU_testchunk(tf);
- if (dumping)
- {
- if (stripping) strip(tf);
- luaU_dumpchunk(tf,efopen(output,"wb"));
- }
- return 0;
+ fprintf(stderr,"%s: cannot %s %sput file ",progname,what,mode);
+ perror(name);
+ exit(EXIT_FAILURE);
}
static void usage(const char* message, const char* arg)
{
if (message!=NULL)
{
- fprintf(stderr,"luac: "); fprintf(stderr,message,arg); fprintf(stderr,"\n");
+ fprintf(stderr,"%s: ",progname); fprintf(stderr,message,arg); fprintf(stderr,"\n");
}
fprintf(stderr,
- "usage: luac [options] [filenames]. Available options are:\n"
+ "usage: %s [options] [filenames]. Available options are:\n"
" - process stdin\n"
" -l list\n"
- " -o file output file (default is \"" OUTPUT "\")\n"
+ " -o name output to file `name' (default is \"" OUTPUT "\")\n"
" -p parse only\n"
" -s strip debug information\n"
- " -t test code integrity\n"
" -v show version information\n"
- );
- exit(1);
+ " -- stop handling options\n",
+ progname);
+ exit(EXIT_FAILURE);
}
-static int doargs(int argc, const char* argv[])
+#define IS(s) (strcmp(argv[i],s)==0)
+
+static int doargs(int argc, char* argv[])
{
int i;
+ if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
for (i=1; i<argc; i++)
{
- if (*argv[i]!='-') /* end of options */
+ if (*argv[i]!='-') /* end of options; keep it */
+ break;
+ else if (IS("--")) /* end of options; skip it */
+ {
+ ++i;
break;
+ }
else if (IS("-")) /* end of options; use stdin */
return i;
else if (IS("-l")) /* list */
@@ -87,117 +89,103 @@ static int doargs(int argc, const char* argv[])
else if (IS("-o")) /* output file */
{
output=argv[++i];
- if (output==NULL) usage(NULL,NULL);
+ if (output==NULL || *output==0) usage("`-o' needs argument",NULL);
}
else if (IS("-p")) /* parse only */
dumping=0;
else if (IS("-s")) /* strip debug information */
stripping=1;
- else if (IS("-t")) /* test */
- {
- testing=1;
- dumping=0;
- }
else if (IS("-v")) /* show version */
{
printf("%s %s\n",LUA_VERSION,LUA_COPYRIGHT);
- if (argc==2) exit(0);
+ if (argc==2) exit(EXIT_SUCCESS);
}
else /* unknown option */
usage("unrecognized option `%s'",argv[i]);
}
- if (i==argc && (listing || testing))
+ if (i==argc && (listing || !dumping))
{
dumping=0;
- argv[--i]=OUTPUT;
+ argv[--i]=Output;
}
return i;
}
-static Proto* load(const char* filename)
+static Proto* toproto(lua_State* L, int i)
{
- Proto* tf;
- ZIO z;
- char source[512];
- FILE* f;
- int c,undump;
- if (filename==NULL)
- {
- f=stdin;
- filename="(stdin)";
- }
- else
- f=efopen(filename,"r");
- c=ungetc(fgetc(f),f);
- if (ferror(f))
- {
- fprintf(stderr,"luac: cannot read from ");
- perror(filename);
- exit(1);
- }
- undump=(c==ID_CHUNK);
- if (undump && f!=stdin)
- {
- fclose(f);
- f=efopen(filename,"rb");
- }
- sprintf(source,"@%.*s",Sizeof(source)-2,filename);
- luaZ_Fopen(&z,f,source);
- tf = undump ? luaU_undump(L,&z) : luaY_parser(L,&z);
- if (f!=stdin) fclose(f);
- return tf;
+ const Closure* c=(const Closure*)lua_topointer(L,i);
+ return c->l.p;
}
-static Proto* combine(Proto** P, int n)
+static Proto* combine(lua_State* L, int n)
{
if (n==1)
- return P[0];
+ return toproto(L,-1);
else
{
int i,pc=0;
- Proto* tf=luaF_newproto(L);
- tf->source=luaS_new(L,"=(luac)");
- tf->maxstacksize=1;
- tf->kproto=P;
- tf->nkproto=n;
- tf->ncode=2*n+1;
- tf->code=luaM_newvector(L,tf->ncode,Instruction);
+ Proto* f=luaF_newproto(L);
+ f->source=luaS_newliteral(L,"=(" PROGNAME ")");
+ f->maxstacksize=1;
+ f->p=luaM_newvector(L,n,Proto*);
+ f->sizep=n;
+ f->sizecode=2*n+1;
+ f->code=luaM_newvector(L,f->sizecode,Instruction);
for (i=0; i<n; i++)
{
- tf->code[pc++]=CREATE_AB(OP_CLOSURE,i,0);
- tf->code[pc++]=CREATE_AB(OP_CALL,0,0);
+ f->p[i]=toproto(L,i-n);
+ f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i);
+ f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
}
- tf->code[pc++]=OP_END;
- return tf;
+ f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0);
+ return f;
}
}
-static void strip(Proto* tf)
+static void strip(lua_State* L, Proto* f)
{
- int i,n=tf->nkproto;
- tf->lineinfo=NULL;
- tf->nlineinfo=0;
- tf->source=luaS_new(L,"=(none)");
- tf->locvars=NULL;
- tf->nlocvars=0;
- for (i=0; i<n; i++) strip(tf->kproto[i]);
+ int i,n=f->sizep;
+ luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
+ luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
+ luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
+ f->lineinfo=NULL; f->sizelineinfo=0;
+ f->locvars=NULL; f->sizelocvars=0;
+ f->upvalues=NULL; f->sizeupvalues=0;
+ f->source=luaS_newliteral(L,"=(none)");
+ for (i=0; i<n; i++) strip(L,f->p[i]);
}
-static FILE* efopen(const char* name, const char* mode)
+static int writer(lua_State* L, const void* p, size_t size, void* u)
{
- FILE* f=fopen(name,mode);
- if (f==NULL)
- {
- fprintf(stderr,"luac: cannot open %sput file ",*mode=='r' ? "in" : "out");
- perror(name);
- exit(1);
- }
- return f;
+ UNUSED(L);
+ return fwrite(p,size,1,(FILE*)u)==1;
}
-void luaU_testchunk(const Proto* Main)
+int main(int argc, char* argv[])
{
- UNUSED(Main);
- fprintf(stderr,"luac: -t not operational in this version\n");
- exit(1);
+ lua_State* L;
+ Proto* f;
+ int i=doargs(argc,argv);
+ argc-=i; argv+=i;
+ if (argc<=0) usage("no input files given",NULL);
+ L=lua_open();
+ luaB_opentests(L);
+ for (i=0; i<argc; i++)
+ {
+ const char* filename=IS("-") ? NULL : argv[i];
+ if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
+ }
+ f=combine(L,argc);
+ if (listing) luaU_print(f);
+ if (dumping)
+ {
+ FILE* D=fopen(output,"wb");
+ if (D==NULL) cannot(output,"open","out");
+ if (stripping) strip(L,f);
+ luaU_dump(L,f,writer,D);
+ if (ferror(D)) cannot(output,"write","out");
+ fclose(D);
+ }
+ lua_close(L);
+ return 0;
}
diff --git a/src/luac/luac.h b/src/luac/luac.h
deleted file mode 100644
index f8987cf2..00000000
--- a/src/luac/luac.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-** $Id: luac.h,v 1.18 2000/10/31 16:57:23 lhf Exp $
-** definitions for luac
-** See Copyright Notice in lua.h
-*/
-
-#include "ldebug.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "lundump.h"
-
-extern lua_State *lua_state;
-#define L lua_state /* lazy! */
-
-/* from dump.c */
-void luaU_dumpchunk(const Proto* Main, FILE* D);
-
-/* from opt.c */
-void luaU_optchunk(Proto* Main);
-
-/* from print.c */
-void luaU_printchunk(const Proto* Main);
-
-/* from test.c */
-void luaU_testchunk(const Proto* Main);
-
-#define Sizeof(x) ((int)sizeof(x))
diff --git a/src/luac/opt.c b/src/luac/opt.c
deleted file mode 100644
index e51a0868..00000000
--- a/src/luac/opt.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-** $Id: opt.c,v 1.22 2000/10/31 16:57:23 lhf Exp $
-** optimize bytecodes
-** See Copyright Notice in lua.h
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "luac.h"
-
-static int MapConstant(Hash* t, int j, const TObject* key)
-{
- const TObject* o=luaH_get(L,t,key);
- if (ttype(o)==LUA_TNUMBER)
- return (int) nvalue(o);
- else
- {
- TObject val;
- ttype(&val)=LUA_TNUMBER;
- nvalue(&val)=j;
- *luaH_set(L,t,key)=val;
- LUA_ASSERT(j>=0,"MapConstant returns negative!");
- return j;
- }
-}
-
-static int MapConstants(Proto* tf, Hash* map)
-{
- int i,j,k,n,m=0;
- TObject o;
- j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
- for (i=0; i<n; i++)
- {
- nvalue(&o)=tf->knum[i];
- k=MapConstant(map,j,&o);
- if (k==j) j++;
- }
- m=j;
- j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
- for (i=0; i<n; i++)
- {
- tsvalue(&o)=tf->kstr[i];
- k=MapConstant(map,j,&o);
- if (k==j) j++;
- }
- return m+j;
-}
-
-static void PackConstants(Proto* tf, Hash* map)
-{
- int i,j,k,n;
- TObject o;
-#ifdef DEBUG
- printf("%p before pack nknum=%d nkstr=%d\n",tf,tf->nknum,tf->nkstr);
-#endif
- j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
- for (i=0; i<n; i++)
- {
- nvalue(&o)=tf->knum[i];
- k=MapConstant(map,-1,&o);
- if (k==j) tf->knum[j++]=tf->knum[i];
- }
- tf->nknum=j;
- j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
- for (i=0; i<n; i++)
- {
- tsvalue(&o)=tf->kstr[i];
- k=MapConstant(map,-1,&o);
- if (k==j) tf->kstr[j++]=tf->kstr[i];
- }
- tf->nkstr=j;
-#ifdef DEBUG
- printf("%p after pack nknum=%d nkstr=%d\n",tf,tf->nknum,tf->nkstr);
-#endif
-}
-
-static void OptConstants(Proto* tf)
-{
- Instruction* p;
- int n=tf->nknum+tf->nkstr;
- Hash* map=luaH_new(L,n);
- int m=MapConstants(tf,map);
-#ifdef DEBUG
- printf("%p n=%d m=%d %s\n",tf,n,m,(m==n)?"nothing to optimize":"yes!");
-#endif
- if (m==n) return;
- for (p=tf->code;; p++)
- {
- Instruction i=*p;
- int op=GET_OPCODE(i);
- switch (op)
- {
- TObject o;
- int j,k;
- case OP_PUSHNUM: case OP_PUSHNEGNUM:
- j=GETARG_U(i);
- ttype(&o)=LUA_TNUMBER; nvalue(&o)=tf->knum[j];
- k=MapConstant(map,-1,&o);
- if (k!=j) *p=CREATE_U(op,k);
- break;
- case OP_PUSHSTRING: case OP_GETGLOBAL: case OP_GETDOTTED:
- case OP_PUSHSELF: case OP_SETGLOBAL:
- j=GETARG_U(i);
- ttype(&o)=LUA_TSTRING; tsvalue(&o)=tf->kstr[j];
- k=MapConstant(map,-1,&o);
- if (k!=j) *p=CREATE_U(op,k);
- break;
- case OP_END:
- PackConstants(tf,map);
- luaH_free(L,map);
- return;
- default:
- break;
- }
- }
-}
-
-#define OptFunction luaU_optchunk
-
-void OptFunction(Proto* tf)
-{
- int i,n=tf->nkproto;
- OptConstants(tf);
- for (i=0; i<n; i++) OptFunction(tf->kproto[i]);
-}
diff --git a/src/luac/print.c b/src/luac/print.c
index 4ffc8b3d..d0b5efb2 100644
--- a/src/luac/print.c
+++ b/src/luac/print.c
@@ -1,31 +1,30 @@
/*
-** $Id: print.c,v 1.32 2000/11/06 20:04:36 lhf Exp $
+** $Id: print.c,v 1.44 2003/04/07 20:34:20 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
#include <stdio.h>
-#include <stdlib.h>
-
-#include "luac.h"
-
-/* macros used in print.h, included in PrintCode */
-#define P_OP(x) printf("%-11s\t",x)
-#define P_NONE
-#define P_AB printf("%d %d",GETARG_A(i),GETARG_B(i))
-#define P_F printf("%d %d\t; %p",GETARG_A(i),GETARG_B(i),tf->kproto[GETARG_A(i)])
-#define P_J printf("%d\t; to %d",GETARG_S(i),GETARG_S(i)+at+1)
-#define P_Q PrintString(tf,GETARG_U(i))
-#define P_K printf("%d\t; %s",GETARG_U(i),tf->kstr[GETARG_U(i)]->str)
-#define P_L PrintLocal(tf,GETARG_U(i),at-1)
-#define P_N printf("%d\t; " NUMBER_FMT,GETARG_U(i),tf->knum[GETARG_U(i)])
-#define P_S printf("%d",GETARG_S(i))
-#define P_U printf("%u",GETARG_U(i))
-
-static void PrintString(const Proto* tf, int n)
+
+#if 0
+#define DEBUG_PRINT
+#endif
+
+#ifndef LUA_OPNAMES
+#define LUA_OPNAMES
+#endif
+
+#include "ldebug.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lundump.h"
+
+#define Sizeof(x) ((int)sizeof(x))
+#define VOID(p) ((const void*)(p))
+
+static void PrintString(const Proto* f, int n)
{
- const char* s=tf->kstr[n]->str;
- printf("%d\t; ",n);
+ const char* s=svalue(&f->k[n]);
putchar('"');
for (; *s; s++)
{
@@ -45,55 +44,174 @@ static void PrintString(const Proto* tf, int n)
putchar('"');
}
-static void PrintLocal(const Proto* tf, int n, int pc)
+static void PrintConstant(const Proto* f, int i)
{
- const char* s=luaF_getlocalname(tf,n+1,pc);
- printf("%u",n);
- if (s!=NULL) printf("\t; %s",s);
+ const TObject* o=&f->k[i];
+ switch (ttype(o))
+ {
+ case LUA_TNUMBER:
+ printf(LUA_NUMBER_FMT,nvalue(o));
+ break;
+ case LUA_TSTRING:
+ PrintString(f,i);
+ break;
+ case LUA_TNIL:
+ printf("nil");
+ break;
+ default: /* cannot happen */
+ printf("? type=%d",ttype(o));
+ break;
+ }
}
-static void PrintCode(const Proto* tf)
+static void PrintCode(const Proto* f)
{
- const Instruction* code=tf->code;
- const Instruction* p=code;
- for (;;)
+ const Instruction* code=f->code;
+ int pc,n=f->sizecode;
+ for (pc=0; pc<n; pc++)
{
- int at=p-code+1;
- Instruction i=*p;
- int line=luaG_getline(tf->lineinfo,at-1,1,NULL);
- printf("%6d\t",at);
- if (line>=0) printf("[%d]\t",line); else printf("[-]\t");
- switch (GET_OPCODE(i)) {
-#include "print.h"
+ Instruction i=code[pc];
+ OpCode o=GET_OPCODE(i);
+ int a=GETARG_A(i);
+ int b=GETARG_B(i);
+ int c=GETARG_C(i);
+ int bc=GETARG_Bx(i);
+ int sbc=GETARG_sBx(i);
+ int line=getline(f,pc);
+#if 0
+ printf("%0*lX",Sizeof(i)*2,i);
+#endif
+ printf("\t%d\t",pc+1);
+ if (line>0) printf("[%d]\t",line); else printf("[-]\t");
+ printf("%-9s\t",luaP_opnames[o]);
+ switch (getOpMode(o))
+ {
+ case iABC: printf("%d %d %d",a,b,c); break;
+ case iABx: printf("%d %d",a,bc); break;
+ case iAsBx: printf("%d %d",a,sbc); break;
+ }
+ switch (o)
+ {
+ case OP_LOADK:
+ printf("\t; "); PrintConstant(f,bc);
+ break;
+ case OP_GETUPVAL:
+ case OP_SETUPVAL:
+ printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
+ break;
+ case OP_GETGLOBAL:
+ case OP_SETGLOBAL:
+ printf("\t; %s",svalue(&f->k[bc]));
+ break;
+ case OP_GETTABLE:
+ case OP_SELF:
+ if (c>=MAXSTACK) { printf("\t; "); PrintConstant(f,c-MAXSTACK); }
+ break;
+ case OP_SETTABLE:
+ case OP_ADD:
+ case OP_SUB:
+ case OP_MUL:
+ case OP_DIV:
+ case OP_POW:
+ case OP_EQ:
+ case OP_LT:
+ case OP_LE:
+ if (b>=MAXSTACK || c>=MAXSTACK)
+ {
+ printf("\t; ");
+ if (b>=MAXSTACK) PrintConstant(f,b-MAXSTACK); else printf("-");
+ printf(" ");
+ if (c>=MAXSTACK) PrintConstant(f,c-MAXSTACK);
+ }
+ break;
+ case OP_JMP:
+ case OP_FORLOOP:
+ case OP_TFORPREP:
+ printf("\t; to %d",sbc+pc+2);
+ break;
+ case OP_CLOSURE:
+ printf("\t; %p",VOID(f->p[bc]));
+ break;
+ default:
+ break;
}
printf("\n");
- if (i==OP_END) break;
- p++;
}
}
-#define IsMain(tf) (tf->lineDefined==0)
+static const char* Source(const Proto* f)
+{
+ const char* s=getstr(f->source);
+ if (*s=='@' || *s=='=')
+ return s+1;
+ else if (*s==LUA_SIGNATURE[0])
+ return "(bstring)";
+ else
+ return "(string)";
+}
+
+#define IsMain(f) (f->lineDefined==0)
#define SS(x) (x==1)?"":"s"
#define S(x) x,SS(x)
-static void PrintHeader(const Proto* tf)
+static void PrintHeader(const Proto* f)
+{
+ printf("\n%s <%s:%d> (%d instruction%s, %d bytes at %p)\n",
+ IsMain(f)?"main":"function",Source(f),f->lineDefined,
+ S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
+ printf("%d%s param%s, %d stack%s, %d upvalue%s, ",
+ f->numparams,f->is_vararg?"+":"",SS(f->numparams),S(f->maxstacksize),
+ S(f->nups));
+ printf("%d local%s, %d constant%s, %d function%s\n",
+ S(f->sizelocvars),S(f->sizek),S(f->sizep));
+}
+
+#ifdef DEBUG_PRINT
+static void PrintConstants(const Proto* f)
+{
+ int i,n=f->sizek;
+ printf("constants (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t",i);
+ PrintConstant(f,i);
+ printf("\n");
+ }
+}
+
+static void PrintLocals(const Proto* f)
{
- printf("\n%s " SOURCE_FMT " (%d instruction%s/%d bytes at %p)\n",
- IsMain(tf)?"main":"function",SOURCE,
- S(tf->ncode),tf->ncode*Sizeof(Instruction),tf);
- printf("%d%s param%s, %d stack%s, ",
- tf->numparams,tf->is_vararg?"+":"",SS(tf->numparams),S(tf->maxstacksize));
- printf("%d local%s, %d string%s, %d number%s, %d function%s, %d line%s\n",
- S(tf->nlocvars),S(tf->nkstr),S(tf->nknum),S(tf->nkproto),S(tf->nlineinfo));
+ int i,n=f->sizelocvars;
+ printf("locals (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t%s\t%d\t%d\n",
+ i,getstr(f->locvars[i].varname),f->locvars[i].startpc,f->locvars[i].endpc);
+ }
}
-#define PrintFunction luaU_printchunk
+static void PrintUpvalues(const Proto* f)
+{
+ int i,n=f->sizeupvalues;
+ printf("upvalues (%d) for %p:\n",n,VOID(f));
+ if (f->upvalues==NULL) return;
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
+ }
+}
+#endif
-void PrintFunction(const Proto* tf)
+void luaU_print(const Proto* f)
{
- int i,n=tf->nkproto;
- PrintHeader(tf);
- PrintCode(tf);
- for (i=0; i<n; i++) PrintFunction(tf->kproto[i]);
+ int i,n=f->sizep;
+ PrintHeader(f);
+ PrintCode(f);
+#ifdef DEBUG_PRINT
+ PrintConstants(f);
+ PrintLocals(f);
+ PrintUpvalues(f);
+#endif
+ for (i=0; i<n; i++) luaU_print(f->p[i]);
}
diff --git a/src/luac/print.h b/src/luac/print.h
deleted file mode 100644
index 5f74e149..00000000
--- a/src/luac/print.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-** $Id: print.h,v 1.1 2000/11/06 20:03:12 lhf Exp $
-** extracted automatically from lopcodes.h by mkprint.lua -- DO NOT EDIT
-** See Copyright Notice in lua.h
-*/
-
- case OP_END: P_OP("END"); P_NONE; break;
- case OP_RETURN: P_OP("RETURN"); P_U; break;
- case OP_CALL: P_OP("CALL"); P_AB; break;
- case OP_TAILCALL: P_OP("TAILCALL"); P_AB; break;
- case OP_PUSHNIL: P_OP("PUSHNIL"); P_U; break;
- case OP_POP: P_OP("POP"); P_U; break;
- case OP_PUSHINT: P_OP("PUSHINT"); P_S; break;
- case OP_PUSHSTRING: P_OP("PUSHSTRING"); P_Q; break;
- case OP_PUSHNUM: P_OP("PUSHNUM"); P_N; break;
- case OP_PUSHNEGNUM: P_OP("PUSHNEGNUM"); P_N; break;
- case OP_PUSHUPVALUE: P_OP("PUSHUPVALUE"); P_U; break;
- case OP_GETLOCAL: P_OP("GETLOCAL"); P_L; break;
- case OP_GETGLOBAL: P_OP("GETGLOBAL"); P_K; break;
- case OP_GETTABLE: P_OP("GETTABLE"); P_NONE; break;
- case OP_GETDOTTED: P_OP("GETDOTTED"); P_K; break;
- case OP_GETINDEXED: P_OP("GETINDEXED"); P_L; break;
- case OP_PUSHSELF: P_OP("PUSHSELF"); P_K; break;
- case OP_CREATETABLE: P_OP("CREATETABLE"); P_U; break;
- case OP_SETLOCAL: P_OP("SETLOCAL"); P_L; break;
- case OP_SETGLOBAL: P_OP("SETGLOBAL"); P_K; break;
- case OP_SETTABLE: P_OP("SETTABLE"); P_AB; break;
- case OP_SETLIST: P_OP("SETLIST"); P_AB; break;
- case OP_SETMAP: P_OP("SETMAP"); P_U; break;
- case OP_ADD: P_OP("ADD"); P_NONE; break;
- case OP_ADDI: P_OP("ADDI"); P_S; break;
- case OP_SUB: P_OP("SUB"); P_NONE; break;
- case OP_MULT: P_OP("MULT"); P_NONE; break;
- case OP_DIV: P_OP("DIV"); P_NONE; break;
- case OP_POW: P_OP("POW"); P_NONE; break;
- case OP_CONCAT: P_OP("CONCAT"); P_U; break;
- case OP_MINUS: P_OP("MINUS"); P_NONE; break;
- case OP_NOT: P_OP("NOT"); P_NONE; break;
- case OP_JMPNE: P_OP("JMPNE"); P_J; break;
- case OP_JMPEQ: P_OP("JMPEQ"); P_J; break;
- case OP_JMPLT: P_OP("JMPLT"); P_J; break;
- case OP_JMPLE: P_OP("JMPLE"); P_J; break;
- case OP_JMPGT: P_OP("JMPGT"); P_J; break;
- case OP_JMPGE: P_OP("JMPGE"); P_J; break;
- case OP_JMPT: P_OP("JMPT"); P_J; break;
- case OP_JMPF: P_OP("JMPF"); P_J; break;
- case OP_JMPONT: P_OP("JMPONT"); P_J; break;
- case OP_JMPONF: P_OP("JMPONF"); P_J; break;
- case OP_JMP: P_OP("JMP"); P_J; break;
- case OP_PUSHNILJMP: P_OP("PUSHNILJMP"); P_NONE; break;
- case OP_FORPREP: P_OP("FORPREP"); P_J; break;
- case OP_FORLOOP: P_OP("FORLOOP"); P_J; break;
- case OP_LFORPREP: P_OP("LFORPREP"); P_J; break;
- case OP_LFORLOOP: P_OP("LFORLOOP"); P_J; break;
- case OP_CLOSURE: P_OP("CLOSURE"); P_F; break;
diff --git a/src/luac/stubs.c b/src/luac/stubs.c
deleted file mode 100644
index 74f509eb..00000000
--- a/src/luac/stubs.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-** $Id: stubs.c,v 1.20 2000/10/31 16:57:23 lhf Exp $
-** avoid runtime modules in luac
-** See Copyright Notice in lua.h
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ldo.h"
-#include "llex.h"
-#include "luac.h"
-#undef L
-
-#ifndef NOSTUBS
-
-const char luac_ident[] = "$luac: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
- "$Authors: " LUA_AUTHORS " $";
-
-/*
-* avoid lapi ldebug ldo lgc lstate ltm lvm
-* use only lcode lfunc llex lmem lobject lparser lstring ltable lzio
-*/
-
-/* simplified from ldo.c */
-void lua_error (lua_State* L, const char* s) {
- UNUSED(L);
- if (s) fprintf(stderr,"luac: %s\n",s);
- exit(1);
-}
-
-/* simplified from ldo.c */
-void luaD_breakrun (lua_State *L, int errcode) {
- UNUSED(errcode);
- lua_error(L,"memory allocation error");
-}
-
-/* simplified from lstate.c */
-lua_State *lua_open (int stacksize) {
- lua_State *L = luaM_new(NULL, lua_State);
- if (L == NULL) return NULL; /* memory allocation error */
- L->stack = NULL;
- L->strt.size = L->udt.size = 0;
- L->strt.nuse = L->udt.nuse = 0;
- L->strt.hash = NULL;
- L->udt.hash = NULL;
- L->Mbuffer = NULL;
- L->Mbuffsize = 0;
- L->rootproto = NULL;
- L->rootcl = NULL;
- L->roottable = NULL;
- L->TMtable = NULL;
- L->last_tag = -1;
- L->refArray = NULL;
- L->refSize = 0;
- L->refFree = NONEXT;
- L->nblocks = sizeof(lua_State);
- L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */
- L->callhook = NULL;
- L->linehook = NULL;
- L->allowhooks = 1;
- L->errorJmp = NULL;
- if (stacksize == 0)
- stacksize = DEFAULT_STACK_SIZE;
- else
- stacksize += LUA_MINSTACK;
- L->gt = luaH_new(L, 10); /* table of globals */
- luaS_init(L);
- luaX_init(L);
- L->GCthreshold = 2*L->nblocks;
- return L;
-}
-
-/* copied from ldebug.c */
-int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
- int refi;
- if (lineinfo == NULL || pc == -1)
- return -1; /* no line info or function is not active */
- refi = prefi ? *prefi : 0;
- if (lineinfo[refi] < 0)
- refline += -lineinfo[refi++];
- LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
- while (lineinfo[refi] > pc) {
- refline--;
- refi--;
- if (lineinfo[refi] < 0)
- refline -= -lineinfo[refi--];
- LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
- }
- for (;;) {
- int nextline = refline + 1;
- int nextref = refi + 1;
- if (lineinfo[nextref] < 0)
- nextline += -lineinfo[nextref++];
- LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info");
- if (lineinfo[nextref] > pc)
- break;
- refline = nextline;
- refi = nextref;
- }
- if (prefi) *prefi = refi;
- return refline;
-}
-
-/*
-* the code below avoids the lexer and the parser (llex lparser lcode).
-* it is useful if you only want to load binary files.
-* this works for interpreters like lua.c too.
-*/
-
-#ifdef NOPARSER
-
-#include "llex.h"
-#include "lparser.h"
-
-void luaX_init(lua_State *L) {
- UNUSED(L);
-}
-
-Proto *luaY_parser(lua_State *L, ZIO *z) {
- UNUSED(z);
- lua_error(L,"parser not loaded");
- return NULL;
-}
-
-#endif
-#endif