Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 645 lines (568 sloc) 19.17 kB
8354436 @mimaki add file header
mimaki authored
1 /*
2 ** load.c - mruby binary loader
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 typedef struct _RiteFILE
17 {
18 FILE* fp;
19 unsigned char buf[256];
20 int cnt;
21 int readlen;
22 } RiteFILE;
23
24 const char hex2bin[256] = {
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //00-0f
26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10-1f
27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-2f
28 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, //30-3f
29 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-4f
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-5f
31 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 //60-6f
32 //70-ff
33 };
34
35 static uint16_t hex_to_bin8(unsigned char*,unsigned char*);
36 static uint16_t hex_to_bin16(unsigned char*,unsigned char*);
37 static uint16_t hex_to_bin32(unsigned char*,unsigned char*);
38 static uint8_t hex_to_uint8(unsigned char*);
39 static uint16_t hex_to_uint16(unsigned char*);
40 static uint32_t hex_to_uint32(unsigned char*);
41 static char* hex_to_str(char*,char*,uint16_t*);
42 uint16_t calc_crc_16_ccitt(unsigned char*,int);
43 static unsigned char rite_fgetcSub(RiteFILE*);
44 static unsigned char rite_fgetc(RiteFILE*,int);
45 static unsigned char* rite_fgets(RiteFILE*,unsigned char*,int,int);
46 static int load_rite_header(FILE*,rite_binary_header*,unsigned char*);
47 static int load_rite_irep_record(mrb_state*, RiteFILE*,unsigned char*,uint32_t*);
48 static int read_rite_header(mrb_state*,unsigned char*,rite_binary_header*);
49 static int read_rite_irep_record(mrb_state*,unsigned char*,mrb_irep*,uint32_t*);
50
51
52 static unsigned char
53 rite_fgetcSub(RiteFILE* rfp)
54 {
55 //only first call
56 if (rfp->buf[0] == '\0') {
57 rfp->readlen = fread(rfp->buf, 1, sizeof(rfp->buf), rfp->fp);
58 rfp->cnt = 0;
59 }
60
61 if (rfp->readlen == rfp->cnt) {
62 rfp->readlen = fread(rfp->buf, 1, sizeof(rfp->buf), rfp->fp);
63 rfp->cnt = 0;
64 if (rfp->readlen == 0) {
65 return '\0';
66 }
67 }
68 return rfp->buf[(rfp->cnt)++];
69 }
70
71 static unsigned char
72 rite_fgetc(RiteFILE* rfp, int ignorecomment)
73 {
74 unsigned char tmp;
75
76 for (;;) {
77 tmp = rite_fgetcSub(rfp);
78 if (tmp == '\n' || tmp == '\r') {
79 continue;
80 }
81 else if (ignorecomment && tmp == '#') {
82 while (tmp != '\n' && tmp != '\r' && tmp != '\0')
83 tmp = rite_fgetcSub(rfp);
84 if (tmp == '\0')
85 return '\0';
86 }
87 else {
88 return tmp;
89 }
90 }
91 }
92
93 static unsigned char*
94 rite_fgets(RiteFILE* rfp, unsigned char* dst, int len, int ignorecomment)
95 {
96 int i;
97
98 for (i=0; i<len; i++) {
99 if ('\0' == (dst[i] = rite_fgetc(rfp, ignorecomment))) {
100 return NULL;
101 }
102 }
103 return dst;
104 }
105
106 static int
107 load_rite_header(FILE* fp, rite_binary_header* bin_header, unsigned char* hcrc)
108 {
109 rite_file_header file_header;
110
b68e69a @matz remove unused assignments
matz authored
111 if (fread(&file_header, 1, sizeof(file_header), fp) < sizeof(file_header)) {
112 return MRB_DUMP_READ_FAULT;
113 }
e0d6430 @mimaki add mruby sources
mimaki authored
114 memcpy(bin_header->rbfi, file_header.rbfi, sizeof(file_header.rbfi));
115 if (memcmp(bin_header->rbfi, RITE_FILE_IDENFIFIER, sizeof(bin_header->rbfi)) != 0) {
116 return MRB_DUMP_INVALID_FILE_HEADER; //File identifier error
117 }
118 memcpy(bin_header->rbfv, file_header.rbfv, sizeof(file_header.rbfv));
119 if (memcmp(bin_header->rbfv, RITE_FILE_FORMAT_VER, sizeof(bin_header->rbfv)) != 0) {
120 return MRB_DUMP_INVALID_FILE_HEADER; //File format version error
121 }
122 memcpy(bin_header->risv, file_header.risv, sizeof(file_header.risv));
123 memcpy(bin_header->rct, file_header.rct, sizeof(file_header.rct));
124 memcpy(bin_header->rcv, file_header.rcv, sizeof(file_header.rcv));
125 hex_to_bin32(bin_header->rbds, file_header.rbds);
126 hex_to_bin16(bin_header->nirep, file_header.nirep);
127 hex_to_bin16(bin_header->sirep, file_header.sirep);
128 memcpy(bin_header->rsv, file_header.rsv, sizeof(file_header.rsv));
129 memcpy(hcrc, file_header.hcrc, sizeof(file_header.hcrc));
130
131 return MRB_DUMP_OK;
132 }
133
134 static int
135 load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_t* len)
136 {
137 int i;
138 uint32_t blocklen;
b68e69a @matz remove unused assignments
matz authored
139 uint16_t offset, pdl, snl, clen;
e0d6430 @mimaki add mruby sources
mimaki authored
140 unsigned char hex2[2], hex4[4], hex8[8], hcrc[4];
141 unsigned char *pStart;
142 char *char_buf;
143 uint16_t buf_size =0;
144
145 buf_size = MRB_DUMP_DEFAULT_STR_LEN;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
146 if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
147 goto error_exit;
148
149 pStart = dst;
150
151 //IREP HEADER BLOCK
152 *dst = rite_fgetc(rfp, TRUE); //record identifier
153 if (*dst != RITE_IREP_IDENFIFIER)
154 return MRB_DUMP_INVALID_IREP;
155 dst += sizeof(unsigned char);
156 *dst = rite_fgetc(rfp, TRUE); //class or module
157 dst += sizeof(unsigned char);
158 rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of local variable
159 dst += hex_to_bin16(dst, hex4);
160 rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of register variable
161 dst += hex_to_bin16(dst, hex4);
162 rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //offset of isec block
163 offset = hex_to_uint16(hex4);
164 rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //header CRC
165 memset( char_buf, '\0', buf_size);
166 rite_fgets(rfp, (unsigned char*)char_buf, (offset - (MRB_DUMP_SIZE_OF_SHORT * RITE_FILE_HEX_SIZE)), TRUE); //class or module name
167 hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT + MRB_DUMP_SIZE_OF_SHORT), &clen); //class or module name
168 dst += uint16_to_bin((MRB_DUMP_SIZE_OF_SHORT/*crc*/ + clen), (char*)dst); //offset of isec block
169 dst += hex_to_bin16(dst, hcrc); //header CRC
170 dst += clen;
171
172 //ISEQ BLOCK
173 rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq length
174 dst += hex_to_bin32(dst, hex8);
175 blocklen = hex_to_uint32(hex8);
176 for (i=0; i<blocklen; i++) {
177 rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq
178 dst += hex_to_bin32(dst, hex8);
179 }
180 rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //iseq CRC
181 dst += hex_to_bin16(dst, hcrc);
182
183 //POOL BLOCK
184 rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //pool length
185 dst += hex_to_bin32(dst, hex8);
186 blocklen = hex_to_uint32(hex8);
187 for (i=0; i<blocklen; i++) {
188 rite_fgets(rfp, hex2, sizeof(hex2), TRUE); //TT
189 dst += hex_to_bin8(dst, hex2);
190 rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //pool data length
191 pdl = hex_to_uint16(hex4);
192
193 if ( pdl > buf_size - 1) {
194 buf_size = pdl + 1;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
195 if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
196 goto error_exit;
197 }
198 memset(char_buf, '\0', buf_size);
199 rite_fgets(rfp, (unsigned char*)char_buf, pdl, FALSE); //pool
200 hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen);
201 dst += uint16_to_bin(clen, (char*)dst);
202 dst += clen;
203 }
204 rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //pool CRC
205 dst += hex_to_bin16(dst, hcrc);
206
207 //SYMS BLOCK
208 rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //syms length
209 dst += hex_to_bin32(dst, hex8);
210 blocklen = hex_to_uint32(hex8);
211 for (i=0; i<blocklen; i++) {
212 rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //symbol name length
213 snl = hex_to_uint16(hex4);
214
215 if (snl == MRB_DUMP_NULL_SYM_LEN) {
216 dst += uint16_to_bin(snl, (char*)dst);
217 continue;
218 }
219
220 if ( snl > buf_size - 1) {
221 buf_size = snl + 1;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
222 if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0)
e0d6430 @mimaki add mruby sources
mimaki authored
223 goto error_exit;
224 }
225 memset(char_buf, '\0', buf_size);
226 rite_fgets(rfp, (unsigned char*)char_buf, snl, FALSE); //symbol name
227 hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen);
228 dst += uint16_to_bin(clen, (char*)dst);
229 dst += clen;
230 }
231 rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //syms CRC
232 dst += hex_to_bin16(dst, hcrc);
233
234 *len = dst - pStart;
235
236 error_exit:
237 if (char_buf)
238 mrb_free(mrb, char_buf);
239
240 return MRB_DUMP_OK;
241 }
242
243 int
244 mrb_load_irep(mrb_state *mrb, FILE* fp)
245 {
246 int ret, i;
6250d06 @monaka Avoid "may be used uninitialized in this function" warning.
monaka authored
247 uint32_t len, rlen = 0;
e0d6430 @mimaki add mruby sources
mimaki authored
248 unsigned char hex8[8], hcrc[4];
249 unsigned char *dst, *rite_dst = NULL;
250 rite_binary_header bin_header;
7496625 @matz initialize stuctures on stack without memset(); close #350
matz authored
251 RiteFILE ritefp = { 0 };
252 RiteFILE *rfp;
e0d6430 @mimaki add mruby sources
mimaki authored
253
254 if ((mrb == NULL) || (fp == NULL)) {
255 return MRB_DUMP_INVALID_ARGUMENT;
256 }
257 ritefp.fp = fp;
258 rfp = &ritefp;
259
260 //Read File Header Section
261 if ((ret = load_rite_header(fp, &bin_header, hcrc)) != MRB_DUMP_OK)
262 return ret;
263
264 len = sizeof(rite_binary_header) + bin_to_uint32(bin_header.rbds);
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
265 if ((rite_dst = (unsigned char *)mrb_malloc(mrb, len)) == NULL)
e0d6430 @mimaki add mruby sources
mimaki authored
266 return MRB_DUMP_GENERAL_FAILURE;
267
268 dst = rite_dst;
269 memset(dst, 0x00, len);
270 memcpy(dst, &bin_header, sizeof(rite_binary_header));
271 dst += sizeof(rite_binary_header);
272 dst += hex_to_bin16(dst, hcrc);
273
274 //Read Binary Data Section
275 len = bin_to_uint16(bin_header.nirep);
276 for (i=0; i<len; i++) {
277 rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //record len
278 dst += hex_to_bin32(dst, hex8);
279 if ((ret = load_rite_irep_record(mrb, rfp, dst, &rlen)) != MRB_DUMP_OK) //irep info
280 goto error_exit;
281 dst += rlen;
282 }
283 rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //dummy record len
9206dcb @matz remove assignment to unused dst; close #424
matz authored
284 hex_to_bin32(dst, hex8); /* dst += hex_to_bin32(dst, hex8); */
e0d6430 @mimaki add mruby sources
mimaki authored
285 if (0 != hex_to_uint32(hex8)) {
286 ret = MRB_DUMP_INVALID_IREP;
287 goto error_exit;
288 }
289
290 if (ret == MRB_DUMP_OK)
291 ret = mrb_read_irep(mrb, (char*)rite_dst);
292
293 error_exit:
294 if (rite_dst)
295 mrb_free(mrb, rite_dst);
296
297 return ret;
298 }
299
300 static int
301 read_rite_header(mrb_state *mrb, unsigned char *bin, rite_binary_header* bin_header)
302 {
303 uint16_t crc;
304
305 memcpy(bin_header, bin, sizeof(rite_binary_header));
306 bin += sizeof(rite_binary_header);
307 if (memcmp(bin_header->rbfi, RITE_FILE_IDENFIFIER, sizeof(bin_header->rbfi)) != 0) {
308 return MRB_DUMP_INVALID_FILE_HEADER; //File identifier error
309 }
310 if (memcmp(bin_header->risv, RITE_VM_VER, sizeof(bin_header->risv)) != 0) {
311 return MRB_DUMP_INVALID_FILE_HEADER; //Instruction set version check
312 }
313
4523bee @matz cast style consistency
matz authored
314 crc = calc_crc_16_ccitt((unsigned char*)bin_header, sizeof(*bin_header)); //Calculate CRC
e0d6430 @mimaki add mruby sources
mimaki authored
315 if (crc != bin_to_uint16(bin)) {
316 return MRB_DUMP_INVALID_FILE_HEADER; //CRC error
317 }
318
319 return bin_to_uint16(bin_header->nirep);
320 }
321
322 static int
323 read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32_t* len)
324 {
325 int i, ret = MRB_DUMP_OK;
326 char *buf;
327 unsigned char *recordStart, *pStart;
328 uint16_t crc, tt, pdl, snl, offset, bufsize=MRB_DUMP_DEFAULT_STR_LEN;
329 mrb_int fix_num;
330 mrb_float f;
b20388c @matz make arena_idx restoration per irep, not per load
matz authored
331 int ai = mrb_gc_arena_save(mrb);
e0d6430 @mimaki add mruby sources
mimaki authored
332
333 recordStart = src;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
334 buf = (char *)mrb_malloc(mrb, bufsize);
e0d6430 @mimaki add mruby sources
mimaki authored
335 if (buf == NULL) {
336 ret = MRB_DUMP_INVALID_IREP;
337 goto error_exit;
338 }
339
340 //Header Section
341 pStart = src;
342 if (*src != RITE_IREP_IDENFIFIER)
343 return MRB_DUMP_INVALID_IREP;
344 src += (sizeof(unsigned char) * 2);
345 irep->nlocals = bin_to_uint16(src); //number of local variable
346 src += MRB_DUMP_SIZE_OF_SHORT;
347 irep->nregs = bin_to_uint16(src); //number of register variable
348 src += MRB_DUMP_SIZE_OF_SHORT;
349 offset = bin_to_uint16(src); //offset of isec block
350 src += MRB_DUMP_SIZE_OF_SHORT;
351 crc = calc_crc_16_ccitt(pStart, src - pStart); //Calculate CRC
352 if (crc != bin_to_uint16(src)) //header CRC
353 return MRB_DUMP_INVALID_IREP;
354 src += offset;
355
356 //Binary Data Section
357 //ISEQ BLOCK
358 pStart = src;
359 irep->ilen = bin_to_uint32(src); //iseq length
360 src += MRB_DUMP_SIZE_OF_LONG;
361 if (irep->ilen > 0) {
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
362 if ((irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen)) == NULL) {
e0d6430 @mimaki add mruby sources
mimaki authored
363 ret = MRB_DUMP_GENERAL_FAILURE;
364 goto error_exit;
365 }
366 for (i=0; i<irep->ilen; i++) {
367 irep->iseq[i] = bin_to_uint32(src); //iseq
368 src += MRB_DUMP_SIZE_OF_LONG;
369 }
370 }
4523bee @matz cast style consistency
matz authored
371 crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC
e0d6430 @mimaki add mruby sources
mimaki authored
372 if (crc != bin_to_uint16(src)) { //iseq CRC
373 ret = MRB_DUMP_INVALID_IREP;
374 goto error_exit;
375 }
376 src += MRB_DUMP_SIZE_OF_SHORT;
377
378 //POOL BLOCK
379 pStart = src;
380 irep->plen = bin_to_uint32(src); //pool length
381 src += MRB_DUMP_SIZE_OF_LONG;
382 if (irep->plen > 0) {
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
383 irep->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value) * irep->plen);
e0d6430 @mimaki add mruby sources
mimaki authored
384 if (irep->pool == NULL) {
385 ret = MRB_DUMP_INVALID_IREP;
386 goto error_exit;
387 }
388
389 for (i=0; i<irep->plen; i++) {
390 tt = *src; //pool TT
391 src += sizeof(unsigned char);
392 pdl = bin_to_uint16(src); //pool data length
393 src += MRB_DUMP_SIZE_OF_SHORT;
394 if (pdl > bufsize - 1) {
395 mrb_free(mrb, buf);
396 bufsize = pdl + 1;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
397 if ((buf = (char *)mrb_malloc(mrb, bufsize)) == NULL) {
e0d6430 @mimaki add mruby sources
mimaki authored
398 ret = MRB_DUMP_GENERAL_FAILURE;
399 goto error_exit;
400 }
401 }
402 memcpy(buf, src, pdl);
403 src += pdl;
404 buf[pdl] = '\0';
405
406 switch (tt) { //pool data
407 case MRB_TT_FIXNUM:
6919ca6 @matz stop using strtol (via readint) except in load.c; use custom readint_…
matz authored
408 fix_num = strtol(buf, NULL, 10);
e0d6430 @mimaki add mruby sources
mimaki authored
409 irep->pool[i] = mrb_fixnum_value(fix_num);
410 break;
411
412 case MRB_TT_FLOAT:
4ec6d41 rm whitespace
roco authored
413 f = readfloat(buf);
e0d6430 @mimaki add mruby sources
mimaki authored
414 irep->pool[i] = mrb_float_value(f);
415 break;
416
417 case MRB_TT_STRING:
418 irep->pool[i] = mrb_str_new(mrb, buf, pdl);
419 break;
420
76f7aec @matz use ENABLE/DISABLE instead of INCLUDE for configuration macro names
matz authored
421 #ifdef ENABLE_REGEXP
e0d6430 @mimaki add mruby sources
mimaki authored
422 case MRB_TT_REGEX:
423 str = mrb_str_new(mrb, buf, pdl);
424 irep->pool[i] = mrb_reg_quote(mrb, str);
425 break;
426 #endif
427
428 default:
429 irep->pool[i] = mrb_nil_value();
430 break;
431 }
432 }
433 }
4523bee @matz cast style consistency
matz authored
434 crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC
e0d6430 @mimaki add mruby sources
mimaki authored
435 if (crc != bin_to_uint16(src)) { //pool CRC
436 ret = MRB_DUMP_INVALID_IREP;
437 goto error_exit;
438 }
439 src += MRB_DUMP_SIZE_OF_SHORT;
440
441 //SYMS BLOCK
442 pStart = src;
443 irep->slen = bin_to_uint32(src); //syms length
444 src += MRB_DUMP_SIZE_OF_LONG;
445 if (irep->slen > 0) {
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
446 if ((irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen)) == NULL) {
e0d6430 @mimaki add mruby sources
mimaki authored
447 ret = MRB_DUMP_INVALID_IREP;
448 goto error_exit;
449 }
450
451 memset(irep->syms, 0, sizeof(mrb_sym)*(irep->slen));
452 for (i=0; i<irep->slen; i++) {
453 snl = bin_to_uint16(src); //symbol name length
454 src += MRB_DUMP_SIZE_OF_SHORT;
455
456 if (snl == MRB_DUMP_NULL_SYM_LEN) {
457 irep->syms[i] = 0;
458 continue;
459 }
460
461 if (snl > bufsize - 1) {
462 mrb_free(mrb, buf);
463 bufsize = snl + 1;
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
464 if ((buf = (char *)mrb_malloc(mrb, bufsize)) == NULL) {
e0d6430 @mimaki add mruby sources
mimaki authored
465 ret = MRB_DUMP_GENERAL_FAILURE;
466 goto error_exit;
467 }
468 }
469 memcpy(buf, src, snl); //symbol name
470 src += snl;
471 buf[snl] = '\0';
b7cc7ff @matz symbol can contain non printable characters
matz authored
472 irep->syms[i] = mrb_intern2(mrb, buf, snl);
e0d6430 @mimaki add mruby sources
mimaki authored
473 }
474 }
4523bee @matz cast style consistency
matz authored
475 crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC
e0d6430 @mimaki add mruby sources
mimaki authored
476 if (crc != bin_to_uint16(src)) { //syms CRC
477 ret = MRB_DUMP_INVALID_IREP;
478 goto error_exit;
479 }
480 src += MRB_DUMP_SIZE_OF_SHORT;
481
482 *len = src - recordStart;
483 error_exit:
b20388c @matz make arena_idx restoration per irep, not per load
matz authored
484 mrb_gc_arena_restore(mrb, ai);
e0d6430 @mimaki add mruby sources
mimaki authored
485 if (buf)
486 mrb_free(mrb, buf);
487
488 return ret;
489 }
490
491 int
4b85151 @pbhogan mrb_read_irep should take const char *
pbhogan authored
492 mrb_read_irep(mrb_state *mrb, const char *bin)
e0d6430 @mimaki add mruby sources
mimaki authored
493 {
494 int ret = MRB_DUMP_OK, i, n, nirep, sirep;
6250d06 @monaka Avoid "may be used uninitialized in this function" warning.
monaka authored
495 uint32_t len = 0;
e0d6430 @mimaki add mruby sources
mimaki authored
496 unsigned char *src;
497 rite_binary_header bin_header;
498
499 if ((mrb == NULL) || (bin == NULL)) {
500 return MRB_DUMP_INVALID_ARGUMENT;
501 }
502 src = (unsigned char*)bin;
503 sirep = mrb->irep_len;
504
505 //Read File Header Section
506 if ((nirep = read_rite_header(mrb, src, &bin_header)) < 0)
507 return nirep;
508
509 mrb_add_irep(mrb, sirep + nirep);
510
511 for (n=0,i=sirep; n<nirep; n++,i++) {
5a4beee @silverhammermba Make all(?) void casts explicit for C++
silverhammermba authored
512 if ((mrb->irep[i] = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep))) == NULL) {
e0d6430 @mimaki add mruby sources
mimaki authored
513 ret = MRB_DUMP_GENERAL_FAILURE;
514 goto error_exit;
515 }
516 memset(mrb->irep[i], 0, sizeof(mrb_irep));
517 }
518 src += sizeof(bin_header) + MRB_DUMP_SIZE_OF_SHORT; //header + crc
519
520 //Read Binary Data Section
521 for (n=0,i=sirep; n<nirep; n++,i++) {
522 src += MRB_DUMP_SIZE_OF_LONG; //record ren
523 if ((ret = read_rite_irep_record(mrb, src, mrb->irep[i], &len)) != MRB_DUMP_OK)
524 goto error_exit;
e6c6dcc @matz update mrb->irep_len for each irep addition
matz authored
525 mrb->irep[mrb->irep_len++]->idx = i;
e0d6430 @mimaki add mruby sources
mimaki authored
526 src += len;
527 }
528 if (0 != bin_to_uint32(src)) { //dummy record len
529 ret = MRB_DUMP_GENERAL_FAILURE;
530 }
531
532 error_exit:
533 if (ret != MRB_DUMP_OK) {
534 for (n=0,i=sirep; n<nirep; n++,i++) {
535 if (mrb->irep[i]) {
536 if (mrb->irep[i]->iseq)
537 mrb_free(mrb, mrb->irep[i]->iseq);
538
539 if (mrb->irep[i]->pool)
540 mrb_free(mrb, mrb->irep[i]->pool);
541
542 if (mrb->irep[i]->syms)
543 mrb_free(mrb, mrb->irep[i]->syms);
544
545 mrb_free(mrb, mrb->irep[i]);
546 }
547 }
548 return ret;
549 }
550 return sirep + hex_to_uint8(bin_header.sirep);
551 }
552
553 static uint16_t
554 hex_to_bin8(unsigned char *dst, unsigned char *src)
555 {
556 dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
557 return 1;
558 }
559
560 static uint16_t
561 hex_to_bin16(unsigned char *dst, unsigned char *src)
562 {
563 dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
564 dst[1] = (hex2bin[src[2]] << 4) | (hex2bin[src[3]]);
565 return 2;
566 }
567
568 static uint16_t
569 hex_to_bin32(unsigned char *dst, unsigned char *src)
570 {
571 dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
572 dst[1] = (hex2bin[src[2]] << 4) | (hex2bin[src[3]]);
573 dst[2] = (hex2bin[src[4]] << 4) | (hex2bin[src[5]]);
574 dst[3] = (hex2bin[src[6]] << 4) | (hex2bin[src[7]]);
575 return 4;
576 }
577
578 static uint8_t
579 hex_to_uint8(unsigned char *hex)
580 {
581 return (unsigned char)hex2bin[hex[0]] << 4 |
582 (unsigned char)hex2bin[hex[1]];
583 }
584
585 static uint16_t
586 hex_to_uint16(unsigned char *hex)
587 {
588 return (uint16_t)hex2bin[hex[0]] << 12 |
589 (uint16_t)hex2bin[hex[1]] << 8 |
590 (uint16_t)hex2bin[hex[2]] << 4 |
591 (uint16_t)hex2bin[hex[3]];
592 }
593
594 static uint32_t
595 hex_to_uint32(unsigned char *hex)
596 {
597 return (uint32_t)hex2bin[hex[0]] << 28 |
598 (uint32_t)hex2bin[hex[1]] << 24 |
599 (uint32_t)hex2bin[hex[2]] << 20 |
600 (uint32_t)hex2bin[hex[3]] << 16 |
601 (uint32_t)hex2bin[hex[4]] << 12 |
602 (uint32_t)hex2bin[hex[5]] << 8 |
603 (uint32_t)hex2bin[hex[6]] << 4 |
604 (uint32_t)hex2bin[hex[7]];
605 }
606
607 static char*
608 hex_to_str(char *hex, char *str, uint16_t *str_len)
609 {
610 char *src, *dst;
568af55 @monaka Refactor hex_to_str().
monaka authored
611 int escape = 0;
e0d6430 @mimaki add mruby sources
mimaki authored
612
613 *str_len = 0;
568af55 @monaka Refactor hex_to_str().
monaka authored
614 for (src = hex, dst = str; *src != '\0'; src++) {
615 if (escape) {
e0d6430 @mimaki add mruby sources
mimaki authored
616 switch(*src) {
617 case 'a': *dst++ = '\a'/* BEL */; break;
618 case 'b': *dst++ = '\b'/* BS */; break;
619 case 't': *dst++ = '\t'/* HT */; break;
620 case 'n': *dst++ = '\n'/* LF */; break;
621 case 'v': *dst++ = '\v'/* VT */; break;
622 case 'f': *dst++ = '\f'/* FF */; break;
623 case 'r': *dst++ = '\r'/* CR */; break;
624 case '\"': /* fall through */
625 case '\'': /* fall through */
626 case '\?': /* fall through */
627 case '\\': *dst++ = *src; break;
628 default:break;
629 }
568af55 @monaka Refactor hex_to_str().
monaka authored
630 escape = 0;
e0d6430 @mimaki add mruby sources
mimaki authored
631 } else {
568af55 @monaka Refactor hex_to_str().
monaka authored
632 if (*src == '\\') {
633 escape = 1;
634 } else {
635 escape = 0;
636 *dst++ = *src;
637 }
638 }
639 if (!escape) {
640 (*str_len)++;
e0d6430 @mimaki add mruby sources
mimaki authored
641 }
642 }
643 return str;
644 }
Something went wrong with that request. Please try again.