Skip to content

Instantly share code, notes, and snippets.

@xebecnan
Last active October 26, 2022 22:12
Show Gist options
  • Save xebecnan/efa0b60d70e2dbf49b8a to your computer and use it in GitHub Desktop.
Save xebecnan/efa0b60d70e2dbf49b8a to your computer and use it in GitHub Desktop.
lua5.3 support load x32 bytecode on x64
typedef struct {
lua_State *L;
ZIO *Z;
Mbuffer *b;
const char *name;
lu_byte load_size_t_size;
lu_byte load_size_t_offset;
} LoadState;
typedef union {
lua_Integer a;
lu_byte b[sizeof(lua_Integer)];
} IntOrBytes;
#define ST_SIZE sizeof(size_t)
/* ... */
static size_t LoadSize(LoadState* S) {
union {
lu_byte b[ST_SIZE];
size_t sz;
} v;
memset(&v, 0, sizeof(v));
LoadBlock(S, &v.b[S->load_size_t_offset], S->load_size_t_size);
return v.sz;
}
static TString *LoadString (LoadState *S) {
size_t size = LoadByte(S);
if (size == 0xFF) {
/* LoadVar(S, size); */
size = LoadSize(S);
}
if (size == 0)
return NULL;
else {
char *s = luaZ_openspace(S->L, S->b, --size);
LoadVector(S, s, size);
return luaS_newlstr(S->L, s, size);
}
}
/* ... */
static void checkHeader (LoadState *S) {
checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */
if (LoadByte(S) != LUAC_VERSION)
error(S, "version mismatch in");
if (LoadByte(S) != LUAC_FORMAT)
error(S, "format mismatch in");
checkliteral(S, LUAC_DATA, "corrupted");
checksize(S, int);
/* supprt run x32 bytes on x64 arch */
/* checksize(S, size_t); */
S->load_size_t_size = LoadByte(S);
checksize(S, Instruction);
checksize(S, lua_Integer);
checksize(S, lua_Number);
/* supprt run x32 bytes on x64 arch */
IntOrBytes i = (IntOrBytes)LoadInteger(S);
lu_byte b = (lu_byte)LUAC_INT;
int is_little_endian = (i.b[0] == b) ? 1 : 0;
S->load_size_t_offset = is_little_endian ? 0 : (ST_SIZE - S->load_size_t_size);
if (i.a != LUAC_INT)
error(S, "endianness mismatch in");
if (LoadNumber(S) != LUAC_NUM)
error(S, "float format mismatch in");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment