From 0c9c3f08ee2c62f6f1b4ce9968a4d12e2ea60276 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 11 Apr 2019 21:42:18 +0900 Subject: Remove incorrect flags updating in `mrb_regexp_p()` --- src/etc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/etc.c b/src/etc.c index 6c5fb7480..d15b398dd 100644 --- a/src/etc.c +++ b/src/etc.c @@ -205,7 +205,6 @@ mrb_regexp_p(mrb_state *mrb, mrb_value v) return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS)); } else { - mrb->flags |= MRB_STATE_REGEXP; mrb->flags |= MRB_STATE_NO_REGEXP; } return FALSE; -- cgit v1.2.3 From 57e617620a4fa8b144dd87e94dc22ae2acd87679 Mon Sep 17 00:00:00 2001 From: Clayton Smith Date: Thu, 11 Apr 2019 20:07:43 -0400 Subject: Fix buffer overflows in parser. --- mrbgems/mruby-compiler/core/parse.y | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index cb62ec3f2..ca4c90770 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -3716,8 +3716,9 @@ yyerror_c(parser_state *p, const char *msg, char c) { char buf[256]; - strcpy(buf, msg); - strcat(buf, &c); + strncpy(buf, msg, sizeof(buf) - 2); + buf[sizeof(buf) - 2] = '\0'; + strncat(buf, &c, 1); yyerror(p, buf); } @@ -3760,9 +3761,10 @@ yywarning_s(parser_state *p, const char *msg, const char *s) { char buf[256]; - strcpy(buf, msg); - strcat(buf, ": "); - strcat(buf, s); + strncpy(buf, msg, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1); + strncat(buf, s, sizeof(buf) - strlen(buf) - 1); yywarning(p, buf); } @@ -4326,11 +4328,12 @@ parse_string(parser_state *p) if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) { yyerror(p, "can't find heredoc delimiter anywhere before EOF"); + } else { + strcpy(buf, s1); + strcat(buf, hinf->term); + strcat(buf, s2); + yyerror(p, buf); } - strcpy(buf, s1); - strcat(buf, hinf->term); - strcat(buf, s2); - yyerror(p, buf); return 0; } pylval.nd = new_str(p, tok(p), toklen(p)); @@ -4487,7 +4490,7 @@ parse_string(parser_state *p) strcat(msg, "s"); } strcat(msg, " - "); - strcat(msg, tok(p)); + strncat(msg, tok(p), sizeof(msg) - strlen(msg) - 1); yyerror(p, msg); } if (f != 0) { @@ -4918,7 +4921,7 @@ parser_yylex(parser_state *p) char cc = (char)c2; strcpy(buf, "invalid character syntax; use ?\\"); - strcat(buf, &cc); + strncat(buf, &cc, 1); yyerror(p, buf); } } @@ -6147,7 +6150,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) strcpy(buf, "line "); dump_int(p->error_buffer[0].lineno, buf+5); strcat(buf, ": "); - strcat(buf, p->error_buffer[0].message); + strncat(buf, p->error_buffer[0].message, sizeof(buf) - strlen(buf) - 1); mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, strlen(buf))); mrb_parser_free(p); return mrb_undef_value(); -- cgit v1.2.3 From 6626fbc5006d662f8fc69a51660ae7c1e998a1f0 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 12 Apr 2019 22:27:07 +0900 Subject: Refine `assert_float` Avoid arithmetic operations when `exp` and/or `act` are infinity or NaN. --- test/assert.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/assert.rb b/test/assert.rb index c57b04c12..e0fac4d90 100644 --- a/test/assert.rb +++ b/test/assert.rb @@ -149,11 +149,11 @@ end # Fails unless +exp+ is equal to +act+ in terms of a Float def assert_float(exp, act, msg = nil) e, a = exp.to_f, act.to_f - if (e.infinite? || a.infinite?) && e != a || + if e.finite? && a.finite? && (n = (e - a).abs) > Mrbtest::FLOAT_TOLERANCE + flunk(msg, " Expected |#{exp} - #{act}| (#{n}) to be <= #{Mrbtest::FLOAT_TOLERANCE}.") + elsif (e.infinite? || a.infinite?) && e != a || e.nan? && !a.nan? || !e.nan? && a.nan? flunk(msg, " Expected #{act} to be #{exp}.") - elsif (n = (e - a).abs) > Mrbtest::FLOAT_TOLERANCE - flunk(msg, " Expected |#{exp} - #{act}| (#{n}) to be <= #{Mrbtest::FLOAT_TOLERANCE}.") else pass end -- cgit v1.2.3 From 00545fc51d33a9c71d610cc8da5e779cf29487af Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 12 Apr 2019 22:52:26 +0900 Subject: The number of local variables should be less than 1024; fix #4370 The `env` stores stack length in a 10 bit field. See `MRB_ENV_STACK_LEN()` macro. --- mrbgems/mruby-compiler/core/codegen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 927cc3a0f..4bb81f415 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -3020,6 +3020,9 @@ scope_finish(codegen_scope *s) mrb_state *mrb = s->mrb; mrb_irep *irep = s->irep; + if (s->nlocals >= 0x3ff) { + codegen_error(s, "too many local variables"); + } irep->flags = 0; if (s->iseq) { irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc); -- cgit v1.2.3 From befdf59e610b43e7043b83074a2cc34070ae4e5f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 12 Apr 2019 22:54:25 +0900 Subject: Deallocate `s->lines` in `codegen_error`; ref #4370 --- mrbgems/mruby-compiler/core/codegen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 4bb81f415..b6d35f363 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -102,6 +102,7 @@ codegen_error(codegen_scope *s, const char *message) while (s->prev) { codegen_scope *tmp = s->prev; mrb_free(s->mrb, s->iseq); + mrb_free(s->mrb, s->lines); mrb_pool_close(s->mpool); s = tmp; } -- cgit v1.2.3 From 79fd986bcb2c6bc056a08669664c0024d77725f9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 12 Apr 2019 23:03:38 +0900 Subject: Small refactoring in `mrb_funcall_with_block`. --- src/vm.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vm.c b/src/vm.c index 60d5dee14..6bd9d53f9 100644 --- a/src/vm.c +++ b/src/vm.c @@ -486,6 +486,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ci->argc = (int)argc; ci->target_class = c; mrb->c->stack = mrb->c->stack + n; + if (argc < 0) argc = 1; if (mrb->c->stbase <= argv && argv < mrb->c->stend) { voff = argv - mrb->c->stbase; } @@ -500,11 +501,10 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ci->argc = -1; argc = 1; } - else { + else if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); ci->proc = p; - if (argc < 0) argc = 1; mrb_stack_extend(mrb, p->body.irep->nregs + argc); } if (voff >= 0) { @@ -520,9 +520,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc int ai = mrb_gc_arena_save(mrb); ci->acc = CI_ACC_DIRECT; - if (MRB_METHOD_PROC_P(m)) { - ci->proc = MRB_METHOD_PROC(m); - } val = MRB_METHOD_CFUNC(m)(mrb, self); mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); -- cgit v1.2.3 From f639da0f1c32c20255c32821191697d35350c1ad Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sat, 13 Apr 2019 18:16:28 +0900 Subject: Fix broken NaN with `MRB_NAN_BOXING` Example: $ bin/mruby -e '(Float::INFINITY - Float::INFINITY).nan?' zsh: segmentation fault Cause: `SET_FLOAT_VALUE` is not used. It is needed for normalizing NaN. Treatment: In my environment, this issue could be reproduced only when `infinity - infinity`, however `SET_FLOAT_VALUE` should be used in all arithmetic operations (regardless of boxing setting), I think. So I fixed all similar codes by extracting to macro. --- src/vm.c | 96 +++++++++++----------------------------------------------------- 1 file changed, 16 insertions(+), 80 deletions(-) diff --git a/src/vm.c b/src/vm.c index 6bd9d53f9..712d39b66 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2214,9 +2214,13 @@ RETRY_TRY_BLOCK: } #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) -#define OP_MATH_BODY(op,v1,v2) do {\ - v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ -} while(0) +#define OP_MATH_FLOAT_BODY(op,t1,t2) do { \ + RETURN_TYPE_OF_##t1 x = t1(regs[a]); \ + RETURN_TYPE_OF_##t2 y = t2(regs[a+1]); \ + SET_FLOAT_VALUE(mrb, regs[a], x op y); \ +} while (0) +#define RETURN_TYPE_OF_mrb_fixnum mrb_int +#define RETURN_TYPE_OF_mrb_float mrb_float CASE(OP_ADD, B) { /* need to check if op is overridden */ @@ -2239,33 +2243,13 @@ RETRY_TRY_BLOCK: break; #ifndef MRB_WITHOUT_FLOAT case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y); - } + OP_MATH_FLOAT_BODY(+,mrb_fixnum,mrb_float); break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x + y); - } -#else - OP_MATH_BODY(+,mrb_float,mrb_fixnum); -#endif + OP_MATH_FLOAT_BODY(+,mrb_float,mrb_fixnum); break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x + y); - } -#else - OP_MATH_BODY(+,mrb_float,mrb_float); -#endif + OP_MATH_FLOAT_BODY(+,mrb_float,mrb_float); break; #endif case TYPES2(MRB_TT_STRING,MRB_TT_STRING): @@ -2300,33 +2284,13 @@ RETRY_TRY_BLOCK: break; #ifndef MRB_WITHOUT_FLOAT case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y); - } + OP_MATH_FLOAT_BODY(-,mrb_fixnum,mrb_float); break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x - y); - } -#else - OP_MATH_BODY(-,mrb_float,mrb_fixnum); -#endif + OP_MATH_FLOAT_BODY(-,mrb_float,mrb_fixnum); break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x - y); - } -#else - OP_MATH_BODY(-,mrb_float,mrb_float); -#endif + OP_MATH_FLOAT_BODY(-,mrb_float,mrb_float); break; #endif default: @@ -2357,33 +2321,13 @@ RETRY_TRY_BLOCK: break; #ifndef MRB_WITHOUT_FLOAT case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y); - } + OP_MATH_FLOAT_BODY(*,mrb_fixnum,mrb_float); break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x * y); - } -#else - OP_MATH_BODY(*,mrb_float,mrb_fixnum); -#endif + OP_MATH_FLOAT_BODY(*,mrb_float,mrb_fixnum); break; case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x * y); - } -#else - OP_MATH_BODY(*,mrb_float,mrb_float); -#endif + OP_MATH_FLOAT_BODY(*,mrb_float,mrb_float); break; #endif default: @@ -2466,14 +2410,10 @@ RETRY_TRY_BLOCK: break; #ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING { mrb_float x = mrb_float(regs[a]); SET_FLOAT_VALUE(mrb, regs[a], x + b); } -#else - mrb_float(regs[a]) += b; -#endif break; #endif default: @@ -2507,14 +2447,10 @@ RETRY_TRY_BLOCK: break; #ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING { mrb_float x = mrb_float(regs[a]); SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b); } -#else - mrb_float(regs_a[0]) -= b; -#endif break; #endif default: -- cgit v1.2.3 From 0ebbc491a1ce45b85934be04e5824d69463ca593 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Apr 2019 15:35:51 +0900 Subject: Include `RFiber` and `RIstruct` as a part of `RVALUE` --- src/gc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gc.c b/src/gc.c index ec52787e8..798e2c00a 100644 --- a/src/gc.c +++ b/src/gc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -109,8 +110,10 @@ typedef struct { struct RHash hash; struct RRange range; struct RData data; + struct RIstruct istruct; struct RProc proc; struct REnv env; + struct RFiber fiber; struct RException exc; struct RBreak brk; #ifdef MRB_WORD_BOXING -- cgit v1.2.3 From c2fa935fee31c201ba4b07e72690e78a3094cf68 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Apr 2019 16:11:21 +0900 Subject: Fix hexdigits convertion --- mrbgems/mruby-compiler/core/parse.y | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index ca4c90770..f6b883b9e 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -5712,10 +5712,11 @@ parser_yylex(parser_state *p) if (!identchar(c)) { char buf[36]; const char s[] = "Invalid char in expression: 0x"; + const char hexdigits[] = "0123456789ABCDEF"; strcpy(buf, s); - buf[sizeof(s)] = (c & 0xff00) >> 8; - buf[sizeof(s)+1] = (c & 0xff); + buf[sizeof(s)] = hexdigits[(c & 0xf0) >> 4]; + buf[sizeof(s)+1] = hexdigits[(c & 0x0f)]; buf[sizeof(s)+2] = 0; yyerror(p, buf); goto retry; -- cgit v1.2.3 From dac0f3f5e85d067b15c44a933b151acefb2d5598 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Apr 2019 16:16:05 +0900 Subject: Fix string index for appending `sizeof(string-literal)` is included `'\0'` character --- mrbgems/mruby-compiler/core/parse.y | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index f6b883b9e..7838b6dfb 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -5715,9 +5715,9 @@ parser_yylex(parser_state *p) const char hexdigits[] = "0123456789ABCDEF"; strcpy(buf, s); - buf[sizeof(s)] = hexdigits[(c & 0xf0) >> 4]; - buf[sizeof(s)+1] = hexdigits[(c & 0x0f)]; - buf[sizeof(s)+2] = 0; + buf[sizeof(s)-1] = hexdigits[(c & 0xf0) >> 4]; + buf[sizeof(s)] = hexdigits[(c & 0x0f)]; + buf[sizeof(s)+1] = 0; yyerror(p, buf); goto retry; } -- cgit v1.2.3 From 3f3e4754d931004838278c1483e047a3635ebeb0 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Apr 2019 15:58:11 +0900 Subject: Fix leaked function symbols - `free_heap()` in src/gc.c - `symhash()` in src/symbol.c - `no_optimize()` in mrbgems/mruby-compiler/core/codegen.c --- mrbgems/mruby-compiler/core/codegen.c | 3 +-- src/gc.c | 2 +- src/symbol.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index b6d35f363..ed8fc3150 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -273,8 +273,7 @@ genop_W(codegen_scope *s, mrb_code i, uint32_t a) #define NOVAL 0 #define VAL 1 -//static -mrb_bool +static mrb_bool no_optimize(codegen_scope *s) { if (s && s->parser && s->parser->no_optimize) diff --git a/src/gc.c b/src/gc.c index ec52787e8..d07335eca 100644 --- a/src/gc.c +++ b/src/gc.c @@ -396,7 +396,7 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc) static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); -void +static void free_heap(mrb_state *mrb, mrb_gc *gc) { mrb_heap_page *page = gc->heaps; diff --git a/src/symbol.c b/src/symbol.c index 96ca9dd17..b26f2b1fd 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -91,7 +91,7 @@ sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp) } #endif -uint8_t +static uint8_t symhash(const char *key, size_t len) { uint32_t hash, i; -- cgit v1.2.3 From d557f977324bc55ae99205608099a788038712d6 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Apr 2019 17:39:50 +0900 Subject: Remove pointer check after `mrb_malloc()` --- src/variable.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/variable.c b/src/variable.c index f97b09c52..6899d7475 100644 --- a/src/variable.c +++ b/src/variable.c @@ -87,7 +87,6 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) } seg = (segment*)mrb_malloc(mrb, sizeof(segment)); - if (!seg) return; seg->next = NULL; seg->key[0] = sym; seg->val[0] = val; -- cgit v1.2.3 From d8527d17ea504aebcdbd3970127899e0216d46dc Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Apr 2019 17:42:35 +0900 Subject: Fix wrong size of instance variable if occur out of memory --- src/variable.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/variable.c b/src/variable.c index 6899d7475..983fe52f7 100644 --- a/src/variable.c +++ b/src/variable.c @@ -79,10 +79,10 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) } /* Not found */ - t->size++; if (matched_seg) { matched_seg->key[matched_idx] = sym; matched_seg->val[matched_idx] = val; + t->size++; return; } @@ -91,6 +91,7 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) seg->key[0] = sym; seg->val[0] = val; t->last_len = 1; + t->size++; if (prev) { prev->next = seg; } -- cgit v1.2.3 From d328808892bf866f9ad72ba476fcee00edd06293 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 14 Apr 2019 17:55:20 +0900 Subject: Fix memory leak for hash table index if occur out of memory --- src/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hash.c b/src/hash.c index c4820513b..a9367a426 100644 --- a/src/hash.c +++ b/src/hash.c @@ -182,7 +182,7 @@ ht_index(mrb_state *mrb, htable *t) if (!index || index->capa < size) { index = (segindex*)mrb_realloc_simple(mrb, index, sizeof(segindex)+sizeof(struct segkv*)*size); if (index == NULL) { - mrb_free(mrb, index); + mrb_free(mrb, t->index); t->index = NULL; return; } -- cgit v1.2.3 From 30c880bea9ace559ccef50d5ed1a5dbf75659bbf Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sun, 14 Apr 2019 22:40:17 +0900 Subject: Extract similar codes to macros for math opcode in `mrb_vm_exec` --- src/vm.c | 269 +++++++++++++++++++++------------------------------------------ 1 file changed, 89 insertions(+), 180 deletions(-) diff --git a/src/vm.c b/src/vm.c index 712d39b66..a7ecc575d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2214,128 +2214,67 @@ RETRY_TRY_BLOCK: } #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) -#define OP_MATH_FLOAT_BODY(op,t1,t2) do { \ - RETURN_TYPE_OF_##t1 x = t1(regs[a]); \ - RETURN_TYPE_OF_##t2 y = t2(regs[a+1]); \ - SET_FLOAT_VALUE(mrb, regs[a], x op y); \ -} while (0) -#define RETURN_TYPE_OF_mrb_fixnum mrb_int -#define RETURN_TYPE_OF_mrb_float mrb_float +#define OP_MATH(op_name) \ + /* need to check if op is overridden */ \ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \ + OP_MATH_CASE_FIXNUM(op_name); \ + OP_MATH_CASE_FLOAT(op_name, fixnum, float); \ + OP_MATH_CASE_FLOAT(op_name, float, fixnum); \ + OP_MATH_CASE_FLOAT(op_name, float, float); \ + OP_MATH_CASE_STRING_##op_name(); \ + default: \ + c = 1; \ + mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ + goto L_SEND_SYM; \ + } \ + NEXT; +#define OP_MATH_CASE_FIXNUM(op_name) \ + case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM): \ + { \ + mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z; \ + if (mrb_int_##op_name##_overflow(x, y, &z)) \ + OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ + else \ + SET_INT_VALUE(regs[a], z); \ + } \ + break +#ifdef MRB_WITHOUT_FLOAT +#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0 +#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z) +#else +#define OP_MATH_CASE_FLOAT(op_name, t1, t2) \ + case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \ + { \ + mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \ + SET_FLOAT_VALUE(mrb, regs[a], z); \ + } \ + break +#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \ + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y) +#endif +#define OP_MATH_CASE_STRING_add() \ + case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \ + regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \ + mrb_gc_arena_restore(mrb, ai); \ + break +#define OP_MATH_CASE_STRING_sub() (void)0 +#define OP_MATH_CASE_STRING_mul() (void)0 +#define OP_MATH_OP_add + +#define OP_MATH_OP_sub - +#define OP_MATH_OP_mul * +#define OP_MATH_TT_fixnum MRB_TT_FIXNUM +#define OP_MATH_TT_float MRB_TT_FLOAT CASE(OP_ADD, B) { - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - mrb_value *regs_a = regs + a; - - x = mrb_fixnum(regs_a[0]); - y = mrb_fixnum(regs_a[1]); - if (mrb_int_add_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - OP_MATH_FLOAT_BODY(+,mrb_fixnum,mrb_float); - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): - OP_MATH_FLOAT_BODY(+,mrb_float,mrb_fixnum); - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): - OP_MATH_FLOAT_BODY(+,mrb_float,mrb_float); - break; -#endif - case TYPES2(MRB_TT_STRING,MRB_TT_STRING): - regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); - break; - default: - c = 1; - mid = mrb_intern_lit(mrb, "+"); - goto L_SEND_SYM; - } - mrb_gc_arena_restore(mrb, ai); - NEXT; + OP_MATH(add); } CASE(OP_SUB, B) { - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - - x = mrb_fixnum(regs[a]); - y = mrb_fixnum(regs[a+1]); - if (mrb_int_sub_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - OP_MATH_FLOAT_BODY(-,mrb_fixnum,mrb_float); - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): - OP_MATH_FLOAT_BODY(-,mrb_float,mrb_fixnum); - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): - OP_MATH_FLOAT_BODY(-,mrb_float,mrb_float); - break; -#endif - default: - c = 1; - mid = mrb_intern_lit(mrb, "-"); - goto L_SEND_SYM; - } - NEXT; + OP_MATH(sub); } CASE(OP_MUL, B) { - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - - x = mrb_fixnum(regs[a]); - y = mrb_fixnum(regs[a+1]); - if (mrb_int_mul_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - OP_MATH_FLOAT_BODY(*,mrb_fixnum,mrb_float); - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): - OP_MATH_FLOAT_BODY(*,mrb_float,mrb_fixnum); - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): - OP_MATH_FLOAT_BODY(*,mrb_float,mrb_float); - break; -#endif - default: - c = 1; - mid = mrb_intern_lit(mrb, "*"); - goto L_SEND_SYM; - } - NEXT; + OP_MATH(mul); } CASE(OP_DIV, B) { @@ -2390,76 +2329,46 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_ADDI, BB) { - /* need to check if + is overridden */ - switch (mrb_type(regs[a])) { - case MRB_TT_FIXNUM: - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_int y = (mrb_int)b; - mrb_int z; - - if (mrb_int_add_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: - { - mrb_float x = mrb_float(regs[a]); - SET_FLOAT_VALUE(mrb, regs[a], x + b); - } - break; +#define OP_MATHI(op_name) \ + /* need to check if op is overridden */ \ + switch (mrb_type(regs[a])) { \ + OP_MATHI_CASE_FIXNUM(op_name); \ + OP_MATHI_CASE_FLOAT(op_name); \ + default: \ + SET_INT_VALUE(regs[a+1], b); \ + c = 1; \ + mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ + goto L_SEND_SYM; \ + } \ + NEXT; +#define OP_MATHI_CASE_FIXNUM(op_name) \ + case MRB_TT_FIXNUM: \ + { \ + mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z; \ + if (mrb_int_##op_name##_overflow(x, y, &z)) \ + OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ + else \ + SET_INT_VALUE(regs[a], z); \ + } \ + break +#ifdef MRB_WITHOUT_FLOAT +#define OP_MATHI_CASE_FLOAT(op_name) (void)0 +#else +#define OP_MATHI_CASE_FLOAT(op_name) \ + case MRB_TT_FLOAT: \ + { \ + mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b; \ + SET_FLOAT_VALUE(mrb, regs[a], z); \ + } \ + break #endif - default: - SET_INT_VALUE(regs[a+1], b); - c = 1; - mid = mrb_intern_lit(mrb, "+"); - goto L_SEND_SYM; - } - NEXT; + + CASE(OP_ADDI, BB) { + OP_MATHI(add); } CASE(OP_SUBI, BB) { - mrb_value *regs_a = regs + a; - - /* need to check if + is overridden */ - switch (mrb_type(regs_a[0])) { - case MRB_TT_FIXNUM: - { - mrb_int x = mrb_fixnum(regs_a[0]); - mrb_int y = (mrb_int)b; - mrb_int z; - - if (mrb_int_sub_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs_a[0], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: - { - mrb_float x = mrb_float(regs[a]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b); - } - break; -#endif - default: - SET_INT_VALUE(regs_a[1], b); - c = 1; - mid = mrb_intern_lit(mrb, "-"); - goto L_SEND_SYM; - } - NEXT; + OP_MATHI(sub); } #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) -- cgit v1.2.3 From 6b8d3c70702948e630536e7c42400e928ed9d773 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 15 Apr 2019 07:13:19 +0900 Subject: Fixed wrong function names; fix #4380 --- src/numeric.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/numeric.c b/src/numeric.c index 742df7b76..8205e41f6 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -510,7 +510,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) } static mrb_value -flo_lshift(mrb_state *mrb, mrb_value x) +flo_rshift(mrb_state *mrb, mrb_value x) { mrb_int width; @@ -519,7 +519,7 @@ flo_lshift(mrb_state *mrb, mrb_value x) } static mrb_value -flo_rshift(mrb_state *mrb, mrb_value x) +flo_lshift(mrb_state *mrb, mrb_value x) { mrb_int width; @@ -1608,8 +1608,8 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fl, "&", flo_and, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, ">>", flo_lshift, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "<<", flo_rshift, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, ">>", flo_rshift, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, "<<", flo_lshift, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */ mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_NONE()); /* 15.2.9.3.10 */ -- cgit v1.2.3 From d53eb8a3779735dc5df8a57f11f150cddf96e877 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Mon, 15 Apr 2019 19:03:39 +0900 Subject: Fix missing assertions in `mruby-random` test --- mrbgems/mruby-random/test/random.rb | 70 ++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/mrbgems/mruby-random/test/random.rb b/mrbgems/mruby-random/test/random.rb index 1653ae4a6..813e23968 100644 --- a/mrbgems/mruby-random/test/random.rb +++ b/mrbgems/mruby-random/test/random.rb @@ -1,48 +1,66 @@ ## # Random Test -assert("Random#srand") do +assert("Random.new") do r1 = Random.new(123) r2 = Random.new(123) - r1.rand == r2.rand + r3 = Random.new(124) + assert_equal(r1.rand, r2.rand) + assert_not_equal(r1.rand, r3.rand) end -assert("Kernel::srand") do +assert("Kernel.srand") do srand(234) r1 = rand srand(234) r2 = rand - r1 == r2 + srand(235) + r3 = rand + assert_equal(r1, r2) + assert_not_equal(r1, r3) end -assert("Random::srand") do +assert("Random.srand") do Random.srand(345) r1 = rand srand(345) r2 = Random.rand - r1 == r2 + Random.srand(346) + r3 = rand + assert_equal(r1, r2) + assert_not_equal(r1, r3) end -assert("fixnum") do - rand(3).class == Fixnum -end - -assert("float") do - rand.class == Float +assert("return class of Kernel.rand") do + assert_kind_of(Fixnum, rand(3)) + assert_kind_of(Fixnum, rand(1.5)) + assert_kind_of(Float, rand) + assert_kind_of(Float, rand(0.5)) end assert("Array#shuffle") do ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + orig = ary.dup shuffled = ary.shuffle - - ary == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and shuffled != ary and 10.times { |x| ary.include? x } + assert_equal(orig, ary) + assert_not_equal(ary, shuffled) + assert_equal(ary.size, shuffled.size) + shuffled.each do |x| + assert_include(ary, x) + ary.delete(x) + end end assert('Array#shuffle!') do ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ary.shuffle! - - ary != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary.include? x } + orig = ary.dup + assert_same(ary, ary.shuffle!) + assert_not_equal(orig, ary) + assert_equal(orig.size, ary.size) + ary.each do |x| + assert_include(orig, x) + orig.delete(x) + end end assert("Array#shuffle(random)") do @@ -52,12 +70,12 @@ assert("Array#shuffle(random)") do end # verify that the same seed causes the same results - ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - shuffle1 = ary1.shuffle Random.new 345 - ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - shuffle2 = ary2.shuffle Random.new 345 - - ary1 != shuffle1 and 10.times { |x| shuffle1.include? x } and shuffle1 == shuffle2 + ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + shuffled1 = ary.shuffle Random.new 345 + shuffled2 = ary.shuffle Random.new 345 + shuffled3 = ary.shuffle Random.new 346 + assert_equal(shuffled1, shuffled2) + assert_not_equal(shuffled1, shuffled3) end assert('Array#shuffle!(random)') do @@ -71,6 +89,8 @@ assert('Array#shuffle!(random)') do ary1.shuffle! Random.new 345 ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ary2.shuffle! Random.new 345 - - ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2 + ary3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ary3.shuffle! Random.new 346 + assert_equal(ary1, ary2) + assert_not_equal(ary1, ary3) end -- cgit v1.2.3