Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 707 lines (572 sloc) 19.469 kB
8354436 @mimaki add file header
mimaki authored
1 /*
2 ** dump.c - mruby binary dumper (Rite binary format)
4ec6d41 rm whitespace
roco authored
3 **
8354436 @mimaki add file header
mimaki authored
4 ** See Copyright Notice in mruby.h
5 */
6
e0d6430 @mimaki add mruby sources
mimaki authored
7 #include <string.h>
8b36709 @matz move header files {irep,dump,cdump,ritehash}.h to /include/mruby
matz authored
8 #include "mruby/dump.h"
e0d6430 @mimaki add mruby sources
mimaki authored
9
10 #include "mruby/string.h"
76f7aec @matz use ENABLE/DISABLE instead of INCLUDE for configuration macro names
matz authored
11 #ifdef ENABLE_REGEXP
e0d6430 @mimaki add mruby sources
mimaki authored
12 #include "re.h"
13 #endif
8b36709 @matz move header files {irep,dump,cdump,ritehash}.h to /include/mruby
matz authored
14 #include "mruby/irep.h"
e0d6430 @mimaki add mruby sources
mimaki authored
15
16 static const unsigned char def_rite_binary_header[] =
17 RITE_FILE_IDENFIFIER
18 RITE_FILE_FORMAT_VER
19 RITE_VM_VER
20 RITE_COMPILER_TYPE
21 RITE_COMPILER_VER
22 "0000" //Binary data size
23 "00" //Number of ireps
24 "00" //Start index
25 RITE_RESERVED
26 ;
27
28 static const unsigned char def_rite_file_header[] =
29 RITE_FILE_IDENFIFIER
30 RITE_FILE_FORMAT_VER
31 RITE_VM_VER
32 RITE_COMPILER_TYPE
33 RITE_COMPILER_VER
34 "00000000" //Binary data size
35 "0000" //Number of ireps
36 "0000" //Start index
37 RITE_RESERVED
38 "0000" //CRC
39 ;
40
41 const char bin2hex[] = {
42 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
43 };
44
45 #define DUMP_SIZE(size, type) ((type == DUMP_TYPE_BIN) ? size : size * RITE_FILE_HEX_SIZE)
46
47 enum {
48 DUMP_IREP_HEADER = 0,
49 DUMP_ISEQ_BLOCK,
50 DUMP_POOL_BLOCK,
51 DUMP_SYMS_BLOCK,
52 DUMP_SECTION_NUM,
53 };
54
55 uint16_t calc_crc_16_ccitt(unsigned char*,int);
56 static inline int uint8_dump(uint8_t,char*,int);
57 static inline int uint16_dump(uint16_t,char*,int);
58 static inline int uint32_dump(uint32_t,char*,int);
59 static char* str_dump(char*,char*,uint16_t,int);
60 static uint16_t str_dump_len(char*,uint16_t, int);
61 static uint32_t get_irep_header_size(mrb_state*,mrb_irep*,int);
62 static uint32_t get_iseq_block_size(mrb_state*,mrb_irep*,int);
63 static uint32_t get_pool_block_size(mrb_state*,mrb_irep*,int);
64 static uint32_t get_syms_block_size(mrb_state*,mrb_irep*,int);
65 static uint32_t get_irep_record_size(mrb_state*,int,int);
66 static int write_irep_header(mrb_state*,mrb_irep*,char*,int);
67 static int write_iseq_block(mrb_state*,mrb_irep*,char*,int);
68 static int write_pool_block(mrb_state*,mrb_irep*,char*,int);
69 static int write_syms_block(mrb_state*,mrb_irep*,char*,int);
70 static int calc_crc_section(mrb_state*,mrb_irep*,uint16_t*,int);
71 static int write_rite_header(mrb_state*,int,char*,uint32_t);
72 static int dump_rite_header(mrb_state*,int,FILE*,uint32_t);
73 static int write_irep_record(mrb_state*,int,char*,uint32_t*,int);
74 static int dump_irep_record(mrb_state*,int,FILE*,uint32_t*);
75 static int mrb_write_irep(mrb_state*,int,char*);
76
77
78 static inline int
79 uint8_dump(unsigned char bin, char *hex, int type)
80 {
81 if (type == DUMP_TYPE_BIN) {
82 *hex = bin;
83 } else {
84 *hex++ = bin2hex[(bin >> 4) & 0x0f];
85 *hex = bin2hex[bin & 0x0f];
86 }
87 return DUMP_SIZE(sizeof(char), type);
88 }
89
90 static inline int
91 uint16_dump(uint16_t bin, char *hex, int type)
92 {
93 if (type == DUMP_TYPE_BIN) {
94 return (uint16_to_bin(bin, hex));
95 } else {
96 *hex++ = bin2hex[(bin >> 12)& 0x0f];
97 *hex++ = bin2hex[(bin >> 8) & 0x0f];
98 *hex++ = bin2hex[(bin >> 4) & 0x0f];
99 *hex = bin2hex[bin & 0x0f];
100 return DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type);
101 }
102 }
103
104 static inline int
105 uint32_dump(uint32_t bin, char *hex, int type)
106 {
107 if (type == DUMP_TYPE_BIN) {
108 return (uint32_to_bin(bin, hex));
109 } else {
110 *hex++ = bin2hex[(bin >> 28) & 0x0f];
111 *hex++ = bin2hex[(bin >> 24) & 0x0f];
112 *hex++ = bin2hex[(bin >> 20) & 0x0f];
113 *hex++ = bin2hex[(bin >> 16) & 0x0f];
114 *hex++ = bin2hex[(bin >> 12) & 0x0f];
115 *hex++ = bin2hex[(bin >> 8) & 0x0f];
116 *hex++ = bin2hex[(bin >> 4) & 0x0f];
117 *hex = bin2hex[bin & 0x0f];
118 return DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type);
119 }
120 }
121
122 static char*
123 str_dump(char *str, char *hex, uint16_t len, int type)
124 {
125 if (type == DUMP_TYPE_BIN)
126 memcpy(hex, str, len);
127 else {
128 char *src, *dst;
129
130 for (src = str, dst = hex; len > 0; src++, dst++, len--) {
131 switch (*src) {
132 case 0x07:/* BEL */ *dst++ = '\\'; *dst = 'a'; break;
133 case 0x08:/* BS */ *dst++ = '\\'; *dst = 'b'; break;
134 case 0x09:/* HT */ *dst++ = '\\'; *dst = 't'; break;
135 case 0x0A:/* LF */ *dst++ = '\\'; *dst = 'n'; break;
136 case 0x0B:/* VT */ *dst++ = '\\'; *dst = 'v'; break;
137 case 0x0C:/* FF */ *dst++ = '\\'; *dst = 'f'; break;
138 case 0x0D:/* CR */ *dst++ = '\\'; *dst = 'r'; break;
139 case 0x22:/* " */ /* fall through */
140 case 0x27:/* ' */ /* fall through */
141 // case 0x3F:/* ? */ /* fall through */
142 case 0x5C:/* \ */ /* fall through */
143 default: *dst = *src; break;
144 }
145 }
146 }
147
148 return hex;
149 }
150
151 static uint16_t
152 str_dump_len(char *str, uint16_t len, int type)
153 {
154 uint16_t dump_len = 0;
155
156 if (type == DUMP_TYPE_BIN)
157 dump_len = len;
158 else {
159 char *src;
160
161 for (src = str; len > 0; src++, len--) {
162 switch (*src) {
163 case 0x07:/* BEL */ /* fall through */
164 case 0x08:/* BS */ /* fall through */
165 case 0x09:/* HT */ /* fall through */
166 case 0x0A:/* LF */ /* fall through */
167 case 0x0B:/* VT */ /* fall through */
168 case 0x0C:/* FF */ /* fall through */
169 case 0x0D:/* CR */ /* fall through */
170 dump_len += 2;
171 break;
172
173 case 0x22:/* " */ /* fall through */
174 case 0x27:/* ' */ /* fall through */
175 // case 0x3F:/* ? */ /* fall through */
176 case 0x5C:/* \ */ /* fall through */
177 default:
178 dump_len++; break;
179 }
180 }
181 }
182
183 return dump_len;
184 }
185
186 static uint32_t
187 get_irep_header_size(mrb_state *mrb, mrb_irep *irep, int type)
188 {
189 uint32_t size = 0;
190
191 size += sizeof(char) * 2;
192 size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type) * 4;
193
194 return size;
195 }
196
197 static uint32_t
198 get_iseq_block_size(mrb_state *mrb, mrb_irep *irep, int type)
199 {
200 uint32_t size = 0;
201
202 size += MRB_DUMP_SIZE_OF_LONG; /* ilen */
203 size += irep->ilen * MRB_DUMP_SIZE_OF_LONG; /* iseq(n) */
204 size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
205
206 return DUMP_SIZE(size, type);
207 }
208
209 static uint32_t
210 get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
211 {
212 uint32_t size = 0;
213 int pool_no;
214 mrb_value str;
215 char buf[32];
216
217 size += MRB_DUMP_SIZE_OF_LONG; /* plen */
218 size += irep->plen * sizeof(char); /* tt(n) */
219 size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */
220 size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
221 size = DUMP_SIZE(size, type);
222
223 for (pool_no = 0; pool_no < irep->plen; pool_no++) {
224 uint16_t nlen =0;
cd50242 @monaka Reduce strlen(). refs #301
monaka authored
225 int len;
e0d6430 @mimaki add mruby sources
mimaki authored
226
7d02df3 @matz NaN boxing
matz authored
227 switch (mrb_type(irep->pool[pool_no])) {
e0d6430 @mimaki add mruby sources
mimaki authored
228 case MRB_TT_FIXNUM:
7d02df3 @matz NaN boxing
matz authored
229 len = sprintf( buf, "%d", mrb_fixnum(irep->pool[pool_no]));
cd50242 @monaka Reduce strlen(). refs #301
monaka authored
230 size += (uint32_t)len;
e0d6430 @mimaki add mruby sources
mimaki authored
231 break;
232 case MRB_TT_FLOAT:
7d02df3 @matz NaN boxing
matz authored
233 len = sprintf( buf, "%.16e", mrb_float(irep->pool[pool_no]));
cd50242 @monaka Reduce strlen(). refs #301
monaka authored
234 size += (uint32_t)len;
e0d6430 @mimaki add mruby sources
mimaki authored
235 break;
236 case MRB_TT_STRING:
237 str = mrb_string_value( mrb, &irep->pool[pool_no]);
238 nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
239 size += nlen;
240 break;
76f7aec @matz use ENABLE/DISABLE instead of INCLUDE for configuration macro names
matz authored
241 #ifdef ENABLE_REGEXP
e0d6430 @mimaki add mruby sources
mimaki authored
242 case MRB_TT_REGEX:
243 str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
244 nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
245 size += nlen;
246 break;
247 #endif
248 default:
249 break;
250 }
251 }
252
253 return size;
254 }
255
256 static uint32_t
257 get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type)
258 {
259 uint32_t size = 0;
260 int sym_no;
261
262 size += MRB_DUMP_SIZE_OF_LONG; /* slen */
263 size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
264 size = DUMP_SIZE(size, type);
265
266 for (sym_no = 0; sym_no < irep->slen; sym_no++) {
267 const char * name;
268 uint16_t nlen =0;
269
270 size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */
271 if (irep->syms[sym_no] != 0) {
b7cc7ff @matz symbol can contain non printable characters
matz authored
272 int len;
273
274 name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
275 nlen = str_dump_len((char*)name, len, type);
e0d6430 @mimaki add mruby sources
mimaki authored
276 size += nlen; /* sn(n) */
277 }
278 }
279
280 return size;
281 }
282
283 static uint32_t
284 get_irep_record_size(mrb_state *mrb, int irep_no, int type)
285 {
286 uint32_t size = 0;
287 mrb_irep *irep = mrb->irep[irep_no];
288
289 size += DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type); /* rlen */
290 size += get_irep_header_size(mrb, irep, type);
291 size += get_iseq_block_size(mrb, irep, type);
292 size += get_pool_block_size(mrb, irep, type);
293 size += get_syms_block_size(mrb, irep, type);
294
295 return size;
296 }
297
298 static int
299 write_irep_header(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
300 {
301 char *buf_top = buf;
302
303 *buf++ = RITE_IREP_IDENFIFIER; /* record identifier */
304 *buf++ = RITE_IREP_TYPE_CLASS; /* class or module */
305 buf += uint16_dump((uint16_t)irep->nlocals, buf, type); /* number of local variable */
306 buf += uint16_dump((uint16_t)irep->nregs, buf, type); /* number of register variable */
307 buf += uint16_dump(DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type)/* crc */, buf, type); /* offset of isec block */
308
309 return (int)(buf - buf_top);
310 }
311
312 static int
313 write_iseq_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
314 {
315 char *buf_top = buf;
316 int iseq_no;
317
318 buf += uint32_dump((uint32_t)irep->ilen, buf, type); /* number of opcode */
319
320 for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
321 buf += uint32_dump((uint32_t)irep->iseq[iseq_no], buf, type); /* opcode */
322 }
323
324 return (int)(buf - buf_top);
325 }
326
327 static int
328 write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
329 {
330 int pool_no;
331 mrb_value str;
332 char *buf_top = buf;
333 char *char_buf;
334 uint16_t buf_size =0;
ebf88ee @tsahara-iij a string may have NUL characters.
tsahara-iij authored
335 uint16_t len =0;
e0d6430 @mimaki add mruby sources
mimaki authored
336
337 buf_size = MRB_DUMP_DEFAULT_STR_LEN;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
338 if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
339 goto error_exit;
340
341 buf += uint32_dump((uint32_t)irep->plen, buf, type); /* number of pool */
342
343 for (pool_no = 0; pool_no < irep->plen; pool_no++) {
7d02df3 @matz NaN boxing
matz authored
344 buf += uint8_dump(mrb_type(irep->pool[pool_no]), buf, type); /* data type */
e0d6430 @mimaki add mruby sources
mimaki authored
345 memset(char_buf, 0, buf_size);
346
7d02df3 @matz NaN boxing
matz authored
347 switch (mrb_type(irep->pool[pool_no])) {
e0d6430 @mimaki add mruby sources
mimaki authored
348 case MRB_TT_FIXNUM:
ebf88ee @tsahara-iij a string may have NUL characters.
tsahara-iij authored
349 len = sprintf(char_buf, "%d", mrb_fixnum(irep->pool[pool_no]));
e0d6430 @mimaki add mruby sources
mimaki authored
350 break;
351
352 case MRB_TT_FLOAT:
ebf88ee @tsahara-iij a string may have NUL characters.
tsahara-iij authored
353 len = sprintf(char_buf, "%.16e", mrb_float(irep->pool[pool_no]));
e0d6430 @mimaki add mruby sources
mimaki authored
354 break;
355
356 case MRB_TT_STRING:
357 str = mrb_string_value( mrb, &irep->pool[pool_no]);
ebf88ee @tsahara-iij a string may have NUL characters.
tsahara-iij authored
358 len = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
359 if ( len > buf_size - 1) {
360 buf_size = len + 1;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
361 if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
362 goto error_exit;
363 memset(char_buf, 0, buf_size);
364 }
365 str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
366 break;
367
76f7aec @matz use ENABLE/DISABLE instead of INCLUDE for configuration macro names
matz authored
368 #ifdef ENABLE_REGEXP
e0d6430 @mimaki add mruby sources
mimaki authored
369 case MRB_TT_REGEX:
370 str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
ebf88ee @tsahara-iij a string may have NUL characters.
tsahara-iij authored
371 len = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
372 if ( len > buf_size - 1) {
373 buf_size = len + 1;
e0d6430 @mimaki add mruby sources
mimaki authored
374 if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
375 goto error_exit;
376 memset(char_buf, 0, buf_size);
377 }
378 str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
379 break;
380 #endif
381
382 default:
383 buf += uint16_dump(0, buf, type); /* data length = 0 */
384 continue;
385 }
386
ebf88ee @tsahara-iij a string may have NUL characters.
tsahara-iij authored
387 buf += uint16_dump(len, buf, type); /* data length */
cc43182 @monaka write_pool_block(): reduce calling strlen(). refs #301.
monaka authored
388
389 memcpy(buf, char_buf, len);
390 buf += len;
e0d6430 @mimaki add mruby sources
mimaki authored
391 }
392
393 error_exit:
394 if (char_buf)
395 mrb_free(mrb, char_buf);
396 return (int)(buf - buf_top);
397 }
398
399 static int
400 write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
401 {
402 int sym_no;
403 char *buf_top = buf;
404 char *char_buf;
405 uint16_t buf_size =0;
406
407 buf_size = MRB_DUMP_DEFAULT_STR_LEN;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
408 if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
409 goto error_exit;
410
411 buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */
412
413 for (sym_no = 0; sym_no < irep->slen; sym_no++) {
414 const char * name;
415 uint16_t nlen =0;
416
417 if (irep->syms[sym_no] != 0) {
a70c4e0 @matz reduce calling of strlen(); #301
matz authored
418 int len;
419
9936ce9 @matz forgot to rename function mrb_sym2name -> mrb_sym2name_len
matz authored
420 name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
a70c4e0 @matz reduce calling of strlen(); #301
matz authored
421 nlen = str_dump_len((char*)name, len, type);
e0d6430 @mimaki add mruby sources
mimaki authored
422 if ( nlen > buf_size - 1) {
423 buf_size = nlen + 1;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
424 if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
425 goto error_exit;
426 }
427 memset(char_buf, 0, buf_size);
a70c4e0 @matz reduce calling of strlen(); #301
matz authored
428 str_dump((char*)name, char_buf, len, type);
e0d6430 @mimaki add mruby sources
mimaki authored
429
430 buf += uint16_dump(nlen, buf, type); /* length of symbol name */
431 memcpy(buf, char_buf, nlen); /* symbol name */
432 buf += nlen;
433 }
434 else {
435 buf += uint16_dump(MRB_DUMP_NULL_SYM_LEN, buf, type); /* length of symbol name */
436 }
437 }
438
439 error_exit:
440 if (char_buf)
441 mrb_free(mrb, char_buf);
442 return (int)(buf - buf_top);
443 }
444
445 static int
446 calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section)
447 {
448 char *buf, *buf_top;
449 uint32_t buf_size;
450 int type = DUMP_TYPE_BIN;
451
452 switch (section) {
453 case DUMP_IREP_HEADER: buf_size = get_irep_header_size(mrb, irep, type); break;
454 case DUMP_ISEQ_BLOCK: buf_size = get_iseq_block_size(mrb, irep, type); break;
455 case DUMP_POOL_BLOCK: buf_size = get_pool_block_size(mrb, irep, type); break;
456 case DUMP_SYMS_BLOCK: buf_size = get_syms_block_size(mrb, irep, type); break;
457 default: return MRB_DUMP_GENERAL_FAILURE;
458 }
459
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
460 if ((buf = (char *)mrb_calloc(mrb, 1, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
461 return MRB_DUMP_GENERAL_FAILURE;
462
463 buf_top = buf;
464
465 switch (section) {
466 case DUMP_IREP_HEADER: buf += write_irep_header(mrb, irep, buf, type); break;
467 case DUMP_ISEQ_BLOCK: buf += write_iseq_block(mrb, irep, buf, type); break;
468 case DUMP_POOL_BLOCK: buf += write_pool_block(mrb, irep, buf, type); break;
469 case DUMP_SYMS_BLOCK: buf += write_syms_block(mrb, irep, buf, type); break;
470 default: break;
471 }
472
4523bee @matz cast style consistency
matz authored
473 *crc = calc_crc_16_ccitt((unsigned char*)buf_top, (int)(buf - buf_top));
e0d6430 @mimaki add mruby sources
mimaki authored
474
475 mrb_free(mrb, buf_top);
476
477 return MRB_DUMP_OK;
478 }
479
480 static int
481 write_rite_header(mrb_state *mrb, int top, char* bin, uint32_t rbds)
482 {
483 rite_binary_header *binary_header;
484 uint16_t crc;
485 int type = DUMP_TYPE_BIN;
486
4523bee @matz cast style consistency
matz authored
487 binary_header = (rite_binary_header*)bin;
e0d6430 @mimaki add mruby sources
mimaki authored
488
489 memcpy( binary_header, def_rite_binary_header, sizeof(*binary_header));
490
4523bee @matz cast style consistency
matz authored
491 uint32_dump(rbds, (char*)binary_header->rbds, type);
492 uint16_dump((uint16_t)mrb->irep_len, (char*)binary_header->nirep, type);
493 uint16_dump((uint16_t)top, (char*)binary_header->sirep, type);
e0d6430 @mimaki add mruby sources
mimaki authored
494
4523bee @matz cast style consistency
matz authored
495 crc = calc_crc_16_ccitt((unsigned char*)binary_header, sizeof(*binary_header));
e0d6430 @mimaki add mruby sources
mimaki authored
496 bin += sizeof(*binary_header);
497 uint16_dump(crc, bin, type);
498
499 return MRB_DUMP_OK;
500 }
501
502 static int
503 dump_rite_header(mrb_state *mrb, int top, FILE* fp, uint32_t rbds)
504 {
505 rite_binary_header binary_header;
506 rite_file_header file_header;
507 uint16_t crc;
508 int type;
509
510 if (fseek(fp, 0, SEEK_SET) != 0)
511 return MRB_DUMP_GENERAL_FAILURE;
512
513 /* calc crc */
514 memcpy( &binary_header, def_rite_binary_header, sizeof(binary_header));
515
516 type = DUMP_TYPE_BIN;
4523bee @matz cast style consistency
matz authored
517 uint32_dump(rbds, (char*)&binary_header.rbds, type);
518 uint16_dump((uint16_t)mrb->irep_len, (char*)&binary_header.nirep, type);
519 uint16_dump((uint16_t)top, (char*)&binary_header.sirep, type);
e0d6430 @mimaki add mruby sources
mimaki authored
520
4523bee @matz cast style consistency
matz authored
521 crc = calc_crc_16_ccitt((unsigned char*)&binary_header, sizeof(binary_header));
e0d6430 @mimaki add mruby sources
mimaki authored
522
523 /* dump rbc header */
524 memcpy( &file_header, def_rite_file_header, sizeof(file_header));
525
526 type = DUMP_TYPE_HEX;
4523bee @matz cast style consistency
matz authored
527 uint32_dump(rbds, (char*)&file_header.rbds, type);
528 uint16_dump((uint16_t)mrb->irep_len, (char*)&file_header.nirep, type);
529 uint16_dump((uint16_t)top, (char*)&file_header.sirep, type);
530 uint16_dump(crc, (char*)&file_header.hcrc, type);
e0d6430 @mimaki add mruby sources
mimaki authored
531
532 if (fwrite(&file_header, sizeof(file_header), 1, fp) != 1)
533 return MRB_DUMP_WRITE_FAULT;
534
535 return MRB_DUMP_OK;
536 }
537
538 static int
539 write_irep_record(mrb_state *mrb, int irep_no, char* bin, uint32_t *rlen, int type)
540 {
541 uint32_t irep_record_size;
542 mrb_irep *irep = mrb->irep[irep_no];
543 int section;
544
545 if (irep == 0)
546 return MRB_DUMP_INVALID_IREP;
547
548 /* buf alloc */
549 irep_record_size = get_irep_record_size(mrb, irep_no, type);
550 if (irep_record_size == 0)
551 return MRB_DUMP_GENERAL_FAILURE;
552
553 memset( bin, 0, irep_record_size);
554
555 /* rlen */
556 *rlen = irep_record_size - DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type);
557
558 bin += uint32_dump(*rlen, bin, type);
559
560 for (section = 0; section < DUMP_SECTION_NUM; section++) {
561 int rc;
562 uint16_t crc;
563
564 switch (section) {
565 case DUMP_IREP_HEADER: bin += write_irep_header(mrb, irep, bin, type); break;
566 case DUMP_ISEQ_BLOCK: bin += write_iseq_block(mrb, irep, bin, type); break;
567 case DUMP_POOL_BLOCK: bin += write_pool_block(mrb, irep, bin, type); break;
568 case DUMP_SYMS_BLOCK: bin += write_syms_block(mrb, irep, bin, type); break;
569 default: break;
570 }
571
572 if ((rc = calc_crc_section(mrb, irep, &crc, section)) != 0)
573 return rc;
574
575 bin += uint16_dump(crc, bin, type); /* crc */
576 }
577
578 return MRB_DUMP_OK;
579 }
580
581 static int
582 dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen)
583 {
584 int rc = MRB_DUMP_OK;
585 uint32_t irep_record_size;
586 char *buf;
587 mrb_irep *irep = mrb->irep[irep_no];
588
589 if (irep == 0)
590 return MRB_DUMP_INVALID_IREP;
591
592 /* buf alloc */
593 irep_record_size = get_irep_record_size(mrb, irep_no, DUMP_TYPE_HEX);
594 if (irep_record_size == 0)
595 return MRB_DUMP_GENERAL_FAILURE;
596
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
597 if ((buf = (char *)mrb_calloc(mrb, 1, irep_record_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
598 return MRB_DUMP_GENERAL_FAILURE;
599
cc43182 @monaka write_pool_block(): reduce calling strlen(). refs #301.
monaka authored
600 if ((rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX)) != MRB_DUMP_OK) {
601 rc = MRB_DUMP_GENERAL_FAILURE;
e0d6430 @mimaki add mruby sources
mimaki authored
602 goto error_exit;
cc43182 @monaka write_pool_block(): reduce calling strlen(). refs #301.
monaka authored
603 }
e0d6430 @mimaki add mruby sources
mimaki authored
604
605
606 if (fwrite(buf, irep_record_size, 1, fp) != 1)
607 rc = MRB_DUMP_WRITE_FAULT;
608
609 error_exit:
610 mrb_free(mrb, buf);
611
612 return rc;
613 }
614
615 static int
616 mrb_write_irep(mrb_state *mrb, int top, char *bin)
617 {
618 int rc;
619 uint32_t rlen=0; /* size of irep record */
620 int irep_no;
621 char *bin_top;
622
623 if (mrb == 0 || top < 0 || top >= mrb->irep_len || bin == 0)
624 return MRB_DUMP_INVALID_ARGUMENT;
625
626 bin_top = bin;
627 bin += sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */;
628
629 for (irep_no=top; irep_no<mrb->irep_len; irep_no++) {
630 if ((rc = write_irep_record(mrb, irep_no, bin, &rlen, DUMP_TYPE_BIN)) != 0)
631 return rc;
632
633 bin += (rlen + DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, DUMP_TYPE_BIN));
634 }
635
636 bin += uint32_dump(0, bin, DUMP_TYPE_BIN); /* end of file */
637
638 rc = write_rite_header(mrb, top, bin_top, (bin - bin_top)); //TODO: Remove top(SIREP)
639
640 return rc;
641 }
642
643 int
644 mrb_dump_irep(mrb_state *mrb, int top, FILE* fp)
645 {
646 int rc;
647 uint32_t rbds=0; /* size of Rite Binary Data */
648 uint32_t rlen=0; /* size of irep record */
649 int irep_no;
650
651 if (mrb == 0 || top < 0 || top >= mrb->irep_len || fp == 0)
652 return MRB_DUMP_INVALID_ARGUMENT;
653
654 if (fwrite(&def_rite_file_header, sizeof(rite_file_header), 1, fp) != 1) /* dummy write */
655 return MRB_DUMP_WRITE_FAULT;
656
657 for (irep_no=top; irep_no<mrb->irep_len; irep_no++) {
658 if ((rc = dump_irep_record(mrb, irep_no, fp, &rlen)) != 0)
659 return rc;
660
661 rbds += rlen;
662 }
663
664 if (fwrite("00000000"/* end of file */, 8, 1, fp) != 1)
665 return MRB_DUMP_WRITE_FAULT;
666
4ec6d41 rm whitespace
roco authored
667 rc = dump_rite_header(mrb, top, fp, rbds); //TODO: Remove top(SIREP)
e0d6430 @mimaki add mruby sources
mimaki authored
668
669 return rc;
670 }
671
672 int
673 mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
674 {
675 int rc;
676 int irep_no;
677 char *buf;
678 int buf_size = 0;
679 int buf_idx = 0;
680
681 if (mrb == 0 || n < 0 || n >= mrb->irep_len || f == 0 || initname == 0)
682 return -1;
683
684 buf_size = sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */;
685 for (irep_no=n; irep_no<mrb->irep_len; irep_no++)
686 buf_size += get_irep_record_size(mrb, irep_no, DUMP_TYPE_BIN);
687 buf_size += MRB_DUMP_SIZE_OF_LONG; /* end of file */
688
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
689 if ((buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
690 return MRB_DUMP_GENERAL_FAILURE;
691
692 rc = mrb_write_irep(mrb, n, buf);
693
694 if (rc == MRB_DUMP_OK) {
695 fprintf(f, "const char %s[] = {", initname);
696 while (buf_idx < buf_size ) {
697 if (buf_idx % 16 == 0 ) fputs("\n", f);
698 fprintf(f, "0x%02x,", (unsigned char)buf[buf_idx++]);
699 }
700 fputs("\n};\n", f);
701 }
702
703 mrb_free(mrb, buf);
704
705 return rc;
706 }
Something went wrong with that request. Please try again.