Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
load.c
Go to the documentation of this file.
1 /*
2 ** load.c - mruby binary loader
3 **
4 ** See Copyright Notice in mruby.h
5 */
6 
7 #ifndef SIZE_MAX
8  /* Some versions of VC++
9  * has SIZE_MAX in stdint.h
10  */
11 # include <limits.h>
12 #endif
13 #include <stdlib.h>
14 #include <string.h>
15 #include "mruby/dump.h"
16 #include "mruby/irep.h"
17 #include "mruby/proc.h"
18 #include "mruby/string.h"
19 #include "mruby/debug.h"
20 
21 #if !defined(_WIN32) && SIZE_MAX < UINT32_MAX
22 # define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y))
23 # define SIZE_ERROR(x) ((x) > SIZE_MAX)
24 #else
25 # define SIZE_ERROR_MUL(x, y) (0)
26 # define SIZE_ERROR(x) (0)
27 #endif
28 
29 #if CHAR_BIT != 8
30 # error This code assumes CHAR_BIT == 8
31 #endif
32 
33 static void
34 irep_free(size_t sirep, mrb_state *mrb)
35 {
36  size_t i;
37  void *p;
38 
39  for (i = sirep; i < mrb->irep_len; i++) {
40  if (mrb->irep[i]) {
41  p = mrb->irep[i]->iseq;
42  if (p)
43  mrb_free(mrb, p);
44 
45  p = mrb->irep[i]->pool;
46  if (p)
47  mrb_free(mrb, p);
48 
49  p = mrb->irep[i]->syms;
50  if (p)
51  mrb_free(mrb, p);
52 
53  mrb_free(mrb, mrb->irep[i]);
54  }
55  }
56 }
57 
58 static size_t
59 offset_crc_body(void)
60 {
61  struct rite_binary_header header;
62  return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc);
63 }
64 
65 static int
66 read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
67 {
68  int ret;
69  size_t i;
70  const uint8_t *src = bin;
71  uint16_t tt, pool_data_len, snl;
72  size_t plen;
73  int ai = mrb_gc_arena_save(mrb);
74  mrb_irep *irep = mrb_add_irep(mrb);
75 
76  // skip record size
77  src += sizeof(uint32_t);
78 
79  // number of local variable
80  irep->nlocals = bin_to_uint16(src);
81  src += sizeof(uint16_t);
82 
83  // number of register variable
84  irep->nregs = bin_to_uint16(src);
85  src += sizeof(uint16_t);
86 
87  // Binary Data Section
88  // ISEQ BLOCK
89  irep->ilen = bin_to_uint32(src);
90  src += sizeof(uint32_t);
91  if (irep->ilen > 0) {
92  if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) {
94  goto error_exit;
95  }
96  irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
97  if (irep->iseq == NULL) {
99  goto error_exit;
100  }
101  for (i = 0; i < irep->ilen; i++) {
102  irep->iseq[i] = bin_to_uint32(src); //iseq
103  src += sizeof(uint32_t);
104  }
105  }
106 
107  //POOL BLOCK
108  plen = bin_to_uint32(src); /* number of pool */
109  src += sizeof(uint32_t);
110  if (plen > 0) {
111  if (SIZE_ERROR_MUL(sizeof(mrb_value), plen)) {
113  goto error_exit;
114  }
115  irep->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value) * plen);
116  if (irep->pool == NULL) {
118  goto error_exit;
119  }
120 
121  for (i = 0; i < plen; i++) {
122  mrb_value s;
123  tt = *src++; //pool TT
124  pool_data_len = bin_to_uint16(src); //pool data length
125  src += sizeof(uint16_t);
126  s = mrb_str_new(mrb, (char *)src, pool_data_len);
127  src += pool_data_len;
128  switch (tt) { //pool data
129  case MRB_TT_FIXNUM:
130  irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE);
131  break;
132 
133  case MRB_TT_FLOAT:
134  irep->pool[i] = mrb_float_value(mrb, mrb_str_to_dbl(mrb, s, FALSE));
135  break;
136 
137  case MRB_TT_STRING:
138  irep->pool[i] = s;
139  break;
140 
141  default:
142  irep->pool[i] = mrb_nil_value();
143  break;
144  }
145  irep->plen++;
146  mrb_gc_arena_restore(mrb, ai);
147  }
148  }
149 
150  //SYMS BLOCK
151  irep->slen = bin_to_uint32(src); //syms length
152  src += sizeof(uint32_t);
153  if (irep->slen > 0) {
154  if (SIZE_ERROR_MUL(sizeof(mrb_sym), irep->slen)) {
156  goto error_exit;
157  }
158  irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen);
159  if (irep->syms == NULL) {
161  goto error_exit;
162  }
163 
164  for (i = 0; i < irep->slen; i++) {
165  snl = bin_to_uint16(src); //symbol name length
166  src += sizeof(uint16_t);
167 
168  if (snl == MRB_DUMP_NULL_SYM_LEN) {
169  irep->syms[i] = 0;
170  continue;
171  }
172 
173  irep->syms[i] = mrb_intern2(mrb, (char *)src, snl);
174  src += snl + 1;
175 
176  mrb_gc_arena_restore(mrb, ai);
177  }
178  }
179  *len = src - bin;
180 
181  ret = MRB_DUMP_OK;
182 error_exit:
183  return ret;
184 }
185 
186 static int
187 read_rite_section_irep(mrb_state *mrb, const uint8_t *bin)
188 {
189  int result;
190  size_t sirep;
191  uint32_t len;
192  uint16_t nirep;
193  uint16_t n;
194  const struct rite_section_irep_header *header;
195 
196  header = (const struct rite_section_irep_header*)bin;
197  bin += sizeof(struct rite_section_irep_header);
198 
199  sirep = mrb->irep_len;
200  nirep = bin_to_uint16(header->nirep);
201 
202  //Read Binary Data Section
203  for (n = 0; n < nirep; n++) {
204  result = read_rite_irep_record(mrb, bin, &len);
205  if (result != MRB_DUMP_OK)
206  goto error_exit;
207  bin += len;
208  }
209 
210  result = nirep;
211 error_exit:
212  if (result < MRB_DUMP_OK) {
213  irep_free(sirep, mrb);
214  }
215  return result;
216 }
217 
218 static int
219 read_rite_lineno_record(mrb_state *mrb, const uint8_t *bin, size_t irepno, uint32_t *len)
220 {
221  int ret;
222  size_t i, fname_len, niseq;
223  char *fname;
224  uint16_t *lines;
225 
226  ret = MRB_DUMP_OK;
227  *len = 0;
228  bin += sizeof(uint32_t); // record size
229  *len += sizeof(uint32_t);
230  fname_len = bin_to_uint16(bin);
231  bin += sizeof(uint16_t);
232  *len += sizeof(uint16_t);
233  if (SIZE_ERROR(fname_len + 1)) {
235  goto error_exit;
236  }
237  fname = (char *)mrb_malloc(mrb, fname_len + 1);
238  if (fname == NULL) {
240  goto error_exit;
241  }
242  memcpy(fname, bin, fname_len);
243  fname[fname_len] = '\0';
244  bin += fname_len;
245  *len += fname_len;
246 
247  niseq = bin_to_uint32(bin);
248  bin += sizeof(uint32_t); // niseq
249  *len += sizeof(uint32_t);
250 
251  if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) {
253  goto error_exit;
254  }
255  lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t));
256  if (lines == NULL) {
258  goto error_exit;
259  }
260  for (i = 0; i < niseq; i++) {
261  lines[i] = bin_to_uint16(bin);
262  bin += sizeof(uint16_t); // niseq
263  *len += sizeof(uint16_t);
264  }
265 
266  mrb->irep[irepno]->filename = fname;
267  mrb->irep[irepno]->lines = lines;
268 
269 error_exit:
270 
271  return ret;
272 }
273 
274 static int
275 read_rite_section_lineno(mrb_state *mrb, const uint8_t *bin, size_t sirep)
276 {
277  int result;
278  size_t i;
279  uint32_t len;
280  uint16_t nirep;
281  uint16_t n;
282  const struct rite_section_lineno_header *header;
283 
284  len = 0;
285  header = (const struct rite_section_lineno_header*)bin;
286  bin += sizeof(struct rite_section_lineno_header);
287 
288  nirep = bin_to_uint16(header->nirep);
289 
290  //Read Binary Data Section
291  for (n = 0, i = sirep; n < nirep; n++, i++) {
292  result = read_rite_lineno_record(mrb, bin, i, &len);
293  if (result != MRB_DUMP_OK)
294  goto error_exit;
295  bin += len;
296  }
297 
298  result = sirep + bin_to_uint16(header->sirep);
299 error_exit:
300  return result;
301 }
302 
303 static int
304 read_rite_debug_record(mrb_state *mrb, const uint8_t *start, size_t irepno, uint32_t *len, const mrb_sym *filenames, size_t filenames_len)
305 {
306  const uint8_t *bin = start;
307  mrb_irep *irep = mrb->irep[irepno];
308  size_t record_size;
309  uint16_t f_idx;
310 
311  if(irep->debug_info) { return MRB_DUMP_INVALID_IREP; }
312 
314  irep->debug_info->pc_count = irep->ilen;
315 
316  record_size = bin_to_uint32(bin);
317  bin += sizeof(uint32_t);
318 
319  irep->debug_info->flen = bin_to_uint16(bin);
321  bin += sizeof(uint16_t);
322 
323  for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
325  uint16_t filename_idx;
326  size_t len;
327 
328  file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file));
329  irep->debug_info->files[f_idx] = file;
330 
331  file->start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t);
332 
333  // filename
334  filename_idx = bin_to_uint16(bin);
335  bin += sizeof(uint16_t);
336  mrb_assert(filename_idx < filenames_len);
337  file->filename_sym = filenames[filename_idx];
338  len = 0;
339  file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len);
340 
341  file->line_entry_count = bin_to_uint32(bin); bin += sizeof(uint32_t);
342  file->line_type = bin_to_uint8(bin); bin += sizeof(uint8_t);
343  switch(file->line_type) {
344  case mrb_debug_line_ary: {
345  size_t l;
346 
347  file->line_ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * file->line_entry_count);
348  for(l = 0; l < file->line_entry_count; ++l) {
349  file->line_ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t);
350  }
351  } break;
352 
354  size_t l;
355 
357  for(l = 0; l < file->line_entry_count; ++l) {
358  file->line_flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t);
359  file->line_flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t);
360  }
361  } break;
362 
363  default: return MRB_DUMP_GENERAL_FAILURE;
364  }
365  }
366 
367  if((long)record_size != (bin - start)) {
369  }
370 
371  *len = bin - start;
372 
373  return MRB_DUMP_OK;
374 }
375 
376 static int
377 read_rite_section_debug(mrb_state *mrb, const uint8_t *start, size_t sirep)
378 {
379  const uint8_t *bin;
380  struct rite_section_debug_header *header;
381  uint16_t i;
382  int result;
383  uint16_t nirep;
384  size_t filenames_len;
385  mrb_sym *filenames;
386 
387  bin = start;
388  header = (struct rite_section_debug_header *)bin;
389  bin += sizeof(struct rite_section_debug_header);
390 
391  nirep = bin_to_uint16(header->nirep);
392 
393  filenames_len = bin_to_uint16(bin);
394  bin += sizeof(uint16_t);
395  filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym*) * filenames_len);
396  for(i = 0; i < filenames_len; ++i) {
397  uint16_t f_len = bin_to_uint16(bin);
398  bin += sizeof(uint16_t);
399  filenames[i] = mrb_intern2(mrb, (const char *)bin, f_len);
400  bin += f_len;
401  }
402 
403  for(i = sirep; i < (sirep + nirep); ++i) {
404  uint32_t len = 0;
405  result = read_rite_debug_record(mrb, bin, i, &len, filenames, filenames_len);
406  if (result != MRB_DUMP_OK) { goto debug_exit; }
407  bin += len;
408  }
409 
410  if ((bin - start) != bin_to_uint32(header->section_size)) {
412  }
413 
414  result = sirep + bin_to_uint16(header->sirep);
415 debug_exit:
416  mrb_free(mrb, filenames);
417  return result;
418 }
419 
420 static int
421 read_rite_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc)
422 {
423  const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
424 
425  if (memcmp(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)) != 0) {
427  }
428 
429  if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) {
431  }
432 
433  *crc = bin_to_uint16(header->binary_crc);
434  if (bin_size) {
435  *bin_size = bin_to_uint32(header->binary_size);
436  }
437 
438  return MRB_DUMP_OK;
439 }
440 
441 int32_t
442 mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
443 {
444  int result;
445  int32_t total_nirep = 0;
446  const struct rite_section_header *section_header;
447  uint16_t crc;
448  size_t bin_size = 0;
449  size_t n;
450  size_t sirep;
451 
452  if ((mrb == NULL) || (bin == NULL)) {
454  }
455 
456  result = read_rite_binary_header(bin, &bin_size, &crc);
457  if (result != MRB_DUMP_OK) {
458  return result;
459  }
460 
461  n = offset_crc_body();
462  if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) {
464  }
465 
466  bin += sizeof(struct rite_binary_header);
467  sirep = mrb->irep_len;
468 
469  do {
470  section_header = (const struct rite_section_header *)bin;
471  if (memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
472  result = read_rite_section_irep(mrb, bin);
473  if (result < MRB_DUMP_OK) {
474  return result;
475  }
476  total_nirep += result;
477  }
478  else if (memcmp(section_header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
479  result = read_rite_section_lineno(mrb, bin, sirep);
480  if (result < MRB_DUMP_OK) {
481  return result;
482  }
483  }
484  else if (memcmp(section_header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
485  result = read_rite_section_debug(mrb, bin, sirep);
486  if (result < MRB_DUMP_OK) {
487  return result;
488  }
489  }
490  bin += bin_to_uint32(section_header->section_size);
491  } while (memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0);
492 
493  return sirep;
494 }
495 
496 static void
497 irep_error(mrb_state *mrb, int n)
498 {
499  static const char msg[] = "irep load error";
500  mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
501 }
502 
503 mrb_value
504 mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
505 {
506  int32_t n;
507 
508  n = mrb_read_irep(mrb, bin);
509  if (n < 0) {
510  irep_error(mrb, n);
511  return mrb_nil_value();
512  }
513  return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
514 }
515 
516 #ifdef ENABLE_STDIO
517 
518 static int32_t
519 read_rite_section_lineno_file(mrb_state *mrb, FILE *fp, size_t sirep)
520 {
521  int32_t result;
522  size_t i;
523  uint16_t nirep;
524  uint16_t n;
525  uint32_t len, buf_size;
526  uint8_t *buf = NULL;
527  const size_t record_header_size = 4;
528 
529  struct rite_section_lineno_header header;
530  if (fread(&header, sizeof(struct rite_section_lineno_header), 1, fp) == 0) {
531  return MRB_DUMP_READ_FAULT;
532  }
533 
534  nirep = bin_to_uint16(header.nirep);
535 
536  buf_size = record_header_size;
537  /* We don't need to check buf_size. As it is enough small. */
538  buf = (uint8_t *)mrb_malloc(mrb, buf_size);
539  if (!buf) {
540  result = MRB_DUMP_GENERAL_FAILURE;
541  goto error_exit;
542  }
543 
544  //Read Binary Data Section
545  for (n = 0, i = sirep; n < nirep; n++, i++) {
546  void *ptr;
547 
548  if (fread(buf, record_header_size, 1, fp) == 0) {
549  result = MRB_DUMP_READ_FAULT;
550  goto error_exit;
551  }
552  buf_size = bin_to_uint32(&buf[0]);
553  if (SIZE_ERROR(buf_size)) {
554  result = MRB_DUMP_GENERAL_FAILURE;
555  goto error_exit;
556  }
557  ptr = mrb_realloc(mrb, buf, buf_size);
558  if (!ptr) {
559  result = MRB_DUMP_GENERAL_FAILURE;
560  goto error_exit;
561  }
562  buf = (uint8_t *)ptr;
563 
564  if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) {
565  result = MRB_DUMP_READ_FAULT;
566  goto error_exit;
567  }
568  result = read_rite_lineno_record(mrb, buf, i, &len);
569  if (result != MRB_DUMP_OK)
570  goto error_exit;
571  }
572 
573  result = sirep + bin_to_uint16(header.sirep);
574 error_exit:
575  if (buf) {
576  mrb_free(mrb, buf);
577  }
578  if (result < MRB_DUMP_OK) {
579  irep_free(sirep, mrb);
580  }
581  return result;
582 }
583 
584 static int32_t
585 read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
586 {
587  int32_t result;
588  size_t sirep;
589  uint16_t nirep;
590  uint16_t n;
591  uint32_t len, buf_size;
592  uint8_t *buf = NULL;
593  const size_t record_header_size = 1 + 4;
594  struct rite_section_irep_header header;
595 
596  if (fread(&header, sizeof(struct rite_section_irep_header), 1, fp) == 0) {
597  return MRB_DUMP_READ_FAULT;
598  }
599 
600  sirep = mrb->irep_len;
601  nirep = bin_to_uint16(header.nirep);
602 
603  buf_size = record_header_size;
604  /* You don't need use SIZE_ERROR as buf_size is enough small. */
605  buf = (uint8_t *)mrb_malloc(mrb, buf_size);
606  if (!buf) {
607  result = MRB_DUMP_GENERAL_FAILURE;
608  goto error_exit;
609  }
610 
611  //Read Binary Data Section
612  for (n = 0; n < nirep; n++) {
613  void *ptr;
614 
615  if (fread(buf, record_header_size, 1, fp) == 0) {
616  result = MRB_DUMP_READ_FAULT;
617  goto error_exit;
618  }
619  buf_size = bin_to_uint32(&buf[0]);
620  if (SIZE_ERROR(buf_size)) {
621  result = MRB_DUMP_GENERAL_FAILURE;
622  goto error_exit;
623  }
624  ptr = mrb_realloc(mrb, buf, buf_size);
625  if (!ptr) {
626  result = MRB_DUMP_GENERAL_FAILURE;
627  goto error_exit;
628  }
629  buf = (uint8_t *)ptr;
630 
631  if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) {
632  result = MRB_DUMP_READ_FAULT;
633  goto error_exit;
634  }
635  result = read_rite_irep_record(mrb, buf, &len);
636  if (result != MRB_DUMP_OK)
637  goto error_exit;
638  }
639 
640  result = nirep;
641 error_exit:
642  if (buf) {
643  mrb_free(mrb, buf);
644  }
645  if (result < MRB_DUMP_OK) {
646  irep_free(sirep, mrb);
647  }
648  return result;
649 }
650 
651 int32_t
652 mrb_read_irep_file(mrb_state *mrb, FILE* fp)
653 {
654  int result;
655  int32_t total_nirep = 0;
656  uint8_t *buf;
657  uint16_t crc, crcwk = 0;
658  uint32_t section_size = 0;
659  size_t nbytes;
660  size_t sirep;
661  struct rite_section_header section_header;
662  long fpos;
663  size_t block_size = 1 << 14;
664  const uint8_t block_fallback_count = 4;
665  int i;
666  const size_t buf_size = sizeof(struct rite_binary_header);
667 
668  if ((mrb == NULL) || (fp == NULL)) {
670  }
671 
672  /* You don't need use SIZE_ERROR as buf_size is enough small. */
673  buf = mrb_malloc(mrb, buf_size);
674  if (!buf) {
676  }
677  if (fread(buf, buf_size, 1, fp) == 0) {
678  mrb_free(mrb, buf);
679  return MRB_DUMP_READ_FAULT;
680  }
681  result = read_rite_binary_header(buf, NULL, &crc);
682  mrb_free(mrb, buf);
683  if (result != MRB_DUMP_OK) {
684  return result;
685  }
686 
687  /* verify CRC */
688  fpos = ftell(fp);
689  /* You don't need use SIZE_ERROR as block_size is enough small. */
690  for (i = 0; i < block_fallback_count; i++,block_size >>= 1){
691  buf = mrb_malloc_simple(mrb, block_size);
692  if (buf) break;
693  }
694  if (!buf) {
696  }
697  fseek(fp, offset_crc_body(), SEEK_SET);
698  while ((nbytes = fread(buf, 1, block_size, fp)) > 0) {
699  crcwk = calc_crc_16_ccitt(buf, nbytes, crcwk);
700  }
701  mrb_free(mrb, buf);
702  if (nbytes == 0 && ferror(fp)) {
703  return MRB_DUMP_READ_FAULT;
704  }
705  if (crcwk != crc) {
707  }
708  fseek(fp, fpos + section_size, SEEK_SET);
709  sirep = mrb->irep_len;
710 
711  // read sections
712  do {
713  fpos = ftell(fp);
714  if (fread(&section_header, sizeof(struct rite_section_header), 1, fp) == 0) {
715  return MRB_DUMP_READ_FAULT;
716  }
717  section_size = bin_to_uint32(section_header.section_size);
718 
719  if (memcmp(section_header.section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header.section_identify)) == 0) {
720  fseek(fp, fpos, SEEK_SET);
721  result = read_rite_section_irep_file(mrb, fp);
722  if (result < MRB_DUMP_OK) {
723  return result;
724  }
725  total_nirep += result;
726  }
727  else if (memcmp(section_header.section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header.section_identify)) == 0) {
728  fseek(fp, fpos, SEEK_SET);
729  result = read_rite_section_lineno_file(mrb, fp, sirep);
730  if (result < MRB_DUMP_OK) {
731  return result;
732  }
733  }
734  else if (memcmp(section_header.section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header.section_identify)) == 0) {
735  uint8_t* const bin = mrb_malloc(mrb, section_size);
736  fseek(fp, fpos, SEEK_SET);
737  if(fread((char*)bin, section_size, 1, fp) != 1) {
738  mrb_free(mrb, bin);
739  return MRB_DUMP_READ_FAULT;
740  }
741  result = read_rite_section_debug(mrb, bin, sirep);
742  mrb_free(mrb, bin);
743  if (result < MRB_DUMP_OK) {
744  return result;
745  }
746  }
747 
748  fseek(fp, fpos + section_size, SEEK_SET);
749  } while (memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0);
750 
751  return sirep;
752 }
753 
754 mrb_value
755 mrb_load_irep_file(mrb_state *mrb, FILE* fp)
756 {
757  int n = mrb_read_irep_file(mrb, fp);
758 
759  if (n < 0) {
760  irep_error(mrb, n);
761  return mrb_nil_value();
762  }
763  return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
764 }
765 #endif /* ENABLE_STDIO */