mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-10 15:21:34 +00:00
a39565b783
... not quite content with where the project files lie but it is ok for now. ... compiling works fine so far (only tested mingw32 right now)
447 lines
9.9 KiB
C
447 lines
9.9 KiB
C
/*
|
|
** $Id: luac.c,v 1.65 2010/10/26 09:07:52 lhf Exp $
|
|
** Lua compiler (saves bytecodes to files; also list bytecodes)
|
|
** See Copyright Notice in lua.h
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define luac_c
|
|
#define LUA_CORE
|
|
|
|
#include "lua.h"
|
|
#include "lauxlib.h"
|
|
|
|
#include "lobject.h"
|
|
#include "lstate.h"
|
|
#include "lundump.h"
|
|
|
|
#if LUA_STANDALONE
|
|
static void PrintFunction(const Proto* f, int full);
|
|
#endif
|
|
#define luaU_print PrintFunction
|
|
|
|
#define PROGNAME "luac" /* default program name */
|
|
#define OUTPUT PROGNAME ".out" /* default output file */
|
|
|
|
#if LUA_STANDALONE
|
|
static int listing=0; /* list bytecodes? */
|
|
static int dumping=1; /* dump bytecodes? */
|
|
static int stripping=0; /* strip debug information? */
|
|
static char Output[]={ OUTPUT }; /* default output file name */
|
|
static const char* output=Output; /* actual output file name */
|
|
static const char* progname=PROGNAME; /* actual program name */
|
|
|
|
static void fatal(const char* message)
|
|
{
|
|
fprintf(stderr,"%s: %s\n",progname,message);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
static void cannot(const char* what)
|
|
{
|
|
fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
static void usage(const char* message)
|
|
{
|
|
if (*message=='-')
|
|
fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message);
|
|
else
|
|
fprintf(stderr,"%s: %s\n",progname,message);
|
|
fprintf(stderr,
|
|
"usage: %s [options] [filenames]\n"
|
|
"Available options are:\n"
|
|
" -l list\n"
|
|
" -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
|
|
" -p parse only\n"
|
|
" -s strip debug information\n"
|
|
" -v show version information\n"
|
|
" -- stop handling options\n"
|
|
" - stop handling options and process stdin\n"
|
|
,progname,Output);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#endif
|
|
|
|
#define IS(s) (strcmp(argv[i],s)==0)
|
|
|
|
#if LUA_STANDALONE
|
|
static int doargs(int argc, char* argv[])
|
|
{
|
|
int i;
|
|
int version=0;
|
|
if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0];
|
|
for (i=1; i<argc; i++)
|
|
{
|
|
if (*argv[i]!='-') /* end of options; keep it */
|
|
break;
|
|
else if (IS("--")) /* end of options; skip it */
|
|
{
|
|
++i;
|
|
if (version) ++version;
|
|
break;
|
|
}
|
|
else if (IS("-")) /* end of options; use stdin */
|
|
break;
|
|
else if (IS("-l")) /* list */
|
|
++listing;
|
|
else if (IS("-o")) /* output file */
|
|
{
|
|
output=argv[++i];
|
|
if (output==NULL || *output==0 || (*output=='-' && output[1]!=0))
|
|
usage(LUA_QL("-o") " needs argument");
|
|
if (IS("-")) output=NULL;
|
|
}
|
|
else if (IS("-p")) /* parse only */
|
|
dumping=0;
|
|
else if (IS("-s")) /* strip debug information */
|
|
stripping=1;
|
|
else if (IS("-v")) /* show version */
|
|
++version;
|
|
else /* unknown option */
|
|
usage(argv[i]);
|
|
}
|
|
if (i==argc && (listing || !dumping))
|
|
{
|
|
dumping=0;
|
|
argv[--i]=Output;
|
|
}
|
|
if (version)
|
|
{
|
|
printf("%s\n",LUA_COPYRIGHT);
|
|
if (version==argc-1) exit(EXIT_SUCCESS);
|
|
}
|
|
return i;
|
|
}
|
|
#endif
|
|
|
|
#define FUNCTION "(function()end)();"
|
|
|
|
#if LUA_STANDALONE
|
|
static const char* reader(lua_State *L, void *ud, size_t *size)
|
|
{
|
|
UNUSED(L);
|
|
if ((*(int*)ud)--)
|
|
{
|
|
*size=sizeof(FUNCTION)-1;
|
|
return FUNCTION;
|
|
}
|
|
else
|
|
{
|
|
*size=0;
|
|
return NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define toproto(L,i) getproto(L->top+(i))
|
|
|
|
#if LUA_STANDALONE
|
|
static const Proto* combine(lua_State* L, int n)
|
|
{
|
|
if (n==1)
|
|
return toproto(L,-1);
|
|
else
|
|
{
|
|
Proto* f;
|
|
int i=n;
|
|
if (lua_load(L,reader,&i,"=(" PROGNAME ")")!=LUA_OK) fatal(lua_tostring(L,-1));
|
|
f=toproto(L,-1);
|
|
for (i=0; i<n; i++) f->p[i]=toproto(L,i-n-1);
|
|
f->sizelineinfo=0;
|
|
f->sizeupvalues=0;
|
|
return f;
|
|
}
|
|
}
|
|
|
|
static int writer(lua_State* L, const void* p, size_t size, void* u)
|
|
{
|
|
UNUSED(L);
|
|
return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0);
|
|
}
|
|
|
|
static int pmain(lua_State* L)
|
|
{
|
|
int argc=(int)lua_tointeger(L,1);
|
|
char** argv=lua_touserdata(L,2);
|
|
const Proto* f;
|
|
int i;
|
|
if (!lua_checkstack(L,argc)) fatal("too many input files");
|
|
for (i=0; i<argc; i++)
|
|
{
|
|
const char* filename=IS("-") ? NULL : argv[i];
|
|
if (luaL_loadfile(L,filename)!=LUA_OK) fatal(lua_tostring(L,-1));
|
|
}
|
|
f=combine(L,argc);
|
|
if (listing) luaU_print(f,listing>1);
|
|
if (dumping)
|
|
{
|
|
FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
|
|
if (D==NULL) cannot("open");
|
|
lua_lock(L);
|
|
luaU_dump(L,f,writer,D,stripping);
|
|
lua_unlock(L);
|
|
if (ferror(D)) cannot("write");
|
|
if (fclose(D)) cannot("close");
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
int main(int argc, char* argv[])
|
|
{
|
|
lua_State* L;
|
|
int i=doargs(argc,argv);
|
|
argc-=i; argv+=i;
|
|
if (argc<=0) usage("no input files given");
|
|
L=luaL_newstate();
|
|
if (L==NULL) fatal("not enough memory for state");
|
|
lua_pushcfunction(L,&pmain);
|
|
lua_pushinteger(L,argc);
|
|
lua_pushlightuserdata(L,argv);
|
|
if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
|
|
lua_close(L);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
** $Id: print.c,v 1.66 2010/10/26 09:07:52 lhf Exp $
|
|
** print bytecodes
|
|
** See Copyright Notice in lua.h
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
|
|
#define luac_c
|
|
#define LUA_CORE
|
|
|
|
#include "ldebug.h"
|
|
#include "lobject.h"
|
|
#include "lopcodes.h"
|
|
|
|
#define Sizeof(x) ((int)sizeof(x))
|
|
#define VOID(p) ((const void*)(p))
|
|
|
|
#if LUA_STANDALONE
|
|
static void PrintString(const TString* ts)
|
|
{
|
|
const char* s=getstr(ts);
|
|
size_t i,n=ts->tsv.len;
|
|
printf("%c",'"');
|
|
for (i=0; i<n; i++)
|
|
{
|
|
int c=(int)(unsigned char)s[i];
|
|
switch (c)
|
|
{
|
|
case '"': printf("\\\""); break;
|
|
case '\\': printf("\\\\"); break;
|
|
case '\a': printf("\\a"); break;
|
|
case '\b': printf("\\b"); break;
|
|
case '\f': printf("\\f"); break;
|
|
case '\n': printf("\\n"); break;
|
|
case '\r': printf("\\r"); break;
|
|
case '\t': printf("\\t"); break;
|
|
case '\v': printf("\\v"); break;
|
|
default: if (isprint(c))
|
|
printf("%c",c);
|
|
else
|
|
printf("\\%03d",c);
|
|
}
|
|
}
|
|
printf("%c",'"');
|
|
}
|
|
|
|
|
|
static void PrintConstant(const Proto* f, int i)
|
|
{
|
|
const TValue* o=&f->k[i];
|
|
switch (ttype(o))
|
|
{
|
|
case LUA_TNIL:
|
|
printf("nil");
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
printf(bvalue(o) ? "true" : "false");
|
|
break;
|
|
case LUA_TNUMBER:
|
|
printf(LUA_NUMBER_FMT,nvalue(o));
|
|
break;
|
|
case LUA_TSTRING:
|
|
PrintString(rawtsvalue(o));
|
|
break;
|
|
default: /* cannot happen */
|
|
printf("? type=%d",ttype(o));
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
|
|
|
|
#if LUA_STANDALONE
|
|
static void PrintCode(const Proto* f)
|
|
{
|
|
const Instruction* code=f->code;
|
|
int pc,n=f->sizecode;
|
|
for (pc=0; pc<n; pc++)
|
|
{
|
|
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 ax=GETARG_Ax(i);
|
|
int bx=GETARG_Bx(i);
|
|
int sbx=GETARG_sBx(i);
|
|
int line=getfuncline(f,pc);
|
|
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",a);
|
|
if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
|
|
if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
|
|
break;
|
|
case iABx:
|
|
if (getBMode(o)==OpArgK) printf("%d %d",a,-bx); else printf("%d %d",a,bx);
|
|
break;
|
|
case iAsBx:
|
|
if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
|
|
break;
|
|
case iAx:
|
|
printf("%d",-1-ax);
|
|
break;
|
|
}
|
|
switch (o)
|
|
{
|
|
case OP_LOADK:
|
|
if (bx>0) { printf("\t; "); PrintConstant(f,bx-1); }
|
|
break;
|
|
case OP_GETUPVAL:
|
|
case OP_SETUPVAL:
|
|
printf("\t; %s",UPVALNAME(b));
|
|
break;
|
|
case OP_GETTABUP:
|
|
printf("\t; %s",UPVALNAME(b));
|
|
if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
|
|
break;
|
|
case OP_SETTABUP:
|
|
printf("\t; %s",UPVALNAME(a));
|
|
if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
|
|
if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
|
|
break;
|
|
case OP_GETTABLE:
|
|
case OP_SELF:
|
|
if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
|
|
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 (ISK(b) || ISK(c))
|
|
{
|
|
printf("\t; ");
|
|
if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
|
|
printf(" ");
|
|
if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
|
|
}
|
|
break;
|
|
case OP_JMP:
|
|
case OP_FORLOOP:
|
|
case OP_FORPREP:
|
|
case OP_TFORLOOP:
|
|
printf("\t; to %d",sbx+pc+2);
|
|
break;
|
|
case OP_CLOSURE:
|
|
printf("\t; %p",VOID(f->p[bx]));
|
|
break;
|
|
case OP_SETLIST:
|
|
if (c==0) printf("\t; %d",(int)code[++pc]);
|
|
else printf("\t; %d",c);
|
|
break;
|
|
case OP_EXTRAARG:
|
|
printf("\t; "); PrintConstant(f,ax);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define SS(x) ((x==1)?"":"s")
|
|
#define S(x) (int)(x),SS(x)
|
|
|
|
#if LUA_STANDALONE
|
|
static void PrintHeader(const Proto* f)
|
|
{
|
|
const char* s=f->source ? getstr(f->source) : "=?";
|
|
if (*s=='@' || *s=='=')
|
|
s++;
|
|
else if (*s==LUA_SIGNATURE[0])
|
|
s="(bstring)";
|
|
else
|
|
s="(string)";
|
|
printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
|
|
(f->linedefined==0)?"main":"function",s,
|
|
f->linedefined,f->lastlinedefined,
|
|
S(f->sizecode),VOID(f));
|
|
printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
|
|
(int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
|
|
S(f->maxstacksize),S(f->sizeupvalues));
|
|
printf("%d local%s, %d constant%s, %d function%s\n",
|
|
S(f->sizelocvars),S(f->sizek),S(f->sizep));
|
|
}
|
|
|
|
static void PrintDebug(const Proto* f)
|
|
{
|
|
int i,n;
|
|
n=f->sizek;
|
|
printf("constants (%d) for %p:\n",n,VOID(f));
|
|
for (i=0; i<n; i++)
|
|
{
|
|
printf("\t%d\t",i+1);
|
|
PrintConstant(f,i);
|
|
printf("\n");
|
|
}
|
|
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+1,f->locvars[i].endpc+1);
|
|
}
|
|
n=f->sizeupvalues;
|
|
printf("upvalues (%d) for %p:\n",n,VOID(f));
|
|
for (i=0; i<n; i++)
|
|
{
|
|
printf("\t%d\t%s\t%d\t%d\n",
|
|
i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
|
|
}
|
|
}
|
|
|
|
static void PrintFunction(const Proto* f, int full)
|
|
{
|
|
int i,n=f->sizep;
|
|
PrintHeader(f);
|
|
PrintCode(f);
|
|
if (full) PrintDebug(f);
|
|
for (i=0; i<n; i++) PrintFunction(f->p[i],full);
|
|
}
|
|
#endif
|