Browse Source

module for dumping chunks

Roberto Ierusalimschy 23 years ago
parent
commit
de00d0d0ad
1 changed files with 158 additions and 0 deletions
  1. 158 0
      ldump.c

+ 158 - 0
ldump.c

@@ -0,0 +1,158 @@
+/*
+** $Id: dump.c,v 1.37 2002/08/07 00:36:03 lhf Exp lhf $
+** save bytecodes
+** See Copyright Notice in lua.h
+*/
+
+#include <stddef.h>
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lundump.h"
+
+#define DumpVector(b,n,size,D)	DumpBlock(b,(n)*(size),D)
+#define DumpLiteral(s,D)	DumpBlock("" s,(sizeof(s))-1,D)
+
+typedef struct {
+ lua_State *L;
+ lua_Chunkwriter write;
+ void *data;
+} DumpState;
+
+
+static void DumpBlock(const void *b, size_t size, DumpState* D)
+{
+ lua_unlock(D->L);
+ (*D->write)(D->L,b,size,D->data);
+ lua_lock(D->L);
+}
+
+static void DumpByte(int y, DumpState* D)
+{
+ char x=(char)y;
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpInt(int x, DumpState* D)
+{
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpSize(size_t x, DumpState* D)
+{
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpNumber(lua_Number x, DumpState* D)
+{
+ DumpBlock(&x,sizeof(x),D);
+}
+
+static void DumpString(TString* s, DumpState* D)
+{
+ if (s==NULL || getstr(s)==NULL)
+  DumpSize(0,D);
+ else
+ {
+  size_t size=s->tsv.len+1;		/* include trailing '\0' */
+  DumpSize(size,D);
+  DumpBlock(getstr(s),size,D);
+ }
+}
+
+static void DumpCode(const Proto* f, DumpState* D)
+{
+ DumpInt(f->sizecode,D);
+ DumpVector(f->code,f->sizecode,sizeof(*f->code),D);
+}
+
+static void DumpLocals(const Proto* f, DumpState* D)
+{
+ int i,n=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);
+ }
+}
+
+static void DumpLines(const Proto* f, DumpState* D)
+{
+ DumpInt(f->sizelineinfo,D);
+ DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
+}
+
+static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
+
+static void DumpConstants(const Proto* f, DumpState* D)
+{
+ int i,n;
+ DumpInt(n=f->sizek,D);
+ for (i=0; i<n; i++)
+ {
+  const TObject* o=&f->k[i];
+  DumpByte(ttype(o),D);
+  switch (ttype(o))
+  {
+   case LUA_TNUMBER:
+	DumpNumber(nvalue(o),D);
+	break;
+   case LUA_TSTRING:
+	DumpString(tsvalue(o),D);
+	break;
+   case LUA_TNIL:
+	break;
+   default:
+	lua_assert(0);			/* cannot happen */
+	break;
+  }
+ }
+ DumpInt(n=f->sizep,D);
+ for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
+}
+
+static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
+{
+ DumpString((f->source==p) ? NULL : f->source,D);
+ DumpInt(f->lineDefined,D);
+ DumpByte(f->nupvalues,D);
+ DumpByte(f->numparams,D);
+ DumpByte(f->is_vararg,D);
+ DumpByte(f->maxstacksize,D);
+ DumpLocals(f,D);
+ DumpLines(f,D);
+ DumpConstants(f,D);
+ DumpCode(f,D);
+}
+
+static void DumpHeader(DumpState* D)
+{
+ DumpLiteral(LUA_SIGNATURE,D);
+ DumpByte(VERSION,D);
+ DumpByte(luaU_endianness(),D);
+ DumpByte(sizeof(int),D);
+ DumpByte(sizeof(size_t),D);
+ DumpByte(sizeof(Instruction),D);
+ DumpByte(SIZE_OP,D);
+ DumpByte(SIZE_A,D);
+ DumpByte(SIZE_B,D);
+ DumpByte(SIZE_C,D);
+ DumpByte(sizeof(lua_Number),D);
+ DumpNumber(TEST_NUMBER,D);
+}
+
+void luaU_dump(lua_State *L, const Proto* Main, lua_Chunkwriter w, void* data)
+{
+ DumpState D;
+ D.L=L;
+ D.write=w;
+ D.data=data;
+ DumpHeader(&D);
+ DumpFunction(Main,NULL,&D);
+}
+