summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-compiler/core/parse.y41
-rw-r--r--src/vm.c5
2 files changed, 27 insertions, 19 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 0a5eb2a7b..6a1faf4ed 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -3967,6 +3967,27 @@ static mrb_bool peeks(parser_state *p, const char *s);
static mrb_bool skips(parser_state *p, const char *s);
static inline int
+nextc0(parser_state *p)
+{
+ int c;
+#ifndef MRB_DISABLE_STDIO
+ if (p->f) {
+ if (feof(p->f)) return -1;
+ c = fgetc(p->f);
+ if (c == EOF) return -1;
+ }
+ else
+#endif
+ if (!p->s || p->s >= p->send) {
+ return -1;
+ }
+ else {
+ c = (unsigned char)*p->s++;
+ }
+ return c;
+}
+
+static inline int
nextc(parser_state *p)
{
int c;
@@ -3980,30 +4001,18 @@ nextc(parser_state *p)
cons_free(tmp);
}
else {
-#ifndef MRB_DISABLE_STDIO
- if (p->f) {
- if (feof(p->f)) goto eof;
- c = fgetc(p->f);
- if (c == EOF) goto eof;
- }
- else
-#endif
- if (!p->s || p->s >= p->send) {
- goto eof;
- }
- else {
- c = (unsigned char)*p->s++;
- }
+ c = nextc0(p);
+ if (c < 0) goto eof;
}
if (c >= 0) {
p->column++;
}
if (c == '\r') {
- const int lf = nextc(p);
+ const int lf = nextc0(p);
if (lf == '\n') {
return '\n';
}
- pushback(p, lf);
+ if (lf > 0) pushback(p, lf);
}
return c;
diff --git a/src/vm.c b/src/vm.c
index 214907a19..d7826230e 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -430,6 +430,7 @@ MRB_API mrb_value
mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk)
{
mrb_value val;
+ int ai = mrb_gc_arena_save(mrb);
if (!mrb->jmp) {
struct mrb_jmpbuf c_jmp;
@@ -518,19 +519,17 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
mrb->c->stack[argc+1] = blk;
if (MRB_METHOD_CFUNC_P(m)) {
- int ai = mrb_gc_arena_save(mrb);
-
ci->acc = CI_ACC_DIRECT;
val = MRB_METHOD_CFUNC(m)(mrb, self);
mrb->c->stack = mrb->c->ci->stackent;
cipop(mrb);
- mrb_gc_arena_restore(mrb, ai);
}
else {
ci->acc = CI_ACC_SKIP;
val = mrb_run(mrb, MRB_METHOD_PROC(m), self);
}
}
+ mrb_gc_arena_restore(mrb, ai);
mrb_gc_protect(mrb, val);
return val;
}