diff options
| -rw-r--r-- | include/mruby/compile.h | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 28 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 9 | ||||
| -rw-r--r-- | src/gc.c | 30 | ||||
| -rw-r--r-- | src/numeric.c | 4 | ||||
| -rw-r--r-- | src/string.c | 8 | ||||
| -rw-r--r-- | test/t/codegen.rb | 28 |
7 files changed, 81 insertions, 28 deletions
diff --git a/include/mruby/compile.h b/include/mruby/compile.h index 3ccaf9f6a..ad3f19db1 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -163,6 +163,7 @@ struct mrb_parser_state { MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*); MRB_API void mrb_parser_free(struct mrb_parser_state*); MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*); +MRB_API double mrb_float_read(const char*, char**); MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*); MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx); @@ -174,6 +175,7 @@ MRB_API struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*); MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*); MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mrbc_context*); MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*); +MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c); /* program load functions */ #ifndef MRB_DISABLE_STDIO diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index b2cd12225..38da952b4 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -818,8 +818,6 @@ gen_values(codegen_scope *s, node *t, int val) } } else { - codegen(s, t->car->cdr, NOVAL); - t = t->cdr; while (t) { codegen(s, t->car, NOVAL); t = t->cdr; @@ -2223,6 +2221,10 @@ codegen(codegen_scope *s, node *tree, int val) { nt = (intptr_t)tree->car; tree = tree->cdr; + if (!val) { + codegen(s, tree, NOVAL); + break; + } switch (nt) { case NODE_FLOAT: { @@ -2560,13 +2562,31 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_A(OP_TCLASS, cursp())); push(); while (t) { - int symbol = new_msym(s, sym(t->car)); + int symbol; + if (num >= CALL_MAXARGS - 1) { + pop_n(num); + genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num)); + while (t) { + symbol = new_msym(s, sym(t->car)); + push(); + genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); + pop(); + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + t = t->cdr; + } + num = CALL_MAXARGS; + break; + } + symbol = new_msym(s, sym(t->car)); genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); push(); t = t->cdr; num++; } - pop_n(num + 1); + pop(); + if (num < CALL_MAXARGS) { + pop_n(num); + } genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num)); if (val) { push(); diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 05b948f8e..ee3373fbf 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -3946,6 +3946,7 @@ parse_string(parser_state *p) } } if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) { + if (c < 0) p->parsing_heredoc = NULL; return tHEREDOC_END; } } @@ -5692,8 +5693,8 @@ mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c) return mrb_parse_nstring(mrb, s, strlen(s), c); } -static mrb_value -load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) +MRB_API mrb_value +mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) { struct RClass *target = mrb->object_class; struct RProc *proc; @@ -5752,7 +5753,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) MRB_API mrb_value mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c) { - return load_exec(mrb, mrb_parse_file(mrb, f, c), c); + return mrb_load_exec(mrb, mrb_parse_file(mrb, f, c), c); } MRB_API mrb_value @@ -5765,7 +5766,7 @@ mrb_load_file(mrb_state *mrb, FILE *f) MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c) { - return load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c); + return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c); } MRB_API mrb_value @@ -453,7 +453,7 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj) mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); mrb_value table = mrb_gv_get(mrb, root); struct RArray *a; - mrb_int i, len; + mrb_int i; if (mrb_nil_p(table)) return; if (mrb_type(table) != MRB_TT_ARRAY) { @@ -462,14 +462,13 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj) } a = mrb_ary_ptr(table); mrb_ary_modify(mrb, a); - len = a->len-1; - for (i=0; i<len; i++) { + for (i = 0; i < a->len; i++) { if (mrb_obj_eq(mrb, a->ptr[i], obj)) { - memmove(&a->ptr[i], &a->ptr[i+1], len-i); + a->len--; + memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i])); break; } } - a->len--; } MRB_API struct RBasic* @@ -742,10 +741,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj) { struct REnv *e = (struct REnv*)obj; - if (!MRB_ENV_STACK_SHARED_P(e)) { - mrb_free(mrb, e->stack); - e->stack = NULL; + if (MRB_ENV_STACK_SHARED_P(e)) { + /* cannot be freed */ + return; } + mrb_free(mrb, e->stack); + e->stack = NULL; } break; @@ -1019,15 +1020,20 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) if (is_dead(gc, &p->as.basic)) { if (p->as.basic.tt != MRB_TT_FREE) { obj_free(mrb, &p->as.basic); - p->as.free.next = page->freelist; - page->freelist = (struct RBasic*)p; - freed++; + if (p->as.basic.tt == MRB_TT_FREE) { + p->as.free.next = page->freelist; + page->freelist = (struct RBasic*)p; + freed++; + } + else { + dead_slot = FALSE; + } } } else { if (!is_generational(gc)) paint_partial_white(gc, &p->as.basic); /* next gc target */ - dead_slot = 0; + dead_slot = FALSE; } p++; } diff --git a/src/numeric.c b/src/numeric.c index 25a411de8..a9a2a641b 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -357,7 +357,11 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) while (width++) { val /= 2; } +#if defined(_ISOC99_SOURCE) val = trunc(val); +#else + val = val > 0 ? floor(val) : ceil(val); +#endif if (val == 0 && mrb_float(x) < 0) { return mrb_fixnum_value(-1); } diff --git a/src/string.c b/src/string.c index a9351619b..a4f8085ec 100644 --- a/src/string.c +++ b/src/string.c @@ -2770,14 +2770,6 @@ mrb_init_string(mrb_state *mrb) #include <ctype.h> #include <errno.h> -#ifndef __STDC__ -# ifdef __GNUC__ -# define const __const__ -# else -# define const -# endif -#endif - static const int maxExponent = 511; /* Largest possible base 10 exponent. Any * exponent larger than this will already * produce underflow or overflow, so there's diff --git a/test/t/codegen.rb b/test/t/codegen.rb index bb0f5c306..709902741 100644 --- a/test/t/codegen.rb +++ b/test/t/codegen.rb @@ -63,3 +63,31 @@ assert('splat in case splat') do assert_equal [1], a end + +assert('undef with 127 or more arguments') do + assert_raise NameError do + undef + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a + end +end + +assert('next in normal loop with 127 arguments') do + assert_raise NameError do + while true + next A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A + end + end +end + +assert('negate literal register alignment') do + a = *case + when 0 + -0.0 + 2 + end + + assert_equal [2], a +end |
