source: EcnlProtoTool/trunk/mruby-1.2.0/src/load.c@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 18.2 KB
Line 
1/*
2** load.c - mruby binary loader
3**
4** See Copyright Notice in mruby.h
5*/
6
7#include <limits.h>
8#include <stdlib.h>
9#include <string.h>
10#include "mruby/dump.h"
11#include "mruby/irep.h"
12#include "mruby/proc.h"
13#include "mruby/string.h"
14#include "mruby/debug.h"
15#include "mruby/error.h"
16
17#if SIZE_MAX < UINT32_MAX
18# error size_t must be at least 32 bits wide
19#endif
20
21#define FLAG_BYTEORDER_BIG 2
22#define FLAG_BYTEORDER_LIL 4
23#define FLAG_BYTEORDER_NATIVE 8
24#define FLAG_SRC_MALLOC 1
25#define FLAG_SRC_STATIC 0
26
27#define SIZE_ERROR_MUL(nmemb, size) ((nmemb) > SIZE_MAX / (size))
28
29static size_t
30skip_padding(const uint8_t *buf)
31{
32 const size_t align = MRB_DUMP_ALIGNMENT;
33 return -(intptr_t)buf & (align-1);
34}
35
36static size_t
37offset_crc_body(void)
38{
39 struct rite_binary_header header;
40 return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc);
41}
42
43static mrb_irep*
44read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
45{
46 size_t i;
47 const uint8_t *src = bin;
48 ptrdiff_t diff;
49 uint16_t tt, pool_data_len, snl;
50 size_t plen;
51 int ai = mrb_gc_arena_save(mrb);
52 mrb_irep *irep = mrb_add_irep(mrb);
53
54 /* skip record size */
55 src += sizeof(uint32_t);
56
57 /* number of local variable */
58 irep->nlocals = bin_to_uint16(src);
59 src += sizeof(uint16_t);
60
61 /* number of register variable */
62 irep->nregs = bin_to_uint16(src);
63 src += sizeof(uint16_t);
64
65 /* number of child irep */
66 irep->rlen = (size_t)bin_to_uint16(src);
67 src += sizeof(uint16_t);
68
69 /* Binary Data Section */
70 /* ISEQ BLOCK */
71 irep->ilen = (size_t)bin_to_uint32(src);
72 src += sizeof(uint32_t);
73 src += skip_padding(src);
74
75 if (irep->ilen > 0) {
76 if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) {
77 return NULL;
78 }
79 if ((flags & FLAG_SRC_MALLOC) == 0 &&
80 (flags & FLAG_BYTEORDER_NATIVE)) {
81 irep->iseq = (mrb_code*)src;
82 src += sizeof(uint32_t) * irep->ilen;
83 irep->flags |= MRB_ISEQ_NO_FREE;
84 }
85 else {
86 irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
87 if (flags & FLAG_BYTEORDER_NATIVE) {
88 memcpy(irep->iseq, src, sizeof(uint32_t) * irep->ilen);
89 src += sizeof(uint32_t) * irep->ilen;
90 }
91 else if (flags & FLAG_BYTEORDER_BIG) {
92 for (i = 0; i < irep->ilen; i++) {
93 irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */
94 src += sizeof(uint32_t);
95 }
96 }
97 else {
98 for (i = 0; i < irep->ilen; i++) {
99 irep->iseq[i] = (mrb_code)bin_to_uint32l(src); /* iseq */
100 src += sizeof(uint32_t);
101 }
102 }
103 }
104 }
105
106 /* POOL BLOCK */
107 plen = (size_t)bin_to_uint32(src); /* number of pool */
108 src += sizeof(uint32_t);
109 if (plen > 0) {
110 if (SIZE_ERROR_MUL(plen, sizeof(mrb_value))) {
111 return NULL;
112 }
113 irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * plen);
114
115 for (i = 0; i < plen; i++) {
116 mrb_value s;
117
118 tt = *src++; /* pool TT */
119 pool_data_len = bin_to_uint16(src); /* pool data length */
120 src += sizeof(uint16_t);
121 if (flags & FLAG_SRC_MALLOC) {
122 s = mrb_str_new(mrb, (char *)src, pool_data_len);
123 }
124 else {
125 s = mrb_str_new_static(mrb, (char *)src, pool_data_len);
126 }
127 src += pool_data_len;
128 switch (tt) { /* pool data */
129 case IREP_TT_FIXNUM:
130 irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE);
131 break;
132
133 case IREP_TT_FLOAT:
134 irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE));
135 break;
136
137 case IREP_TT_STRING:
138 irep->pool[i] = mrb_str_pool(mrb, s);
139 break;
140
141 default:
142 /* should not happen */
143 irep->pool[i] = mrb_nil_value();
144 break;
145 }
146 irep->plen++;
147 mrb_gc_arena_restore(mrb, ai);
148 }
149 }
150
151 /* SYMS BLOCK */
152 irep->slen = (size_t)bin_to_uint32(src); /* syms length */
153 src += sizeof(uint32_t);
154 if (irep->slen > 0) {
155 if (SIZE_ERROR_MUL(irep->slen, sizeof(mrb_sym))) {
156 return NULL;
157 }
158 irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen);
159
160 for (i = 0; i < irep->slen; i++) {
161 snl = bin_to_uint16(src); /* symbol name length */
162 src += sizeof(uint16_t);
163
164 if (snl == MRB_DUMP_NULL_SYM_LEN) {
165 irep->syms[i] = 0;
166 continue;
167 }
168
169 if (flags & FLAG_SRC_MALLOC) {
170 irep->syms[i] = mrb_intern(mrb, (char *)src, snl);
171 }
172 else {
173 irep->syms[i] = mrb_intern_static(mrb, (char *)src, snl);
174 }
175 src += snl + 1;
176
177 mrb_gc_arena_restore(mrb, ai);
178 }
179 }
180
181 irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen);
182
183 diff = src - bin;
184 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
185 *len = (size_t)diff;
186
187 return irep;
188}
189
190static mrb_irep*
191read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
192{
193 mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags);
194 size_t i;
195
196 if (irep == NULL) {
197 return NULL;
198 }
199
200 bin += *len;
201 for (i=0; i<irep->rlen; i++) {
202 size_t rlen;
203
204 irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags);
205 if (irep->reps[i] == NULL) {
206 return NULL;
207 }
208 bin += rlen;
209 *len += rlen;
210 }
211 return irep;
212}
213
214static mrb_irep*
215read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
216{
217 size_t len;
218
219 bin += sizeof(struct rite_section_irep_header);
220 return read_irep_record(mrb, bin, &len, flags);
221}
222
223static int
224read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len)
225{
226 size_t i, fname_len, niseq;
227 char *fname;
228 uint16_t *lines;
229
230 *len = 0;
231 bin += sizeof(uint32_t); /* record size */
232 *len += sizeof(uint32_t);
233 fname_len = bin_to_uint16(bin);
234 bin += sizeof(uint16_t);
235 *len += sizeof(uint16_t);
236 fname = (char *)mrb_malloc(mrb, fname_len + 1);
237 memcpy(fname, bin, fname_len);
238 fname[fname_len] = '\0';
239 bin += fname_len;
240 *len += fname_len;
241
242 niseq = (size_t)bin_to_uint32(bin);
243 bin += sizeof(uint32_t); /* niseq */
244 *len += sizeof(uint32_t);
245
246 if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) {
247 return MRB_DUMP_GENERAL_FAILURE;
248 }
249 lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t));
250 for (i = 0; i < niseq; i++) {
251 lines[i] = bin_to_uint16(bin);
252 bin += sizeof(uint16_t); /* niseq */
253 *len += sizeof(uint16_t);
254 }
255
256 irep->filename = fname;
257 irep->lines = lines;
258 return MRB_DUMP_OK;
259}
260
261static int
262read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp)
263{
264 int result = read_lineno_record_1(mrb, bin, irep, lenp);
265 size_t i;
266
267 if (result != MRB_DUMP_OK) return result;
268 for (i = 0; i < irep->rlen; i++) {
269 size_t len;
270
271 result = read_lineno_record(mrb, bin, irep->reps[i], &len);
272 if (result != MRB_DUMP_OK) break;
273 bin += len;
274 *lenp += len;
275 }
276 return result;
277}
278
279static int
280read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep)
281{
282 size_t len;
283
284 len = 0;
285 bin += sizeof(struct rite_section_lineno_header);
286
287 /* Read Binary Data Section */
288 return read_lineno_record(mrb, bin, irep, &len);
289}
290
291static int
292read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len)
293{
294 const uint8_t *bin = start;
295 ptrdiff_t diff;
296 size_t record_size, i;
297 uint16_t f_idx;
298
299 if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; }
300
301 irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info));
302 irep->debug_info->pc_count = irep->ilen;
303
304 record_size = (size_t)bin_to_uint32(bin);
305 bin += sizeof(uint32_t);
306
307 irep->debug_info->flen = bin_to_uint16(bin);
308 irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen);
309 bin += sizeof(uint16_t);
310
311 for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
312 mrb_irep_debug_info_file *file;
313 uint16_t filename_idx;
314 mrb_int len;
315
316 file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file));
317 irep->debug_info->files[f_idx] = file;
318
319 file->start_pos = bin_to_uint32(bin);
320 bin += sizeof(uint32_t);
321
322 /* filename */
323 filename_idx = bin_to_uint16(bin);
324 bin += sizeof(uint16_t);
325 mrb_assert(filename_idx < filenames_len);
326 file->filename_sym = filenames[filename_idx];
327 len = 0;
328 file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len);
329
330 file->line_entry_count = bin_to_uint32(bin);
331 bin += sizeof(uint32_t);
332 file->line_type = (mrb_debug_line_type)bin_to_uint8(bin);
333 bin += sizeof(uint8_t);
334 switch (file->line_type) {
335 case mrb_debug_line_ary: {
336 uint32_t l;
337
338 file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count));
339 for (l = 0; l < file->line_entry_count; ++l) {
340 file->lines.ary[l] = bin_to_uint16(bin);
341 bin += sizeof(uint16_t);
342 }
343 } break;
344
345 case mrb_debug_line_flat_map: {
346 uint32_t l;
347
348 file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(
349 mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count));
350 for (l = 0; l < file->line_entry_count; ++l) {
351 file->lines.flat_map[l].start_pos = bin_to_uint32(bin);
352 bin += sizeof(uint32_t);
353 file->lines.flat_map[l].line = bin_to_uint16(bin);
354 bin += sizeof(uint16_t);
355 }
356 } break;
357
358 default: return MRB_DUMP_GENERAL_FAILURE;
359 }
360 }
361
362 diff = bin - start;
363 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
364
365 if (record_size != (size_t)diff) {
366 return MRB_DUMP_GENERAL_FAILURE;
367 }
368
369 for (i = 0; i < irep->rlen; i++) {
370 size_t len;
371 int ret;
372
373 ret = read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_len);
374 if (ret != MRB_DUMP_OK) return ret;
375 bin += len;
376 }
377
378 diff = bin - start;
379 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
380 *record_len = (size_t)diff;
381
382 return MRB_DUMP_OK;
383}
384
385static int
386read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
387{
388 const uint8_t *bin;
389 ptrdiff_t diff;
390 struct rite_section_debug_header *header;
391 uint16_t i;
392 size_t len = 0;
393 int result;
394 uint16_t filenames_len;
395 mrb_sym *filenames;
396
397 bin = start;
398 header = (struct rite_section_debug_header *)bin;
399 bin += sizeof(struct rite_section_debug_header);
400
401 filenames_len = bin_to_uint16(bin);
402 bin += sizeof(uint16_t);
403 filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len);
404 for (i = 0; i < filenames_len; ++i) {
405 uint16_t f_len = bin_to_uint16(bin);
406 bin += sizeof(uint16_t);
407 if (flags & FLAG_SRC_MALLOC) {
408 filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len);
409 }
410 else {
411 filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len);
412 }
413 bin += f_len;
414 }
415
416 result = read_debug_record(mrb, bin, irep, &len, filenames, filenames_len);
417 if (result != MRB_DUMP_OK) goto debug_exit;
418
419 bin += len;
420 diff = bin - start;
421 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
422 if ((uint32_t)diff != bin_to_uint32(header->section_size)) {
423 result = MRB_DUMP_GENERAL_FAILURE;
424 }
425
426debug_exit:
427 mrb_free(mrb, filenames);
428 return result;
429}
430
431static int
432read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *record_len, mrb_sym const *syms, uint32_t syms_len)
433{
434 const uint8_t *bin = start;
435 size_t i;
436 ptrdiff_t diff;
437
438 irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (irep->nlocals - 1));
439
440 for (i = 0; i + 1< irep->nlocals; ++i) {
441 uint16_t const sym_idx = bin_to_uint16(bin);
442 bin += sizeof(uint16_t);
443 if (sym_idx == RITE_LV_NULL_MARK) {
444 irep->lv[i].name = 0;
445 irep->lv[i].r = 0;
446 }
447 else {
448 if (sym_idx >= syms_len) {
449 return MRB_DUMP_GENERAL_FAILURE;
450 }
451 irep->lv[i].name = syms[sym_idx];
452
453 irep->lv[i].r = bin_to_uint16(bin);
454 }
455 bin += sizeof(uint16_t);
456 }
457
458 for (i = 0; i < irep->rlen; ++i) {
459 size_t len;
460 int ret;
461
462 ret = read_lv_record(mrb, bin, irep->reps[i], &len, syms, syms_len);
463 if (ret != MRB_DUMP_OK) return ret;
464 bin += len;
465 }
466
467 diff = bin - start;
468 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
469 *record_len = (size_t)diff;
470
471 return MRB_DUMP_OK;
472}
473
474static int
475read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
476{
477 const uint8_t *bin;
478 ptrdiff_t diff;
479 struct rite_section_lv_header const *header;
480 uint32_t i;
481 size_t len = 0;
482 int result;
483 uint32_t syms_len;
484 mrb_sym *syms;
485 mrb_sym (*intern_func)(mrb_state*, const char*, size_t) =
486 (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static;
487
488 bin = start;
489 header = (struct rite_section_lv_header const*)bin;
490 bin += sizeof(struct rite_section_lv_header);
491
492 syms_len = bin_to_uint32(bin);
493 bin += sizeof(uint32_t);
494 syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)syms_len);
495 for (i = 0; i < syms_len; ++i) {
496 uint16_t const str_len = bin_to_uint16(bin);
497 bin += sizeof(uint16_t);
498
499 syms[i] = intern_func(mrb, (const char*)bin, str_len);
500 bin += str_len;
501 }
502
503 result = read_lv_record(mrb, bin, irep, &len, syms, syms_len);
504 if (result != MRB_DUMP_OK) goto lv_exit;
505
506 bin += len;
507 diff = bin - start;
508 mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
509 if ((uint32_t)diff != bin_to_uint32(header->section_size)) {
510 result = MRB_DUMP_GENERAL_FAILURE;
511 }
512
513lv_exit:
514 mrb_free(mrb, syms);
515 return result;
516}
517
518static int
519read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags)
520{
521 const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
522
523 if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) {
524 if (bigendian_p())
525 *flags |= FLAG_BYTEORDER_NATIVE;
526 else
527 *flags |= FLAG_BYTEORDER_BIG;
528 }
529 else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) {
530 if (bigendian_p())
531 *flags |= FLAG_BYTEORDER_LIL;
532 else
533 *flags |= FLAG_BYTEORDER_NATIVE;
534 }
535 else {
536 return MRB_DUMP_INVALID_FILE_HEADER;
537 }
538
539 if (crc) {
540 *crc = bin_to_uint16(header->binary_crc);
541 }
542 *bin_size = (size_t)bin_to_uint32(header->binary_size);
543
544 return MRB_DUMP_OK;
545}
546
547MRB_API mrb_irep*
548read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
549{
550 int result;
551 mrb_irep *irep = NULL;
552 const struct rite_section_header *section_header;
553 uint16_t crc;
554 size_t bin_size = 0;
555 size_t n;
556
557 if ((mrb == NULL) || (bin == NULL)) {
558 return NULL;
559 }
560
561 result = read_binary_header(bin, &bin_size, &crc, &flags);
562 if (result != MRB_DUMP_OK) {
563 return NULL;
564 }
565
566 n = offset_crc_body();
567 if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) {
568 return NULL;
569 }
570
571 bin += sizeof(struct rite_binary_header);
572 do {
573 section_header = (const struct rite_section_header *)bin;
574 if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) {
575 irep = read_section_irep(mrb, bin, flags);
576 if (!irep) return NULL;
577 }
578 else if (memcmp(section_header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(section_header->section_ident)) == 0) {
579 if (!irep) return NULL; /* corrupted data */
580 result = read_section_lineno(mrb, bin, irep);
581 if (result < MRB_DUMP_OK) {
582 return NULL;
583 }
584 }
585 else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) {
586 if (!irep) return NULL; /* corrupted data */
587 result = read_section_debug(mrb, bin, irep, flags);
588 if (result < MRB_DUMP_OK) {
589 return NULL;
590 }
591 }
592 else if (memcmp(section_header->section_ident, RITE_SECTION_LV_IDENT, sizeof(section_header->section_ident)) == 0) {
593 if (!irep) return NULL;
594 result = read_section_lv(mrb, bin, irep, flags);
595 if (result < MRB_DUMP_OK) {
596 return NULL;
597 }
598 }
599 bin += bin_to_uint32(section_header->section_size);
600 } while (memcmp(section_header->section_ident, RITE_BINARY_EOF, sizeof(section_header->section_ident)) != 0);
601
602 return irep;
603}
604
605MRB_API mrb_irep*
606mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
607{
608#ifdef MRB_USE_ETEXT_EDATA
609 uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC;
610#else
611 uint8_t flags = FLAG_SRC_STATIC;
612#endif
613
614 return read_irep(mrb, bin, flags);
615}
616
617static void
618irep_error(mrb_state *mrb)
619{
620 mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error"));
621}
622
623MRB_API mrb_value
624mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c)
625{
626 mrb_irep *irep = mrb_read_irep(mrb, bin);
627 struct RProc *proc;
628
629 if (!irep) {
630 irep_error(mrb);
631 return mrb_nil_value();
632 }
633 proc = mrb_proc_new(mrb, irep);
634 mrb_irep_decref(mrb, irep);
635 if (c && c->no_exec) return mrb_obj_value(proc);
636 return mrb_toplevel_run(mrb, proc);
637}
638
639MRB_API mrb_value
640mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
641{
642 return mrb_load_irep_cxt(mrb, bin, NULL);
643}
644
645#ifndef MRB_DISABLE_STDIO
646
647MRB_API mrb_irep*
648mrb_read_irep_file(mrb_state *mrb, FILE* fp)
649{
650 mrb_irep *irep = NULL;
651 uint8_t *buf;
652 const size_t header_size = sizeof(struct rite_binary_header);
653 size_t buf_size = 0;
654 uint8_t flags = 0;
655 int result;
656
657 if ((mrb == NULL) || (fp == NULL)) {
658 return NULL;
659 }
660
661 buf = (uint8_t*)mrb_malloc(mrb, header_size);
662 if (fread(buf, header_size, 1, fp) == 0) {
663 goto irep_exit;
664 }
665 result = read_binary_header(buf, &buf_size, NULL, &flags);
666 if (result != MRB_DUMP_OK || buf_size <= header_size) {
667 goto irep_exit;
668 }
669
670 buf = (uint8_t*)mrb_realloc(mrb, buf, buf_size);
671 if (fread(buf+header_size, buf_size-header_size, 1, fp) == 0) {
672 goto irep_exit;
673 }
674 irep = read_irep(mrb, buf, FLAG_SRC_MALLOC);
675
676irep_exit:
677 mrb_free(mrb, buf);
678 return irep;
679}
680
681void mrb_codedump_all(mrb_state*, struct RProc*);
682
683MRB_API mrb_value
684mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c)
685{
686 mrb_irep *irep = mrb_read_irep_file(mrb, fp);
687 mrb_value val;
688 struct RProc *proc;
689
690 if (!irep) {
691 irep_error(mrb);
692 return mrb_nil_value();
693 }
694 proc = mrb_proc_new(mrb, irep);
695 mrb_irep_decref(mrb, irep);
696 if (c && c->dump_result) mrb_codedump_all(mrb, proc);
697 if (c && c->no_exec) return mrb_obj_value(proc);
698 val = mrb_toplevel_run(mrb, proc);
699 return val;
700}
701
702MRB_API mrb_value
703mrb_load_irep_file(mrb_state *mrb, FILE* fp)
704{
705 return mrb_load_irep_file_cxt(mrb, fp, NULL);
706}
707#endif /* MRB_DISABLE_STDIO */
Note: See TracBrowser for help on using the repository browser.