From ed0038fdf298750abeb9cf582f9576b3071e9411 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 21 Apr 2020 15:43:35 +0900 Subject: Simplified `mrb_obj_instance_eval`; ref #4973 --- src/vm.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index d7826230e..bcd846025 100644 --- a/src/vm.c +++ b/src/vm.c @@ -730,19 +730,8 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented"); } - switch (mrb_type(self)) { - case MRB_TT_SYMBOL: - case MRB_TT_FIXNUM: -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: -#endif - c = 0; - break; - default: - cv = mrb_singleton_class(mrb, self); - c = mrb_class_ptr(cv); - break; - } + cv = mrb_singleton_class(mrb, self); + c = mrb_class_ptr(cv); return eval_under(mrb, self, b, c); } -- cgit v1.2.3 From 61c6832b486ec4fc01353109c8c4085c88fa8f76 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 21 Apr 2020 15:44:21 +0900 Subject: Fix the bug by `#instance_eval` called via a method object; fix #4973 The tranpoline code in 6a0b68f8b was wrong; reverted. --- src/vm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index bcd846025..f8f4609bf 100644 --- a/src/vm.c +++ b/src/vm.c @@ -648,8 +648,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) } ci = mrb->c->ci; if (ci->acc == CI_ACC_DIRECT) { - ci->target_class = c; - return mrb_yield_cont(mrb, blk, self, 1, &self); + return mrb_yield_with_class(mrb, blk, 1, &self, self, c); } ci->target_class = c; p = mrb_proc_ptr(blk); -- cgit v1.2.3 From ab508e1e7f66d8e4eb6dd5f6a9cdf37c8c9e5005 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Apr 2020 16:47:26 +0900 Subject: Make `mrb_obj_instance_eval` to use `mrb_singleton_class_ptr`; #4973 --- src/vm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index f8f4609bf..85f28584c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -723,15 +723,11 @@ mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) { mrb_value a, b; - mrb_value cv; - struct RClass *c; if (mrb_get_args(mrb, "|S&", &a, &b) == 1) { mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented"); } - cv = mrb_singleton_class(mrb, self); - c = mrb_class_ptr(cv); - return eval_under(mrb, self, b, c); + return eval_under(mrb, self, b, mrb_singleton_class_ptr(mrb, self)); } MRB_API mrb_value -- cgit v1.2.3 From c143d87e7ce55092aa7b3578be3d525d5b311384 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 6 May 2020 15:49:06 +0900 Subject: Remove `mrb_run` from `MRB_API`; #4488 `mrb_run` requires to push callinfo stack before calling, which is very hard from outside of `vm.c`. So there should be virtually no correct usage of the function, hence the cause of #4488. We removed it. You can use `mrb_top_run(mrb, proc, self, 0)` instead of `mrb_run(mrb, proc self)`. --- include/mruby.h | 1 - src/vm.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vm.c') diff --git a/include/mruby.h b/include/mruby.h index eca7eb9cf..af7503375 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1150,7 +1150,6 @@ MRB_API void mrb_close(mrb_state *mrb); MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*); MRB_API mrb_value mrb_top_self(mrb_state *mrb); -MRB_API mrb_value mrb_run(mrb_state *mrb, struct RProc* proc, mrb_value self); MRB_API mrb_value mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep); MRB_API mrb_value mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep); MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *iseq); diff --git a/src/vm.c b/src/vm.c index 85f28584c..ea1bb5087 100644 --- a/src/vm.c +++ b/src/vm.c @@ -324,6 +324,7 @@ cipop(mrb_state *mrb) } void mrb_exc_set(mrb_state *mrb, mrb_value exc); +static mrb_value mrb_run(mrb_state *mrb, struct RProc* proc, mrb_value self); static void ecall(mrb_state *mrb) @@ -2808,7 +2809,7 @@ RETRY_TRY_BLOCK: MRB_END_EXC(&c_jmp); } -MRB_API mrb_value +static mrb_value mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) { if (mrb->c->ci->argc < 0) { -- cgit v1.2.3 From fa8668c77d181a5075dc56fb63d6fa087ab4b1d3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 17 Jan 2020 09:28:21 +0900 Subject: Add a new instruction `OP_LOADI16`. Which loads 16bit integer to the register. The instruction number should be reorder on massive instruction refactoring. The instruction is added for `mruby/c` which had performance issue with `OP_EXT`. With this instruction, `mruby/c` VM can just raise errors on `OP_EXT` extension instructions. --- include/mruby/ops.h | 1 + mrbgems/mruby-compiler/core/codegen.c | 21 ++++++++++++++++----- src/codedump.c | 4 ++++ src/vm.c | 5 +++++ 4 files changed, 26 insertions(+), 5 deletions(-) (limited to 'src/vm.c') diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 2327c33fd..c8990ae43 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -115,3 +115,4 @@ OPCODE(EXT1, Z) /* make 1st operand 16bit */ OPCODE(EXT2, Z) /* make 2nd operand 16bit */ OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */ OPCODE(STOP, Z) /* stop VM */ +OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 717d9eb9a..162666eb9 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2440,12 +2440,20 @@ codegen(codegen_scope *s, node *tree, int val) else #endif { - if (i == -1) genop_1(s, OP_LOADI__1, cursp()); - else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); + if (i < 0) { + if (i == -1) genop_1(s, OP_LOADI__1, cursp()); + else if (i >= -0xff) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); + else if (i >= -0x8000) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); + else goto lit_int; + } else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp()); - else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i); + else if (i <= 0xff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i); + else if (i <= 0xffff) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); else { - int off = new_lit(s, mrb_fixnum_value(i)); + int off; + + lit_int: + off = new_lit(s, mrb_fixnum_value(i)); genop_2(s, OP_LOADL, cursp(), off); } } @@ -2501,9 +2509,12 @@ codegen(codegen_scope *s, node *tree, int val) else { #endif if (i == -1) genop_1(s, OP_LOADI__1, cursp()); - else if (i >= -0xffff) { + else if (i >= -0xff) { genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); } + else if (i >= -0x8000) { + genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i); + } else { int off = new_lit(s, mrb_fixnum_value(i)); genop_2(s, OP_LOADL, cursp(), off); diff --git a/src/codedump.c b/src/codedump.c index 7faa39360..649be176b 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -130,6 +130,10 @@ codedump(mrb_state *mrb, mrb_irep *irep) printf("OP_LOADI\tR%d\t-%d\t", a, b); print_lv_a(mrb, irep, a); break; + CASE(OP_LOADI16, BS): + printf("OP_LOADI16\tR%d\t%d\t", a, (int)(int16_t)b); + print_lv_a(mrb, irep, a); + break; CASE(OP_LOADI__1, B): printf("OP_LOADI__1\tR%d\t\t", a); print_lv_a(mrb, irep, a); diff --git a/src/vm.c b/src/vm.c index ea1bb5087..26da5831e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1047,6 +1047,11 @@ RETRY_TRY_BLOCK: NEXT; } + CASE(OP_LOADI16, BS) { + SET_INT_VALUE(regs[a], (mrb_int)(int16_t)b); + NEXT; + } + CASE(OP_LOADSYM, BB) { SET_SYM_VALUE(regs[a], syms[b]); NEXT; -- cgit v1.2.3 From bd60ad98eb3ed48fc7bbe52ad5b879189c582bbd Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 10 May 2020 20:15:55 +0900 Subject: Get an irep symbol if it's `OP_GETSV` or `OP_SETSV` --- src/vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index 26da5831e..7bb153910 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1089,13 +1089,13 @@ RETRY_TRY_BLOCK: } CASE(OP_GETSV, BB) { - mrb_value val = mrb_vm_special_get(mrb, b); + mrb_value val = mrb_vm_special_get(mrb, syms[b]); regs[a] = val; NEXT; } CASE(OP_SETSV, BB) { - mrb_vm_special_set(mrb, b, regs[a]); + mrb_vm_special_set(mrb, syms[b], regs[a]); NEXT; } -- cgit v1.2.3 From 6f4c585bd73fc43fb9e34a70d74b5a50852600ea Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Sun, 24 May 2020 01:25:03 +0900 Subject: Do not destruct rest arguments for __send__ Formerly, `__send__(*args)` modified `args` with `Array#shift`. This bug affects optcarrot. This changeset avoids the array destruction by using `args = args[1, len-1]`. --- include/mruby/array.h | 3 +++ src/array.c | 7 +++++++ src/vm.c | 2 +- test/t/kernel.rb | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/vm.c') diff --git a/include/mruby/array.h b/include/mruby/array.h index fd4094a02..92c86a8c5 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -292,6 +292,9 @@ MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep); */ MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len); +/* helper functions */ +mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len); + MRB_END_DECL #endif /* MRUBY_ARRAY_H */ diff --git a/src/array.c b/src/array.c index 6e73bcd8e..ad0d5b8db 100644 --- a/src/array.c +++ b/src/array.c @@ -808,6 +808,13 @@ ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len) return mrb_obj_value(b); } +mrb_value +mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len) +{ + struct RArray *a = mrb_ary_ptr(ary); + return ary_subseq(mrb, a, beg, len); +} + static mrb_int aget_index(mrb_state *mrb, mrb_value index) { diff --git a/src/vm.c b/src/vm.c index 7bb153910..bd54f3f00 100644 --- a/src/vm.c +++ b/src/vm.c @@ -625,7 +625,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) ci->argc--; } else { /* variable length arguments */ - mrb_ary_shift(mrb, regs[0]); + regs[0] = mrb_ary_subseq(mrb, regs[0], 1, RARRAY_LEN(regs[0]) - 1); } if (MRB_METHOD_CFUNC_P(m)) { diff --git a/test/t/kernel.rb b/test/t/kernel.rb index aac6373fa..e3b9fe8ab 100644 --- a/test/t/kernel.rb +++ b/test/t/kernel.rb @@ -100,6 +100,10 @@ assert('Kernel#__send__', '15.3.1.3.4') do assert_true __send__(:respond_to?, :nil?) # test without argument and without block assert_equal String, __send__(:to_s).class + + args = [:respond_to?, :nil?] + assert_true __send__(*args) + assert_equal [:respond_to?, :nil?], args end assert('Kernel#block_given?', '15.3.1.3.6') do -- cgit v1.2.3 From d5cca2bdb2a0352e3253cf3ba2a79157dde5f163 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 28 May 2020 18:43:20 +0900 Subject: Check `c->eidx` before decrement in `ecall()`; close #4977 --- src/vm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index bd54f3f00..a280026f8 100644 --- a/src/vm.c +++ b/src/vm.c @@ -336,10 +336,12 @@ ecall(mrb_state *mrb) struct REnv *env; ptrdiff_t cioff; int ai = mrb_gc_arena_save(mrb); - uint16_t i = --c->eidx; + uint16_t i; int nregs; - if (i<0) return; + if (c->eidx == 0) return; + i = --c->eidx; + /* restrict total call depth of ecall() */ if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) { mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); -- cgit v1.2.3