|
21 | 21 | #include <mruby/error.h>
|
22 | 22 | #include <mruby/throw.h>
|
23 | 23 | #include <mruby/string.h>
|
| 24 | +#include <mruby/dump.h> |
24 | 25 | #include "node.h"
|
25 | 26 |
|
26 | 27 | #define YYLEX_PARAM p
|
@@ -4122,20 +4123,20 @@ static inline int
|
4122 | 4123 | nextc0(parser_state *p)
|
4123 | 4124 | {
|
4124 | 4125 | int c;
|
4125 |
| -#ifndef MRB_DISABLE_STDIO |
4126 |
| - if (p->f) { |
4127 |
| - if (feof(p->f)) return -1; |
4128 |
| - c = fgetc(p->f); |
4129 |
| - if (c == EOF) return -1; |
| 4126 | + |
| 4127 | + if (p->s && p->s < p->send) { |
| 4128 | + c = (unsigned char)*p->s++; |
4130 | 4129 | }
|
4131 |
| - else |
| 4130 | + else { |
| 4131 | +#ifndef MRB_DISABLE_STDIO |
| 4132 | + if (p->f) { |
| 4133 | + c = fgetc(p->f); |
| 4134 | + if (feof(p->f)) return -1; |
| 4135 | + } |
| 4136 | + else |
4132 | 4137 | #endif
|
4133 |
| - if (!p->s || p->s >= p->send) { |
4134 | 4138 | return -1;
|
4135 |
| - } |
4136 |
| - else { |
4137 |
| - c = (unsigned char)*p->s++; |
4138 |
| - } |
| 4139 | + } |
4139 | 4140 | return c;
|
4140 | 4141 | }
|
4141 | 4142 |
|
@@ -6520,19 +6521,26 @@ mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
|
6520 | 6521 | }
|
6521 | 6522 |
|
6522 | 6523 | #ifndef MRB_DISABLE_STDIO
|
6523 |
| -MRB_API parser_state* |
6524 |
| -mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c) |
| 6524 | +static struct mrb_parser_state * |
| 6525 | +mrb_parse_file_continue(mrb_state *mrb, FILE *f, const void *prebuf, size_t prebufsize, mrbc_context *c) |
6525 | 6526 | {
|
6526 | 6527 | parser_state *p;
|
6527 | 6528 |
|
6528 | 6529 | p = mrb_parser_new(mrb);
|
6529 | 6530 | if (!p) return NULL;
|
6530 |
| - p->s = p->send = NULL; |
| 6531 | + p->s = (const char *)prebuf; |
| 6532 | + p->send = (const char *)prebuf + prebufsize; |
6531 | 6533 | p->f = f;
|
6532 | 6534 |
|
6533 | 6535 | mrb_parser_parse(p, c);
|
6534 | 6536 | return p;
|
6535 | 6537 | }
|
| 6538 | + |
| 6539 | +MRB_API parser_state* |
| 6540 | +mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c) |
| 6541 | +{ |
| 6542 | + return mrb_parse_file_continue(mrb, f, NULL, 0, c); |
| 6543 | +} |
6536 | 6544 | #endif
|
6537 | 6545 |
|
6538 | 6546 | MRB_API parser_state*
|
@@ -6629,6 +6637,55 @@ mrb_load_file(mrb_state *mrb, FILE *f)
|
6629 | 6637 | {
|
6630 | 6638 | return mrb_load_file_cxt(mrb, f, NULL);
|
6631 | 6639 | }
|
| 6640 | + |
| 6641 | +#define DETECT_SIZE 64 |
| 6642 | + |
| 6643 | +/* |
| 6644 | + * In order to be recognized as a `.mrb` file, the following three points must be satisfied: |
| 6645 | + * - File starts with "RITE" |
| 6646 | + * - At least `sizeof(struct rite_binary_header)` bytes can be read |
| 6647 | + * - `NUL` is included in the first 64 bytes of the file |
| 6648 | + */ |
| 6649 | +MRB_API mrb_value |
| 6650 | +mrb_load_detect_file_cxt(mrb_state *mrb, FILE *fp, mrbc_context *c) |
| 6651 | +{ |
| 6652 | + union { |
| 6653 | + char b[DETECT_SIZE]; |
| 6654 | + struct rite_binary_header h; |
| 6655 | + } leading; |
| 6656 | + size_t bufsize; |
| 6657 | + |
| 6658 | + if (mrb == NULL || fp == NULL) { |
| 6659 | + return mrb_nil_value(); |
| 6660 | + } |
| 6661 | + |
| 6662 | + bufsize = fread(leading.b, sizeof(char), sizeof(leading), fp); |
| 6663 | + if (bufsize < sizeof(leading.h) || |
| 6664 | + memcmp(leading.h.binary_ident, RITE_BINARY_IDENT, sizeof(leading.h.binary_ident)) != 0 || |
| 6665 | + memchr(leading.b, '\0', bufsize) == NULL) { |
| 6666 | + return mrb_load_exec(mrb, mrb_parse_file_continue(mrb, fp, leading.b, bufsize, c), c); |
| 6667 | + } |
| 6668 | + else { |
| 6669 | + size_t binsize; |
| 6670 | + uint8_t *bin; |
| 6671 | + mrb_value bin_obj = mrb_nil_value(); /* temporary string object */ |
| 6672 | + mrb_value result; |
| 6673 | + |
| 6674 | + binsize = bin_to_uint32(leading.h.binary_size); |
| 6675 | + bin_obj = mrb_str_new(mrb, NULL, binsize); |
| 6676 | + bin = (uint8_t *)RSTRING_PTR(bin_obj); |
| 6677 | + memcpy(bin, leading.b, bufsize); |
| 6678 | + if (binsize > bufsize && |
| 6679 | + fread(bin + bufsize, binsize - bufsize, 1, fp) == 0) { |
| 6680 | + binsize = bufsize; |
| 6681 | + /* The error is reported by mrb_load_irep_buf_cxt() */ |
| 6682 | + } |
| 6683 | + |
| 6684 | + result = mrb_load_irep_buf_cxt(mrb, bin, binsize, c); |
| 6685 | + if (mrb_string_p(bin_obj)) mrb_str_resize(mrb, bin_obj, 0); |
| 6686 | + return result; |
| 6687 | + } |
| 6688 | +} |
6632 | 6689 | #endif
|
6633 | 6690 |
|
6634 | 6691 | MRB_API mrb_value
|
|
0 commit comments