Mercurial > vba-clojure
view src/lua/lundump.c @ 96:cb487c4ce5c0
added write-memory!, which allows me to write any value to the
gameboy's memory-mapped rom or ram.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 11 Mar 2012 23:27:19 -0500 |
parents | 27763b933818 |
children |
line wrap: on
line source
1 /*2 ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $3 ** load precompiled Lua chunks4 ** See Copyright Notice in lua.h5 */7 #include <string.h>9 #define lundump_c10 #define LUA_CORE12 #include "lua.h"14 #include "ldebug.h"15 #include "ldo.h"16 #include "lfunc.h"17 #include "lmem.h"18 #include "lobject.h"19 #include "lstring.h"20 #include "lundump.h"21 #include "lzio.h"23 typedef struct {24 lua_State* L;25 ZIO* Z;26 Mbuffer* b;27 const char* name;28 } LoadState;30 #ifdef LUAC_TRUST_BINARIES31 #define IF(c,s)32 #define error(S,s)33 #else34 #define IF(c,s) if (c) error(S,s)36 static void error(LoadState* S, const char* why)37 {38 luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);39 luaD_throw(S->L,LUA_ERRSYNTAX);40 }41 #endif43 #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))44 #define LoadByte(S) (lu_byte)LoadChar(S)45 #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))46 #define LoadVector(S,b,n,size) LoadMem(S,b,n,size)48 static void LoadBlock(LoadState* S, void* b, size_t size)49 {50 size_t r=luaZ_read(S->Z,b,size);51 IF (r!=0, "unexpected end");52 }54 static int LoadChar(LoadState* S)55 {56 char x;57 LoadVar(S,x);58 return x;59 }61 static int LoadInt(LoadState* S)62 {63 int x;64 LoadVar(S,x);65 IF (x<0, "bad integer");66 return x;67 }69 static lua_Number LoadNumber(LoadState* S)70 {71 lua_Number x;72 LoadVar(S,x);73 return x;74 }76 static TString* LoadString(LoadState* S)77 {78 size_t size;79 LoadVar(S,size);80 if (size==0)81 return NULL;82 else83 {84 char* s=luaZ_openspace(S->L,S->b,size);85 LoadBlock(S,s,size);86 return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */87 }88 }90 static void LoadCode(LoadState* S, Proto* f)91 {92 int n=LoadInt(S);93 f->code=luaM_newvector(S->L,n,Instruction);94 f->sizecode=n;95 LoadVector(S,f->code,n,sizeof(Instruction));96 }98 static Proto* LoadFunction(LoadState* S, TString* p);100 static void LoadConstants(LoadState* S, Proto* f)101 {102 int i,n;103 n=LoadInt(S);104 f->k=luaM_newvector(S->L,n,TValue);105 f->sizek=n;106 for (i=0; i<n; i++) setnilvalue(&f->k[i]);107 for (i=0; i<n; i++)108 {109 TValue* o=&f->k[i];110 int t=LoadChar(S);111 switch (t)112 {113 case LUA_TNIL:114 setnilvalue(o);115 break;116 case LUA_TBOOLEAN:117 setbvalue(o,LoadChar(S)!=0);118 break;119 case LUA_TNUMBER:120 setnvalue(o,LoadNumber(S));121 break;122 case LUA_TSTRING:123 setsvalue2n(S->L,o,LoadString(S));124 break;125 default:126 error(S,"bad constant");127 break;128 }129 }130 n=LoadInt(S);131 f->p=luaM_newvector(S->L,n,Proto*);132 f->sizep=n;133 for (i=0; i<n; i++) f->p[i]=NULL;134 for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);135 }137 static void LoadDebug(LoadState* S, Proto* f)138 {139 int i,n;140 n=LoadInt(S);141 f->lineinfo=luaM_newvector(S->L,n,int);142 f->sizelineinfo=n;143 LoadVector(S,f->lineinfo,n,sizeof(int));144 n=LoadInt(S);145 f->locvars=luaM_newvector(S->L,n,LocVar);146 f->sizelocvars=n;147 for (i=0; i<n; i++) f->locvars[i].varname=NULL;148 for (i=0; i<n; i++)149 {150 f->locvars[i].varname=LoadString(S);151 f->locvars[i].startpc=LoadInt(S);152 f->locvars[i].endpc=LoadInt(S);153 }154 n=LoadInt(S);155 f->upvalues=luaM_newvector(S->L,n,TString*);156 f->sizeupvalues=n;157 for (i=0; i<n; i++) f->upvalues[i]=NULL;158 for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);159 }161 static Proto* LoadFunction(LoadState* S, TString* p)162 {163 Proto* f;164 if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");165 f=luaF_newproto(S->L);166 setptvalue2s(S->L,S->L->top,f); incr_top(S->L);167 f->source=LoadString(S); if (f->source==NULL) f->source=p;168 f->linedefined=LoadInt(S);169 f->lastlinedefined=LoadInt(S);170 f->nups=LoadByte(S);171 f->numparams=LoadByte(S);172 f->is_vararg=LoadByte(S);173 f->maxstacksize=LoadByte(S);174 LoadCode(S,f);175 LoadConstants(S,f);176 LoadDebug(S,f);177 IF (!luaG_checkcode(f), "bad code");178 S->L->top--;179 S->L->nCcalls--;180 return f;181 }183 static void LoadHeader(LoadState* S)184 {185 char h[LUAC_HEADERSIZE];186 char s[LUAC_HEADERSIZE];187 luaU_header(h);188 LoadBlock(S,s,LUAC_HEADERSIZE);189 IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");190 }192 /*193 ** load precompiled chunk194 */195 Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)196 {197 LoadState S;198 if (*name=='@' || *name=='=')199 S.name=name+1;200 else if (*name==LUA_SIGNATURE[0])201 S.name="binary string";202 else203 S.name=name;204 S.L=L;205 S.Z=Z;206 S.b=buff;207 LoadHeader(&S);208 return LoadFunction(&S,luaS_newliteral(L,"=?"));209 }211 /*212 * make header213 */214 void luaU_header (char* h)215 {216 int x=1;217 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);218 h+=sizeof(LUA_SIGNATURE)-1;219 *h++=(char)LUAC_VERSION;220 *h++=(char)LUAC_FORMAT;221 *h++=(char)*(char*)&x; /* endianness */222 *h++=(char)sizeof(int);223 *h++=(char)sizeof(size_t);224 *h++=(char)sizeof(Instruction);225 *h++=(char)sizeof(lua_Number);226 *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */227 }