mirror of
https://github.com/lua/lua
synced 2024-11-25 22:29:39 +03:00
063d4e4543
This is the first commit for the branch Lua 5.3. All source files were copied from the official distribution of 5.3.5 in the Lua site. The test files are the same of 5.3.4. The manual came from the previous RCS repository, revision 1.167.1.2.
216 lines
4.4 KiB
C
216 lines
4.4 KiB
C
/*
|
|
** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $
|
|
** save precompiled Lua chunks
|
|
** See Copyright Notice in lua.h
|
|
*/
|
|
|
|
#define ldump_c
|
|
#define LUA_CORE
|
|
|
|
#include "lprefix.h"
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
#include "lua.h"
|
|
|
|
#include "lobject.h"
|
|
#include "lstate.h"
|
|
#include "lundump.h"
|
|
|
|
|
|
typedef struct {
|
|
lua_State *L;
|
|
lua_Writer writer;
|
|
void *data;
|
|
int strip;
|
|
int status;
|
|
} DumpState;
|
|
|
|
|
|
/*
|
|
** All high-level dumps go through DumpVector; you can change it to
|
|
** change the endianness of the result
|
|
*/
|
|
#define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D)
|
|
|
|
#define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D)
|
|
|
|
|
|
static void DumpBlock (const void *b, size_t size, DumpState *D) {
|
|
if (D->status == 0 && size > 0) {
|
|
lua_unlock(D->L);
|
|
D->status = (*D->writer)(D->L, b, size, D->data);
|
|
lua_lock(D->L);
|
|
}
|
|
}
|
|
|
|
|
|
#define DumpVar(x,D) DumpVector(&x,1,D)
|
|
|
|
|
|
static void DumpByte (int y, DumpState *D) {
|
|
lu_byte x = (lu_byte)y;
|
|
DumpVar(x, D);
|
|
}
|
|
|
|
|
|
static void DumpInt (int x, DumpState *D) {
|
|
DumpVar(x, D);
|
|
}
|
|
|
|
|
|
static void DumpNumber (lua_Number x, DumpState *D) {
|
|
DumpVar(x, D);
|
|
}
|
|
|
|
|
|
static void DumpInteger (lua_Integer x, DumpState *D) {
|
|
DumpVar(x, D);
|
|
}
|
|
|
|
|
|
static void DumpString (const TString *s, DumpState *D) {
|
|
if (s == NULL)
|
|
DumpByte(0, D);
|
|
else {
|
|
size_t size = tsslen(s) + 1; /* include trailing '\0' */
|
|
const char *str = getstr(s);
|
|
if (size < 0xFF)
|
|
DumpByte(cast_int(size), D);
|
|
else {
|
|
DumpByte(0xFF, D);
|
|
DumpVar(size, D);
|
|
}
|
|
DumpVector(str, size - 1, D); /* no need to save '\0' */
|
|
}
|
|
}
|
|
|
|
|
|
static void DumpCode (const Proto *f, DumpState *D) {
|
|
DumpInt(f->sizecode, D);
|
|
DumpVector(f->code, f->sizecode, D);
|
|
}
|
|
|
|
|
|
static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
|
|
|
|
static void DumpConstants (const Proto *f, DumpState *D) {
|
|
int i;
|
|
int n = f->sizek;
|
|
DumpInt(n, D);
|
|
for (i = 0; i < n; i++) {
|
|
const TValue *o = &f->k[i];
|
|
DumpByte(ttype(o), D);
|
|
switch (ttype(o)) {
|
|
case LUA_TNIL:
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
DumpByte(bvalue(o), D);
|
|
break;
|
|
case LUA_TNUMFLT:
|
|
DumpNumber(fltvalue(o), D);
|
|
break;
|
|
case LUA_TNUMINT:
|
|
DumpInteger(ivalue(o), D);
|
|
break;
|
|
case LUA_TSHRSTR:
|
|
case LUA_TLNGSTR:
|
|
DumpString(tsvalue(o), D);
|
|
break;
|
|
default:
|
|
lua_assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void DumpProtos (const Proto *f, DumpState *D) {
|
|
int i;
|
|
int n = f->sizep;
|
|
DumpInt(n, D);
|
|
for (i = 0; i < n; i++)
|
|
DumpFunction(f->p[i], f->source, D);
|
|
}
|
|
|
|
|
|
static void DumpUpvalues (const Proto *f, DumpState *D) {
|
|
int i, n = f->sizeupvalues;
|
|
DumpInt(n, D);
|
|
for (i = 0; i < n; i++) {
|
|
DumpByte(f->upvalues[i].instack, D);
|
|
DumpByte(f->upvalues[i].idx, D);
|
|
}
|
|
}
|
|
|
|
|
|
static void DumpDebug (const Proto *f, DumpState *D) {
|
|
int i, n;
|
|
n = (D->strip) ? 0 : f->sizelineinfo;
|
|
DumpInt(n, D);
|
|
DumpVector(f->lineinfo, n, D);
|
|
n = (D->strip) ? 0 : f->sizelocvars;
|
|
DumpInt(n, D);
|
|
for (i = 0; i < n; i++) {
|
|
DumpString(f->locvars[i].varname, D);
|
|
DumpInt(f->locvars[i].startpc, D);
|
|
DumpInt(f->locvars[i].endpc, D);
|
|
}
|
|
n = (D->strip) ? 0 : f->sizeupvalues;
|
|
DumpInt(n, D);
|
|
for (i = 0; i < n; i++)
|
|
DumpString(f->upvalues[i].name, D);
|
|
}
|
|
|
|
|
|
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
|
|
if (D->strip || f->source == psource)
|
|
DumpString(NULL, D); /* no debug info or same source as its parent */
|
|
else
|
|
DumpString(f->source, D);
|
|
DumpInt(f->linedefined, D);
|
|
DumpInt(f->lastlinedefined, D);
|
|
DumpByte(f->numparams, D);
|
|
DumpByte(f->is_vararg, D);
|
|
DumpByte(f->maxstacksize, D);
|
|
DumpCode(f, D);
|
|
DumpConstants(f, D);
|
|
DumpUpvalues(f, D);
|
|
DumpProtos(f, D);
|
|
DumpDebug(f, D);
|
|
}
|
|
|
|
|
|
static void DumpHeader (DumpState *D) {
|
|
DumpLiteral(LUA_SIGNATURE, D);
|
|
DumpByte(LUAC_VERSION, D);
|
|
DumpByte(LUAC_FORMAT, D);
|
|
DumpLiteral(LUAC_DATA, D);
|
|
DumpByte(sizeof(int), D);
|
|
DumpByte(sizeof(size_t), D);
|
|
DumpByte(sizeof(Instruction), D);
|
|
DumpByte(sizeof(lua_Integer), D);
|
|
DumpByte(sizeof(lua_Number), D);
|
|
DumpInteger(LUAC_INT, D);
|
|
DumpNumber(LUAC_NUM, D);
|
|
}
|
|
|
|
|
|
/*
|
|
** dump Lua function as precompiled chunk
|
|
*/
|
|
int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
|
|
int strip) {
|
|
DumpState D;
|
|
D.L = L;
|
|
D.writer = w;
|
|
D.data = data;
|
|
D.strip = strip;
|
|
D.status = 0;
|
|
DumpHeader(&D);
|
|
DumpByte(f->sizeupvalues, &D);
|
|
DumpFunction(f, NULL, &D);
|
|
return D.status;
|
|
}
|
|
|