Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 707 lines (572 sloc) 19.469 kb
8354436 Hiroshi Mimaki add file header
mimaki authored
1 /*
2 ** dump.c - mruby binary dumper (Rite binary format)
4ec6d41 rm whitespace
roco authored
3 **
8354436 Hiroshi Mimaki add file header
mimaki authored
4 ** See Copyright Notice in mruby.h
5 */
6
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
7 #include <string.h>
8b36709 Yukihiro "Matz" Matsumoto move header files {irep,dump,cdump,ritehash}.h to /include/mruby
matz authored
8 #include "mruby/dump.h"
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
9
10 #include "mruby/string.h"
76f7aec Yukihiro "Matz" Matsumoto use ENABLE/DISABLE instead of INCLUDE for configuration macro names
matz authored
11 #ifdef ENABLE_REGEXP
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
12 #include "re.h"
13 #endif
8b36709 Yukihiro "Matz" Matsumoto move header files {irep,dump,cdump,ritehash}.h to /include/mruby
matz authored
14 #include "mruby/irep.h"
e0d6430 Hiroshi 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 Masaki Muranaka Reduce strlen(). refs #301
monaka authored
225 int len;
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
226
7d02df3 Yukihiro "Matz" Matsumoto NaN boxing
matz authored
227 switch (mrb_type(irep->pool[pool_no])) {
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
228 case MRB_TT_FIXNUM:
7d02df3 Yukihiro "Matz" Matsumoto NaN boxing
matz authored
229 len = sprintf( buf, "%d", mrb_fixnum(irep->pool[pool_no]));
cd50242 Masaki Muranaka Reduce strlen(). refs #301
monaka authored
230 size += (uint32_t)len;
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
231 break;
232 case MRB_TT_FLOAT:
7d02df3 Yukihiro "Matz" Matsumoto NaN boxing
matz authored
233 len = sprintf( buf, "%.16e", mrb_float(irep->pool[pool_no]));
cd50242 Masaki Muranaka Reduce strlen(). refs #301
monaka authored
234 size += (uint32_t)len;
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto use ENABLE/DISABLE instead of INCLUDE for configuration macro names
matz authored
241 #ifdef ENABLE_REGEXP
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto 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 Hiroshi 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 Tomoyuki Sahara a string may have NUL characters.
tsahara-iij authored
335 uint16_t len =0;
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
336
337 buf_size = MRB_DUMP_DEFAULT_STR_LEN;
5a4beee Max Make all(?) void casts explicit for C++
silverhammermba authored
338 if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto NaN boxing
matz authored
344 buf += uint8_dump(mrb_type(irep->pool[pool_no]), buf, type); /* data type */
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
345 memset(char_buf, 0, buf_size);
346
7d02df3 Yukihiro "Matz" Matsumoto NaN boxing
matz authored
347 switch (mrb_type(irep->pool[pool_no])) {
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
348 case MRB_TT_FIXNUM:
ebf88ee Tomoyuki Sahara a string may have NUL characters.
tsahara-iij authored
349 len = sprintf(char_buf, "%d", mrb_fixnum(irep->pool[pool_no]));
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
350 break;
351
352 case MRB_TT_FLOAT:
ebf88ee Tomoyuki Sahara a string may have NUL characters.
tsahara-iij authored
353 len = sprintf(char_buf, "%.16e", mrb_float(irep->pool[pool_no]));
e0d6430 Hiroshi 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 Tomoyuki Sahara 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 Max Make all(?) void casts explicit for C++
silverhammermba authored
361 if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto use ENABLE/DISABLE instead of INCLUDE for configuration macro names
matz authored
368 #ifdef ENABLE_REGEXP
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
369 case MRB_TT_REGEX:
370 str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
ebf88ee Tomoyuki Sahara 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 Hiroshi 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 Tomoyuki Sahara a string may have NUL characters.
tsahara-iij authored
387 buf += uint16_dump(len, buf, type); /* data length */
cc43182 Masaki Muranaka write_pool_block(): reduce calling strlen(). refs #301.
monaka authored
388
389 memcpy(buf, char_buf, len);
390 buf += len;
e0d6430 Hiroshi 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 Max Make all(?) void casts explicit for C++
silverhammermba authored
408 if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto reduce calling of strlen(); #301
matz authored
418 int len;
419
9936ce9 Yukihiro "Matz" Matsumoto forgot to rename function mrb_sym2name -> mrb_sym2name_len
matz authored
420 name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
a70c4e0 Yukihiro "Matz" Matsumoto reduce calling of strlen(); #301
matz authored
421 nlen = str_dump_len((char*)name, len, type);
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
422 if ( nlen > buf_size - 1) {
423 buf_size = nlen + 1;
5a4beee Max Make all(?) void casts explicit for C++
silverhammermba authored
424 if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
425 goto error_exit;
426 }
427 memset(char_buf, 0, buf_size);
a70c4e0 Yukihiro "Matz" Matsumoto reduce calling of strlen(); #301
matz authored
428 str_dump((char*)name, char_buf, len, type);
e0d6430 Hiroshi 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 Max Make all(?) void casts explicit for C++
silverhammermba authored
460 if ((buf = (char *)mrb_calloc(mrb, 1, buf_size)) == 0)
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto cast style consistency
matz authored
473 *crc = calc_crc_16_ccitt((unsigned char*)buf_top, (int)(buf - buf_top));
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto cast style consistency
matz authored
487 binary_header = (rite_binary_header*)bin;
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
488
489 memcpy( binary_header, def_rite_binary_header, sizeof(*binary_header));
490
4523bee Yukihiro "Matz" Matsumoto 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 Hiroshi Mimaki add mruby sources
mimaki authored
494
4523bee Yukihiro "Matz" Matsumoto cast style consistency
matz authored
495 crc = calc_crc_16_ccitt((unsigned char*)binary_header, sizeof(*binary_header));
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto 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 Hiroshi Mimaki add mruby sources
mimaki authored
520
4523bee Yukihiro "Matz" Matsumoto cast style consistency
matz authored
521 crc = calc_crc_16_ccitt((unsigned char*)&binary_header, sizeof(binary_header));
e0d6430 Hiroshi 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 Yukihiro "Matz" Matsumoto 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 Hiroshi 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 Max Make all(?) void casts explicit for C++
silverhammermba authored
597 if ((buf = (char *)mrb_calloc(mrb, 1, irep_record_size)) == 0)
e0d6430 Hiroshi Mimaki add mruby sources
mimaki authored
598 return MRB_DUMP_GENERAL_FAILURE;
599
cc43182 Masaki Muranaka 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 Hiroshi Mimaki add mruby sources
mimaki authored
602 goto error_exit;
cc43182 Masaki Muranaka write_pool_block(): reduce calling strlen(). refs #301.
monaka authored
603 }
e0d6430 Hiroshi 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 Hiroshi 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 Max Make all(?) void casts explicit for C++
silverhammermba authored
689 if ((buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
e0d6430 Hiroshi 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.