ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

lundump.cpp

Go to the documentation of this file.
00001 /*
00002 ** load bytecodes from files
00003 ** See Copyright Notice in lua.h
00004 */
00005 
00006 #include "engines/grim/lua/lauxlib.h"
00007 #include "engines/grim/lua/lfunc.h"
00008 #include "engines/grim/lua/lmem.h"
00009 #include "engines/grim/lua/lstring.h"
00010 #include "engines/grim/lua/lundump.h"
00011 
00012 namespace Grim {
00013 
00014 static float conv_float(const byte *data) {
00015     float f;
00016     byte *fdata = (byte *)(&f);
00017     fdata[0] = data[3];
00018     fdata[1] = data[2];
00019     fdata[2] = data[1];
00020     fdata[3] = data[0];
00021     return f;
00022 }
00023 
00024 static void unexpectedEOZ(ZIO *Z) {
00025     luaL_verror("unexpected end of file in %s", zname(Z));
00026 }
00027 
00028 static int32 ezgetc(ZIO *Z) {
00029     int32 c = zgetc(Z);
00030     if (c == EOZ)
00031         unexpectedEOZ(Z);
00032     return c;
00033 }
00034 
00035 static void ezread(ZIO *Z, void *b, int32 n) {
00036     int32 r = zread(Z, b, n);
00037     if (r)
00038         unexpectedEOZ(Z);
00039 }
00040 
00041 static uint16 LoadWord(ZIO *Z) {
00042     uint16 hi = ezgetc(Z);
00043     uint16 lo = ezgetc(Z);
00044     return (hi << 8) | lo;
00045 }
00046 
00047 static void *LoadBlock(int size, ZIO *Z) {
00048     void *b = luaM_malloc(size);
00049     ezread(Z, b, size);
00050     return b;
00051 }
00052 
00053 static uint32 LoadSize(ZIO *Z) {
00054     uint32 hi = LoadWord(Z);
00055     uint32 lo = LoadWord(Z);
00056     return (hi << 16) | lo;
00057 }
00058 
00059 static float LoadFloat(ZIO *Z) {
00060     uint32 l = LoadSize(Z);
00061     return conv_float((const byte *)&l);
00062 }
00063 
00064 static TaggedString *LoadTString(ZIO *Z) {
00065     int32 size = LoadWord(Z);
00066     int32 i;
00067 
00068     if (size == 0)
00069         return nullptr;
00070     else {
00071         char *s = luaL_openspace(size);
00072         ezread(Z, s, size);
00073         for (i = 0; i < size; i++)
00074             s[i] ^= 0xff;
00075         return luaS_new(s);
00076     }
00077 }
00078 
00079 static void LoadLocals(TProtoFunc *tf, ZIO *Z) {
00080     int32 i, n = LoadWord(Z);
00081     if (n == 0)
00082         return;
00083     tf->locvars = luaM_newvector(n + 1, LocVar);
00084     for (i = 0; i < n; i++) {
00085         tf->locvars[i].line = LoadWord(Z);
00086         tf->locvars[i].varname = LoadTString(Z);
00087     }
00088     tf->locvars[i].line = -1;       // flag end of vector
00089     tf->locvars[i].varname = nullptr;
00090 }
00091 
00092 static void LoadConstants(TProtoFunc *tf, ZIO *Z) {
00093     int32 i, n = LoadWord(Z);
00094     tf->nconsts = n;
00095     if (n == 0)
00096         return;
00097     tf->consts = luaM_newvector(n, TObject);
00098     for (i = 0; i < n; i++) {
00099         TObject *o = tf->consts + i;
00100         int c = ezgetc(Z);
00101         switch (c) {
00102         case ID_NUM:
00103             ttype(o) = LUA_T_NUMBER;
00104             nvalue(o) = LoadFloat(Z);
00105             break;
00106         case ID_STR:
00107             ttype(o) = LUA_T_STRING;
00108             tsvalue(o) = LoadTString(Z);
00109             break;
00110         case ID_FUN:
00111             ttype(o) = LUA_T_PROTO;
00112             tfvalue(o) = nullptr;
00113         default:
00114             break;
00115         }
00116     }
00117 }
00118 
00119 static void LoadFunctions(TProtoFunc *tf, ZIO *Z);
00120 
00121 static TProtoFunc *LoadFunction(ZIO *Z) {
00122     TProtoFunc *tf = luaF_newproto();
00123     tf->lineDefined = LoadWord(Z);
00124     tf->fileName = LoadTString(Z);
00125     tf->code = (byte *)LoadBlock(LoadSize(Z), Z);
00126     LoadConstants(tf, Z);
00127     LoadLocals(tf, Z);
00128     LoadFunctions(tf, Z);
00129 
00130     return tf;
00131 }
00132 
00133 static void LoadFunctions(TProtoFunc *tf, ZIO *Z) {
00134     while (ezgetc(Z) == ID_FUNCTION) {
00135         int32 i = LoadWord(Z);
00136         TProtoFunc *t = LoadFunction(Z);
00137         TObject *o = tf->consts + i;
00138         tfvalue(o) = t;
00139     }
00140 }
00141 
00142 static void LoadSignature(ZIO *Z) {
00143     const char *s = SIGNATURE;
00144 
00145     while (*s && ezgetc(Z) == *s)
00146         ++s;
00147     if (*s)
00148         luaL_verror("bad signature in %s", zname(Z));
00149 }
00150 
00151 static void LoadHeader(ZIO *Z) {
00152     int32 version, sizeofR;
00153 
00154     LoadSignature(Z);
00155     version = ezgetc(Z);
00156     if (version > VERSION)
00157         luaL_verror("%s too new: version=0x%02x; expected at most 0x%02x", zname(Z), version, VERSION);
00158     if (version < VERSION)          // check last major change
00159         luaL_verror("%s too old: version=0x%02x; expected at least 0x%02x", zname(Z), version, VERSION);
00160     sizeofR = ezgetc(Z);            // test number representation
00161     if (sizeofR != sizeof(float))
00162         luaL_verror("number expected float in %s", zname(Z));
00163     ezgetc(Z);
00164     ezgetc(Z);
00165     ezgetc(Z);
00166     ezgetc(Z);
00167 }
00168 
00169 static TProtoFunc *LoadChunk(ZIO *Z) {
00170     LoadHeader(Z);
00171     return LoadFunction(Z);
00172 }
00173 
00174 /*
00175 ** load one chunk from a file or buffer
00176 ** return main if ok and NULL at EOF
00177 */
00178 TProtoFunc *luaU_undump1(ZIO *Z) {
00179     int32 c = zgetc(Z);
00180     if (c == ID_CHUNK)
00181         return LoadChunk(Z);
00182     else if (c != EOZ)
00183         luaL_verror("%s is not a Lua binary file", zname(Z));
00184     return nullptr;
00185 }
00186 
00187 } // end of namespace Grim


Generated on Sat May 25 2019 05:00:49 for ResidualVM by doxygen 1.7.1
curved edge   curved edge