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)
237 lines
4.9 KiB
C
237 lines
4.9 KiB
C
/*
|
|
** $Id: lundump.c,v 1.68 2010/10/26 00:23:46 lhf Exp $
|
|
** load precompiled Lua chunks
|
|
** See Copyright Notice in lua.h
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#define lundump_c
|
|
#define LUA_CORE
|
|
|
|
#include "lua.h"
|
|
|
|
#include "ldebug.h"
|
|
#include "ldo.h"
|
|
#include "lfunc.h"
|
|
#include "lmem.h"
|
|
#include "lobject.h"
|
|
#include "lstring.h"
|
|
#include "lundump.h"
|
|
#include "lzio.h"
|
|
|
|
typedef struct {
|
|
lua_State* L;
|
|
ZIO* Z;
|
|
Mbuffer* b;
|
|
const char* name;
|
|
} LoadState;
|
|
|
|
static void error(LoadState* S, const char* why)
|
|
{
|
|
luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
|
|
luaD_throw(S->L,LUA_ERRSYNTAX);
|
|
}
|
|
|
|
#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
|
|
#define LoadByte(S) (lu_byte)LoadChar(S)
|
|
#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
|
|
#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
|
|
|
|
static void LoadBlock(LoadState* S, void* b, size_t size)
|
|
{
|
|
if (luaZ_read(S->Z,b,size)!=0) error(S,"corrupted");
|
|
}
|
|
|
|
static int LoadChar(LoadState* S)
|
|
{
|
|
char x;
|
|
LoadVar(S,x);
|
|
return x;
|
|
}
|
|
|
|
static int LoadInt(LoadState* S)
|
|
{
|
|
int x;
|
|
LoadVar(S,x);
|
|
return x;
|
|
}
|
|
|
|
static lua_Number LoadNumber(LoadState* S)
|
|
{
|
|
lua_Number x;
|
|
LoadVar(S,x);
|
|
return x;
|
|
}
|
|
|
|
static TString* LoadString(LoadState* S)
|
|
{
|
|
size_t size;
|
|
LoadVar(S,size);
|
|
if (size==0)
|
|
return NULL;
|
|
else
|
|
{
|
|
char* s=luaZ_openspace(S->L,S->b,size);
|
|
LoadBlock(S,s,size);
|
|
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
|
|
}
|
|
}
|
|
|
|
static void LoadCode(LoadState* S, Proto* f)
|
|
{
|
|
int n=LoadInt(S);
|
|
f->code=luaM_newvector(S->L,n,Instruction);
|
|
f->sizecode=n;
|
|
LoadVector(S,f->code,n,sizeof(Instruction));
|
|
}
|
|
|
|
static Proto* LoadFunction(LoadState* S);
|
|
|
|
static void LoadConstants(LoadState* S, Proto* f)
|
|
{
|
|
int i,n;
|
|
n=LoadInt(S);
|
|
f->k=luaM_newvector(S->L,n,TValue);
|
|
f->sizek=n;
|
|
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
|
|
for (i=0; i<n; i++)
|
|
{
|
|
TValue* o=&f->k[i];
|
|
int t=LoadChar(S);
|
|
switch (t)
|
|
{
|
|
case LUA_TNIL:
|
|
setnilvalue(o);
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
setbvalue(o,LoadChar(S));
|
|
break;
|
|
case LUA_TNUMBER:
|
|
setnvalue(o,LoadNumber(S));
|
|
break;
|
|
case LUA_TSTRING:
|
|
setsvalue2n(S->L,o,LoadString(S));
|
|
break;
|
|
}
|
|
}
|
|
n=LoadInt(S);
|
|
f->p=luaM_newvector(S->L,n,Proto*);
|
|
f->sizep=n;
|
|
for (i=0; i<n; i++) f->p[i]=NULL;
|
|
for (i=0; i<n; i++) f->p[i]=LoadFunction(S);
|
|
}
|
|
|
|
static void LoadUpvalues(LoadState* S, Proto* f)
|
|
{
|
|
int i,n;
|
|
n=LoadInt(S);
|
|
f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
|
|
f->sizeupvalues=n;
|
|
for (i=0; i<n; i++) f->upvalues[i].name=NULL;
|
|
for (i=0; i<n; i++)
|
|
{
|
|
f->upvalues[i].instack=LoadChar(S);
|
|
f->upvalues[i].idx=LoadChar(S);
|
|
}
|
|
}
|
|
|
|
static void LoadDebug(LoadState* S, Proto* f)
|
|
{
|
|
int i,n;
|
|
f->source=LoadString(S);
|
|
n=LoadInt(S);
|
|
f->lineinfo=luaM_newvector(S->L,n,int);
|
|
f->sizelineinfo=n;
|
|
LoadVector(S,f->lineinfo,n,sizeof(int));
|
|
n=LoadInt(S);
|
|
f->locvars=luaM_newvector(S->L,n,LocVar);
|
|
f->sizelocvars=n;
|
|
for (i=0; i<n; i++) f->locvars[i].varname=NULL;
|
|
for (i=0; i<n; i++)
|
|
{
|
|
f->locvars[i].varname=LoadString(S);
|
|
f->locvars[i].startpc=LoadInt(S);
|
|
f->locvars[i].endpc=LoadInt(S);
|
|
}
|
|
n=LoadInt(S);
|
|
for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
|
|
}
|
|
|
|
static Proto* LoadFunction(LoadState* S)
|
|
{
|
|
Proto* f=luaF_newproto(S->L);
|
|
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
|
|
f->linedefined=LoadInt(S);
|
|
f->lastlinedefined=LoadInt(S);
|
|
f->numparams=LoadByte(S);
|
|
f->is_vararg=LoadByte(S);
|
|
f->maxstacksize=LoadByte(S);
|
|
LoadCode(S,f);
|
|
LoadConstants(S,f);
|
|
LoadUpvalues(S,f);
|
|
LoadDebug(S,f);
|
|
S->L->top--;
|
|
return f;
|
|
}
|
|
|
|
/* the code below must be consistent with the code in luaU_header */
|
|
#define N0 LUAC_HEADERSIZE
|
|
#define N1 (sizeof(LUA_SIGNATURE)-1)
|
|
#define N2 N1+2
|
|
#define N3 N2+6
|
|
|
|
static void LoadHeader(LoadState* S)
|
|
{
|
|
char h[LUAC_HEADERSIZE];
|
|
char s[LUAC_HEADERSIZE];
|
|
luaU_header(h);
|
|
LoadBlock(S,s,LUAC_HEADERSIZE);
|
|
if (memcmp(h,s,N0)==0) return;
|
|
if (memcmp(h,s,N1)!=0) error(S,"not a");
|
|
if (memcmp(h,s,N2)!=0) error(S,"version mismatch in");
|
|
if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted");
|
|
}
|
|
|
|
/*
|
|
** load precompiled chunk
|
|
*/
|
|
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
|
|
{
|
|
LoadState S;
|
|
if (*name=='@' || *name=='=')
|
|
S.name=name+1;
|
|
else if (*name==LUA_SIGNATURE[0])
|
|
S.name="binary string";
|
|
else
|
|
S.name=name;
|
|
S.L=L;
|
|
S.Z=Z;
|
|
S.b=buff;
|
|
LoadHeader(&S);
|
|
return LoadFunction(&S);
|
|
}
|
|
|
|
/* data to catch conversion errors */
|
|
#define TAIL "\x19\x93\r\n\x1a\n"
|
|
|
|
/*
|
|
* make header for precompiled chunks
|
|
* if you make any changes in the code below or in LUA_SIGNATURE in lua.h,
|
|
* be sure to update LoadHeader above and LUAC_HEADERSIZE in lundump.h
|
|
*/
|
|
void luaU_header (char* h)
|
|
{
|
|
int x=1;
|
|
memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
|
|
h+=sizeof(LUA_SIGNATURE)-1;
|
|
*h++=(char)0x52; /* Lua 5.2 */
|
|
*h++=(char)0; /* the official format */
|
|
*h++=(char)*(char*)&x; /* endianness */
|
|
*h++=(char)sizeof(int);
|
|
*h++=(char)sizeof(size_t);
|
|
*h++=(char)sizeof(Instruction);
|
|
*h++=(char)sizeof(lua_Number);
|
|
*h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
|
|
memcpy(h,TAIL,sizeof(TAIL)-1);
|
|
}
|