Imported from ../lua-3.1.tar.gz.
[lua.git] / src / luac / dump.c
blobce9551e689b874a041566b7060962f8ebc14bb98
1 /*
2 ** $Id: dump.c,v 1.11 1998/07/12 00:17:37 lhf Exp $
3 ** save bytecodes to file
4 ** See Copyright Notice in lua.h
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "luac.h"
11 #define NotWord(x) ((unsigned short)x!=x)
12 #define DumpBlock(b,size,D) fwrite(b,size,1,D)
13 #define DumpNative(t,D) DumpBlock(&t,sizeof(t),D)
15 static void DumpWord(int i, FILE* D)
17 int hi= 0x0000FF & (i>>8);
18 int lo= 0x0000FF & i;
19 fputc(hi,D);
20 fputc(lo,D);
23 static void DumpLong(long i, FILE* D)
25 int hi= 0x00FFFF & (i>>16);
26 int lo= 0x00FFFF & i;
27 DumpWord(hi,D);
28 DumpWord(lo,D);
31 #if ID_NUMBER==ID_REAL4
32 /* LUA_NUMBER */
33 /* assumes sizeof(long)==4 and sizeof(float)==4 (IEEE) */
34 static void DumpFloat(float f, FILE* D)
36 long l=*(long*)&f;
37 DumpLong(l,D);
39 #endif
41 #if ID_NUMBER==ID_REAL8
42 /* LUA_NUMBER */
43 /* assumes sizeof(long)==4 and sizeof(double)==8 (IEEE) */
44 static void DumpDouble(double f, FILE* D)
46 long* l=(long*)&f;
47 int x=1;
48 if (*(char*)&x==1) /* little-endian */
50 DumpLong(l[1],D);
51 DumpLong(l[0],D);
53 else /* big-endian */
55 DumpLong(l[0],D);
56 DumpLong(l[1],D);
59 #endif
61 static void DumpCode(TProtoFunc* tf, FILE* D)
63 int size=CodeSize(tf);
64 if (NotWord(size))
65 fprintf(stderr,"luac: warning: "
66 "\"%s\":%d code too long for 16-bit machines (%d bytes)\n",
67 fileName(tf),tf->lineDefined,size);
68 DumpLong(size,D);
69 DumpBlock(tf->code,size,D);
72 static void DumpString(char* s, int size, FILE* D)
74 if (s==NULL)
75 DumpWord(0,D);
76 else
78 if (NotWord(size))
79 luaL_verror("string too long (%d bytes): \"%.32s...\"",size,s);
80 DumpWord(size,D);
81 DumpBlock(s,size,D);
85 static void DumpTString(TaggedString* s, FILE* D)
87 if (s==NULL) DumpString(NULL,0,D); else DumpString(s->str,s->u.s.len+1,D);
90 static void DumpLocals(TProtoFunc* tf, FILE* D)
92 int n;
93 LocVar* lv;
94 for (n=0,lv=tf->locvars; lv && lv->line>=0; lv++) ++n;
95 DumpWord(n,D);
96 for (lv=tf->locvars; lv && lv->line>=0; lv++)
98 DumpWord(lv->line,D);
99 DumpTString(lv->varname,D);
103 static void DumpFunction(TProtoFunc* tf, FILE* D);
105 static void DumpConstants(TProtoFunc* tf, FILE* D)
107 int i,n=tf->nconsts;
108 DumpWord(n,D);
109 for (i=0; i<n; i++)
111 TObject* o=tf->consts+i;
112 fputc(-ttype(o),D);
113 switch (ttype(o))
115 case LUA_T_NUMBER:
116 DumpNumber(nvalue(o),D);
117 break;
118 case LUA_T_STRING:
119 DumpTString(tsvalue(o),D);
120 break;
121 case LUA_T_PROTO:
122 DumpFunction(tfvalue(o),D);
123 break;
124 case LUA_T_NIL:
125 break;
126 default: /* cannot happen */
127 luaL_verror("cannot dump constant #%d: type=%d [%s]",
128 i,ttype(o),luaO_typename(o));
129 break;
134 static void DumpFunction(TProtoFunc* tf, FILE* D)
136 DumpWord(tf->lineDefined,D);
137 DumpTString(tf->fileName,D);
138 DumpCode(tf,D);
139 DumpLocals(tf,D);
140 DumpConstants(tf,D);
143 static void DumpHeader(TProtoFunc* Main, FILE* D)
145 real t=TEST_NUMBER;
146 fputc(ID_CHUNK,D);
147 fputs(SIGNATURE,D);
148 fputc(VERSION,D);
149 fputc(ID_NUMBER,D);
150 fputc(sizeof(t),D);
151 DumpNumber(t,D);
154 void DumpChunk(TProtoFunc* Main, FILE* D)
156 DumpHeader(Main,D);
157 DumpFunction(Main,D);