From 8558627b9bb99635ebaaaa06bdbbebda4d4aef39 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 31 Jul 2018 16:48:50 +0900 Subject: Reorganize flags values for classes; fix #3975 Renamed flag macro names as well: `MRB_FLAG_IS_FROZEN` -> `MRB_FL_OBJ_FROZEN` `MRB_FLAG_IS_PREPENDED` -> `MRB_FL_CLASS_IS_PREPENDED` `MRB_FLAG_IS_ORIGIN` -> `MRB_FL_CLASS_IS_ORIGIN` `MRB_FLAG_IS_INHERITED` -> `MRB_FL_CLASS_IS_INHERITED` --- src/gc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index 69121d630..c52641959 100644 --- a/src/gc.c +++ b/src/gc.c @@ -622,7 +622,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_ICLASS: { struct RClass *c = (struct RClass*)obj; - if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN)) + if (MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_ORIGIN)) mrb_gc_mark_mt(mrb, c); mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); } @@ -761,7 +761,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) mrb_gc_free_iv(mrb, (struct RObject*)obj); break; case MRB_TT_ICLASS: - if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN)) + if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) mrb_gc_free_mt(mrb, (struct RClass*)obj); break; case MRB_TT_ENV: -- cgit v1.2.3 From b9817b00a4644bc2905be918e429fb1b78796fd4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 1 Aug 2018 13:18:32 +0900 Subject: Remove `nregs` member from `mrb_callinfo`. This means reducing one word per a call frame. --- include/mruby.h | 1 - mrbgems/mruby-fiber/src/fiber.c | 1 - src/gc.c | 32 +++++++++++--- src/vm.c | 97 ++++++++++++++++++++++++----------------- 4 files changed, 83 insertions(+), 48 deletions(-) (limited to 'src/gc.c') diff --git a/include/mruby.h b/include/mruby.h index b0bfe78b5..93fc0f010 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -123,7 +123,6 @@ typedef struct { mrb_sym mid; struct RProc *proc; mrb_value *stackent; - int nregs; int ridx; int epos; struct REnv *env; diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 27b74dba5..17ce77c5d 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -127,7 +127,6 @@ fiber_init(mrb_state *mrb, mrb_value self) ci->proc = p; mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); ci->pc = p->body.irep->iseq; - ci->nregs = p->body.irep->nregs; ci[1] = ci[0]; c->ci++; /* push dummy callinfo */ diff --git a/src/gc.c b/src/gc.c index c52641959..33d83f28e 100644 --- a/src/gc.c +++ b/src/gc.c @@ -548,21 +548,39 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) gc->gray_list = obj; } +static int +ci_nregs(mrb_callinfo *ci) +{ + struct RProc *p = ci->proc; + int n = 0; + + if (!p) { + if (ci->argc < 0) return 3; + return ci->argc+2; + } + if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { + n = p->body.irep->nregs; + } + if (ci->argc < 0) { + if (n < 3) n = 3; /* self + args + blk */ + } + if (ci->argc > n) { + n = ci->argc + 2; /* self + blk */ + } + return n; +} + static void mark_context_stack(mrb_state *mrb, struct mrb_context *c) { size_t i; size_t e; mrb_value nil; - mrb_int nregs; if (c->stack == NULL) return; e = c->stack - c->stbase; if (c->ci) { - nregs = c->ci->argc + 2; - if (c->ci->nregs > nregs) - nregs = c->ci->nregs; - e += nregs; + e += ci_nregs(c->ci); } if (c->stbase + e > c->stend) e = c->stend - c->stbase; for (i=0; istack - c->stbase; - if (c->ci) i += c->ci->nregs; + if (c->ci) { + i += ci_nregs(c->ci); + } if (c->stbase + i > c->stend) i = c->stend - c->stbase; children += i; diff --git a/src/vm.c b/src/vm.c index 7a436828a..066c6ba2e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -356,7 +356,6 @@ ecall(mrb_state *mrb) ci->acc = CI_ACC_SKIP; ci->argc = 0; ci->proc = p; - ci->nregs = p->body.irep->nregs; ci->target_class = MRB_PROC_TARGET_CLASS(p); env = MRB_PROC_ENV(p); mrb_assert(env); @@ -396,6 +395,30 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) return mrb_funcall_argv(mrb, self, mid, argc, argv); } +static int +ci_nregs(mrb_callinfo *ci) +{ + struct RProc *p; + int n = 0; + + if (!ci) return 3; + p = ci->proc; + if (!p) { + if (ci->argc < 0) return 3; + return ci->argc+2; + } + if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { + n = p->body.irep->nregs; + } + if (ci->argc < 0) { + if (n < 3) n = 3; /* self + args + blk */ + } + if (ci->argc > n) { + n = ci->argc + 2; /* self + blk */ + } + return n; +} + 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) { @@ -426,13 +449,12 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb_method_t m; struct RClass *c; mrb_callinfo *ci; - int n; + int n = ci_nregs(mrb->c->ci); ptrdiff_t voff = -1; if (!mrb->c->stack) { stack_init(mrb); } - n = mrb->c->ci->nregs; if (argc < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc)); } @@ -463,22 +485,22 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc voff = argv - mrb->c->stbase; } if (MRB_METHOD_CFUNC_P(m)) { - ci->nregs = (int)(argc + 2); - mrb_stack_extend(mrb, ci->nregs); + mrb_stack_extend(mrb, argc + 2); } else if (argc >= CALL_MAXARGS) { mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - mrb_stack_extend(mrb, ci->nregs+2); + + mrb_stack_extend(mrb, 3); mrb->c->stack[1] = args; ci->argc = -1; argc = 1; } else { struct RProc *p = MRB_METHOD_PROC(m); + ci->proc = p; if (argc < 0) argc = 1; - ci->nregs = (int)(p->body.irep->nregs + argc); - mrb_stack_extend(mrb, ci->nregs); + mrb_stack_extend(mrb, p->body.irep->nregs + argc); } if (voff >= 0) { argv = mrb->c->stbase + voff; @@ -520,26 +542,25 @@ mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) { mrb_callinfo *ci = mrb->c->ci; - int keep; + int keep, nregs; mrb->c->stack[0] = self; ci->proc = p; if (MRB_PROC_CFUNC_P(p)) { return MRB_PROC_CFUNC(p)(mrb, self); } - ci->nregs = p->body.irep->nregs; + nregs = p->body.irep->nregs; if (ci->argc < 0) keep = 3; else keep = ci->argc + 2; - if (ci->nregs < keep) { + if (nregs < keep) { mrb_stack_extend(mrb, keep); } else { - mrb_stack_extend(mrb, ci->nregs); - stack_clear(mrb->c->stack+keep, ci->nregs-keep); + mrb_stack_extend(mrb, nregs); + stack_clear(mrb->c->stack+keep, nregs-keep); } ci = cipush(mrb); - ci->nregs = 0; ci->target_class = 0; ci->pc = p->body.irep->iseq; ci->stackent = mrb->c->stack; @@ -618,6 +639,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) { struct RProc *p; mrb_callinfo *ci; + int nregs; if (mrb_nil_p(blk)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); @@ -639,13 +661,12 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb->c->stack[2] = mrb_nil_value(); return MRB_PROC_CFUNC(p)(mrb, self); } - ci->nregs = p->body.irep->nregs; - mrb_stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs); + nregs = p->body.irep->nregs; + mrb_stack_extend(mrb, (nregs < 3) ? 3 : nregs); mrb->c->stack[0] = self; mrb->c->stack[1] = self; mrb->c->stack[2] = mrb_nil_value(); ci = cipush(mrb); - ci->nregs = 0; ci->target_class = 0; ci->pc = p->body.irep->iseq; ci->stackent = mrb->c->stack; @@ -728,13 +749,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value struct RProc *p; mrb_sym mid = mrb->c->ci->mid; mrb_callinfo *ci; - int n = mrb->c->ci->nregs; mrb_value val; + int n; if (mrb_nil_p(b)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); } - if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { + ci = mrb->c->ci; + n = ci_nregs(ci); + if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } p = mrb_proc_ptr(b); @@ -745,9 +768,9 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ci->argc = (int)argc; ci->target_class = c; ci->acc = CI_ACC_SKIP; + n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs; mrb->c->stack = mrb->c->stack + n; - ci->nregs = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs; - mrb_stack_extend(mrb, ci->nregs); + mrb_stack_extend(mrb, n); mrb->c->stack[0] = self; if (argc > 0) { @@ -1009,7 +1032,6 @@ RETRY_TRY_BLOCK: } mrb->jmp = &c_jmp; mrb->c->ci->proc = proc; - mrb->c->ci->nregs = irep->nregs; #define regs (mrb->c->stack) INIT_DISPATCH { @@ -1363,6 +1385,8 @@ RETRY_TRY_BLOCK: a = mrb->c->eidx - epos; pc = pc + 1; for (n=0; nnregs; + proc = mrb->c->ensure[epos+n]; mrb->c->ensure[epos+n] = NULL; if (proc == NULL) continue; @@ -1372,12 +1396,11 @@ RETRY_TRY_BLOCK: ci->argc = 0; ci->proc = proc; ci->stackent = mrb->c->stack; - ci->nregs = irep->nregs; ci->target_class = target_class; ci->pc = pc; - ci->acc = ci[-1].nregs; + ci->acc = nregs; mrb->c->stack += ci->acc; - mrb_stack_extend(mrb, ci->nregs); + mrb_stack_extend(mrb, irep->nregs); regs[0] = self; pc = irep->iseq; } @@ -1414,7 +1437,7 @@ RETRY_TRY_BLOCK: mrb_value recv, blk; mrb_sym mid = syms[b]; - mrb_assert(bidx < ci->nregs); + mrb_assert(bidx < irep->nregs); recv = regs[a]; if (GET_OPCODE(i) != OP_SENDB) { @@ -1466,7 +1489,6 @@ RETRY_TRY_BLOCK: mrb->c->stack += a; if (MRB_METHOD_CFUNC_P(m)) { - ci->nregs = (argc < 0) ? 3 : n+2; if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); @@ -1514,8 +1536,7 @@ RETRY_TRY_BLOCK: irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - ci->nregs = irep->nregs; - mrb_stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); + mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); pc = irep->iseq; JUMP; } @@ -1575,8 +1596,7 @@ RETRY_TRY_BLOCK: } pool = irep->pool; syms = irep->syms; - ci->nregs = irep->nregs; - mrb_stack_extend(mrb, ci->nregs); + mrb_stack_extend(mrb, irep->nregs); if (ci->argc < 0) { if (irep->nregs > 3) { stack_clear(regs+3, irep->nregs-3); @@ -1606,7 +1626,7 @@ RETRY_TRY_BLOCK: mrb_sym mid = ci->mid; struct RClass* target_class = MRB_PROC_TARGET_CLASS(ci->proc); - mrb_assert(bidx < ci->nregs); + mrb_assert(bidx < irep->nregs); if (mid == 0 || !target_class) { mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); @@ -1652,7 +1672,7 @@ RETRY_TRY_BLOCK: } mid = missing; if (argc >= 0) { - if (a+2 >= ci->nregs) { + if (a+2 >= irep->nregs) { mrb_stack_extend(mrb, a+3); } regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); @@ -1676,7 +1696,7 @@ RETRY_TRY_BLOCK: if (MRB_METHOD_CFUNC_P(m)) { mrb_value v; - ci->nregs = (argc < 0) ? 3 : n+2; + if (MRB_METHOD_PROC_P(m)) { ci->proc = MRB_METHOD_PROC(m); } @@ -1713,8 +1733,7 @@ RETRY_TRY_BLOCK: irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - ci->nregs = irep->nregs; - mrb_stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); + mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); pc = irep->iseq; JUMP; } @@ -2884,9 +2903,8 @@ RETRY_TRY_BLOCK: irep = p->body.irep; pool = irep->pool; syms = irep->syms; - ci->nregs = irep->nregs; - mrb_stack_extend(mrb, ci->nregs); - stack_clear(regs+1, ci->nregs-1); + mrb_stack_extend(mrb, irep->nregs); + stack_clear(regs+1, irep->nregs-1); pc = irep->iseq; JUMP; } @@ -3014,7 +3032,6 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta } ci = cipush(mrb); ci->mid = 0; - ci->nregs = 1; /* protect the receiver */ ci->acc = CI_ACC_SKIP; ci->target_class = mrb->object_class; v = mrb_vm_run(mrb, proc, self, stack_keep); -- cgit v1.2.3 From 54246db00aa9ae5a048d65f4263a3d14fd65d9d0 Mon Sep 17 00:00:00 2001 From: pyama86 Date: Mon, 6 Aug 2018 18:15:00 +0900 Subject: irep is released when Fiber is terminated --- src/gc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index 33d83f28e..9858e45fc 100644 --- a/src/gc.c +++ b/src/gc.c @@ -965,9 +965,11 @@ gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) size_t i; mrb_callinfo *ci; - if (!c) break; + if (!c || c->status == MRB_FIBER_TERMINATED) break; + /* mark stack */ i = c->stack - c->stbase; + if (c->ci) { i += ci_nregs(c->ci); } -- cgit v1.2.3 From 366848996a6cce8e733246bce6c3f76d797003bb Mon Sep 17 00:00:00 2001 From: dearblue Date: Fri, 7 Sep 2018 00:22:36 +0900 Subject: Clear terminated space --- examples/targets/build_config_android_arm64-v8a.rb | 4 ++-- examples/targets/build_config_android_armeabi.rb | 4 ++-- mrbgems/mruby-array-ext/test/array.rb | 2 +- mrbgems/mruby-compiler/core/codegen.c | 8 ++++---- mrbgems/mruby-random/src/random.c | 2 +- src/array.c | 2 +- src/codedump.c | 2 +- src/gc.c | 2 +- src/numeric.c | 2 +- src/variable.c | 10 +++++----- src/vm.c | 4 ++-- tasks/toolchains/gcc.rake | 2 +- test/t/kernel.rb | 2 +- test/t/syntax.rb | 6 +++--- 14 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src/gc.c') diff --git a/examples/targets/build_config_android_arm64-v8a.rb b/examples/targets/build_config_android_arm64-v8a.rb index 6188c13ec..70b0f4b97 100644 --- a/examples/targets/build_config_android_arm64-v8a.rb +++ b/examples/targets/build_config_android_arm64-v8a.rb @@ -15,8 +15,8 @@ end # Requires Android NDK r13 or later. MRuby::CrossBuild.new('android-arm64-v8a') do |conf| - params = { - :arch => 'arm64-v8a', + params = { + :arch => 'arm64-v8a', :platform => 'android-24', :toolchain => :clang, } diff --git a/examples/targets/build_config_android_armeabi.rb b/examples/targets/build_config_android_armeabi.rb index b7eb33a92..17330242a 100644 --- a/examples/targets/build_config_android_armeabi.rb +++ b/examples/targets/build_config_android_armeabi.rb @@ -15,8 +15,8 @@ end # Requires Android NDK r13 or later. MRuby::CrossBuild.new('android-armeabi') do |conf| - params = { - :arch => 'armeabi', + params = { + :arch => 'armeabi', :platform => 'android-24', :toolchain => :clang, } diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb index 7d810acc2..4f54c65c3 100644 --- a/mrbgems/mruby-array-ext/test/array.rb +++ b/mrbgems/mruby-array-ext/test/array.rb @@ -418,5 +418,5 @@ assert('Array#transpose') do assert_equal([[1], [2], [3]].transpose, [[1,2,3]]) assert_equal([[1,2], [3,4], [5,6]].transpose, [[1,3,5], [2,4,6]]) assert_raise(TypeError) { [1].transpose } - assert_raise(IndexError) { [[1], [2,3,4]].transpose } + assert_raise(IndexError) { [[1], [2,3,4]].transpose } end diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 8be9a8ebe..74504ffd1 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -419,7 +419,7 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) } else { struct mrb_insn_data data = mrb_last_insn(s); - + switch (data.insn) { case OP_MOVE: if (dst == src) return; /* remove useless MOVE */ @@ -456,7 +456,7 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src) } else { struct mrb_insn_data data = mrb_last_insn(s); - + if (data.insn == OP_MOVE && src == data.a) { s->pc = s->lastpc; genop_1(s, op, data.b); @@ -764,7 +764,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) kd = tail && tail->cdr->cdr->car? 1 : 0; /* block argument? */ ba = tail && tail->cdr->cdr->cdr->car ? 1 : 0; - + if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) { codegen_error(s, "too many formal arguments"); } @@ -3118,7 +3118,7 @@ generate_code(mrb_state *mrb, parser_state *p, int val) scope->filename_index = p->current_filename_index; MRB_TRY(&scope->jmp) { - mrb->jmp = &scope->jmp; + mrb->jmp = &scope->jmp; /* prepare irep */ codegen(scope, p->tree, val); proc = mrb_proc_new(mrb, scope->irep); diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index b865244cc..5b926a228 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -219,7 +219,7 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) mrb_int j; mrb_value *ptr = RARRAY_PTR(ary); mrb_value tmp; - + j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary)))); diff --git a/src/array.c b/src/array.c index 2152e292d..f0c32bc7f 100644 --- a/src/array.c +++ b/src/array.c @@ -231,7 +231,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) static void ary_shrink_capa(mrb_state *mrb, struct RArray *a) { - + mrb_int capa; if (ARY_EMBED_P(a)) return; diff --git a/src/codedump.c b/src/codedump.c index 454b16b36..30a14f937 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -516,7 +516,7 @@ codedump(mrb_state *mrb, mrb_irep *irep) #undef OPCODE } break; - + default: printf("OP_unknown (0x%x)\n", ins); break; diff --git a/src/gc.c b/src/gc.c index 9858e45fc..e429603dd 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1559,7 +1559,7 @@ mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, vo mrb->jmp = &c_jmp; gc_each_objects(mrb, &mrb->gc, callback, data); mrb->jmp = prev_jmp; - mrb->gc.iterating = iterating; + mrb->gc.iterating = iterating; } MRB_CATCH(&c_jmp) { mrb->gc.iterating = iterating; mrb->jmp = prev_jmp; diff --git a/src/numeric.c b/src/numeric.c index c3e7d77a3..f7f0318e8 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -433,7 +433,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) val = trunc(val); #else if (val > 0){ - val = floor(val); + val = floor(val); } else { val = ceil(val); } diff --git a/src/variable.c b/src/variable.c index 00bdb4b8d..506b4b63e 100644 --- a/src/variable.c +++ b/src/variable.c @@ -790,7 +790,7 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) proc = mrb->c->ci->proc; while (proc) { c2 = MRB_PROC_TARGET_CLASS(proc); - if (c2 && iv_get(mrb, c2->iv, sym, &v)) { + if (c2 && iv_get(mrb, c2->iv, sym, &v)) { return v; } proc = proc->upper; @@ -988,25 +988,25 @@ struct csym_arg { struct RClass *c; mrb_sym sym; }; - + static int csym_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) { struct csym_arg *a = (struct csym_arg*)p; struct RClass *c = a->c; - + if (mrb_type(v) == c->tt && mrb_class_ptr(v) == c) { a->sym = sym; return 1; /* stop iteration */ } return 0; } - + static mrb_sym find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c) { struct csym_arg arg; - + if (!outer) return 0; if (outer == c) return 0; arg.c = c; diff --git a/src/vm.c b/src/vm.c index 9c4580fb3..14c42984e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1818,7 +1818,7 @@ RETRY_TRY_BLOCK: } regs[blk_pos] = *blk; /* move block */ if (kd) regs[len + 1] = kdict; - + /* copy mandatory and optional arguments */ if (argv0 != argv) { value_move(®s[1], argv, argc-mlen); /* m1 + o */ @@ -2077,7 +2077,7 @@ RETRY_TRY_BLOCK: break; case OP_R_BREAK: if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; - if (MRB_PROC_ORPHAN_P(proc)) { + if (MRB_PROC_ORPHAN_P(proc)) { mrb_value exc; L_BREAK_ERROR: diff --git a/tasks/toolchains/gcc.rake b/tasks/toolchains/gcc.rake index fc2e0bff3..e0eb36f26 100644 --- a/tasks/toolchains/gcc.rake +++ b/tasks/toolchains/gcc.rake @@ -55,7 +55,7 @@ MRuby::Toolchain.new(:gcc) do |conf, _params| @header_search_paths end end - + def conf.enable_sanitizer(*opts) fail 'sanitizer already set' if @sanitizer_list diff --git a/test/t/kernel.rb b/test/t/kernel.rb index a730bdb24..74176fbd0 100644 --- a/test/t/kernel.rb +++ b/test/t/kernel.rb @@ -157,7 +157,7 @@ assert('Kernel#clone', '15.3.1.3.8') do assert_true a.respond_to?(:test) assert_false b.respond_to?(:test) assert_true c.respond_to?(:test) - + a.freeze d = a.clone assert_true d.frozen? diff --git a/test/t/syntax.rb b/test/t/syntax.rb index c5405aa9c..883cbd1ba 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -454,15 +454,15 @@ assert('multiline comments work correctly') do =begin this is a comment with nothing after begin and end =end -=begin this is a comment +=begin this is a comment this is a comment with extra after =begin =end =begin this is a comment that has =end with spaces after it -=end +=end =begin this is a comment this is a comment that has extra after =begin and =end with spaces after it -=end +=end line = __LINE__ =begin this is a comment this is a comment that has extra after =begin and =end with tabs after it -- cgit v1.2.3 From dffa203d07aaeec4ea65669542a8ec2033559bdd Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 29 Oct 2018 11:51:04 +0900 Subject: Need to mark shared env objects as `MRB_TT_FREE`; fix #4143 The following code mistakenly exits from the function without marking the env object as `MRB_TT_FREE`. ``` ruby if (MRB_ENV_STACK_SHARED_P(e)) { /* cannot be freed */ return; // <- should be `break` } ``` --- src/gc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index e429603dd..9b11b7a83 100644 --- a/src/gc.c +++ b/src/gc.c @@ -788,7 +788,8 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) if (MRB_ENV_STACK_SHARED_P(e)) { /* cannot be freed */ - return; + e->stack = NULL; + break; } mrb_free(mrb, e->stack); e->stack = NULL; -- cgit v1.2.3 From 3dc3643e34e1e9f119594ebd550f19e876d60e26 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 29 Oct 2018 11:58:10 +0900 Subject: Marking from terminated fibers are not needed; ref #4143 The old condition marks the top-level callinfo even after the fiber is terminated. --- src/gc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index 9b11b7a83..bacc322e8 100644 --- a/src/gc.c +++ b/src/gc.c @@ -801,10 +801,10 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) struct mrb_context *c = ((struct RFiber*)obj)->cxt; if (c && c != mrb->root_c) { - mrb_callinfo *ci = c->ci; - mrb_callinfo *ce = c->cibase; + if (!end && c->status != MRB_FIBER_TERMINATED) { + mrb_callinfo *ci = c->ci; + mrb_callinfo *ce = c->cibase; - if (!end) { while (ce <= ci) { struct REnv *e = ci->env; if (e && !is_dead(&mrb->gc, e) && -- cgit v1.2.3 From d68da042b3666c1e46e4d3cf1a14e708df89f440 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 1 Nov 2018 22:33:15 +0900 Subject: The `env` object referenced from fibers may be freed; fix #4154 By dffa203 that reclaim `env` objects from heaps, there's more chance for `env` objects referenced from fibers may be freed from heap pages. --- src/gc.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index bacc322e8..a52c64bfa 100644 --- a/src/gc.c +++ b/src/gc.c @@ -274,9 +274,29 @@ mrb_free(mrb_state *mrb, void *p) (mrb->allocf)(mrb, p, 0, mrb->allocf_ud); } +static mrb_bool +heap_p(mrb_gc *gc, struct RBasic *object) +{ + mrb_heap_page* page; + + page = gc->heaps; + while (page) { + RVALUE *p; + + p = objects(page); + if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE].as.basic) { + return TRUE; + } + page = page->next; + } + return FALSE; +} + MRB_API mrb_bool mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) { - return is_dead(&mrb->gc, object); + mrb_gc *gc = &mrb->gc; + if (!heap_p(gc, object)) return TRUE; + return is_dead(gc, object); } static void @@ -807,7 +827,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) while (ce <= ci) { struct REnv *e = ci->env; - if (e && !is_dead(&mrb->gc, e) && + if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { mrb_env_unshare(mrb, e); } -- cgit v1.2.3 From 648b57620a6f0bd03ab11db61b1fee343c889dfe Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Tue, 1 Jan 2019 15:35:56 +0900 Subject: range: Embed edges in RRange on boxing environment. [Breaking changes] Developers must use following APIs for accessing attributes of RRange because RRange structure depends on boxing setting. - mrb_range_beg - mrb_range_end - mrb_range_excl_p --- include/mruby/range.h | 34 ++++++-- mrbgems/mruby-range-ext/src/range.c | 15 ++-- src/gc.c | 11 +-- src/range.c | 161 +++++++++++++++++++++--------------- test/t/range.rb | 16 ++++ 5 files changed, 147 insertions(+), 90 deletions(-) (limited to 'src/gc.c') diff --git a/include/mruby/range.h b/include/mruby/range.h index b166e586b..4df5ccc70 100644 --- a/include/mruby/range.h +++ b/include/mruby/range.h @@ -14,20 +14,43 @@ */ MRB_BEGIN_DECL +#if defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING) +# define MRB_RANGE_EMBED +#endif + +#ifdef MRB_RANGE_EMBED +struct RRange { + MRB_OBJECT_HEADER; + mrb_value beg; + mrb_value end; + mrb_bool excl; +}; +# define mrb_gc_free_range(mrb, p) ((void)0) +# define RANGE_BEG(p) ((p)->beg) +# define RANGE_END(p) ((p)->end) +#else typedef struct mrb_range_edges { mrb_value beg; mrb_value end; } mrb_range_edges; - struct RRange { MRB_OBJECT_HEADER; mrb_range_edges *edges; - mrb_bool excl : 1; + mrb_bool excl; }; +# define mrb_gc_free_range(mrb, p) mrb_free(mrb, ((struct RRange*)p)->edges) +# define RANGE_BEG(p) ((p)->edges->beg) +# define RANGE_END(p) ((p)->edges->end) +#endif + +#define mrb_range_beg(mrb, r) RANGE_BEG(mrb_range_ptr(mrb, r)) +#define mrb_range_end(mrb, r) RANGE_END(mrb_range_ptr(mrb, r)) +#define mrb_range_excl_p(mrb, r) RANGE_EXCL(mrb_range_ptr(mrb, r)) +#define mrb_range_raw_ptr(r) ((struct RRange*)mrb_ptr(r)) +#define mrb_range_value(p) mrb_obj_value((void*)(p)) +#define RANGE_EXCL(p) ((p)->excl) -MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v); -#define mrb_range_raw_ptr(v) ((struct RRange*)mrb_ptr(v)) -#define mrb_range_value(p) mrb_obj_value((void*)(p)) +MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value range); /* * Initializes a Range. @@ -43,6 +66,7 @@ MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)); +void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r); MRB_END_DECL diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index aca71cc01..1fc383755 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -48,11 +48,11 @@ mrb_range_cover(mrb_state *mrb, mrb_value range) mrb_get_args(mrb, "o", &val); - beg = r->edges->beg; - end = r->edges->end; + beg = RANGE_BEG(r); + end = RANGE_END(r); if (r_le(mrb, beg, val)) { - if (r->excl) { + if (RANGE_EXCL(r)) { if (r_lt(mrb, val, end)) return mrb_true_value(); } @@ -86,10 +86,9 @@ mrb_range_last(mrb_state *mrb, mrb_value range) { mrb_value num; mrb_value array; - struct RRange *r = mrb_range_ptr(mrb, range); if (mrb_get_args(mrb, "|o", &num) == 0) { - return r->edges->end; + return mrb_range_end(mrb, range); } array = mrb_funcall(mrb, range, "to_a", 0); @@ -116,9 +115,9 @@ mrb_range_size(mrb_state *mrb, mrb_value range) mrb_bool num_p = TRUE; mrb_bool excl; - beg = r->edges->beg; - end = r->edges->end; - excl = r->excl; + beg = RANGE_BEG(r); + end = RANGE_END(r); + excl = RANGE_EXCL(r); if (mrb_fixnum_p(beg)) { beg_f = (mrb_float)mrb_fixnum(beg); } diff --git a/src/gc.c b/src/gc.c index a52c64bfa..ec52787e8 100644 --- a/src/gc.c +++ b/src/gc.c @@ -739,14 +739,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) break; case MRB_TT_RANGE: - { - struct RRange *r = (struct RRange*)obj; - - if (r->edges) { - mrb_gc_mark_value(mrb, r->edges->beg); - mrb_gc_mark_value(mrb, r->edges->end); - } - } + mrb_gc_mark_range(mrb, (struct RRange*)obj); break; default: @@ -870,7 +863,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) break; case MRB_TT_RANGE: - mrb_free(mrb, ((struct RRange*)obj)->edges); + mrb_gc_free_range(mrb, ((struct RRange*)obj)); break; case MRB_TT_DATA: diff --git a/src/range.c b/src/range.c index e45308d35..d2f897bd5 100644 --- a/src/range.c +++ b/src/range.c @@ -10,12 +10,17 @@ #include #include +#define RANGE_INITIALIZED_MASK 1 +#define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_MASK) +#define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_MASK) + MRB_API struct RRange* -mrb_range_ptr(mrb_state *mrb, mrb_value v) +mrb_range_ptr(mrb_state *mrb, mrb_value range) { - struct RRange *r = (struct RRange*)mrb_ptr(v); + struct RRange *r = mrb_range_raw_ptr(range); - if (r->edges == NULL) { + /* check for if #initialize_copy was removed [#3320] */ + if (!RANGE_INITIALIZED_P(r)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range"); } return r; @@ -46,17 +51,52 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b) } } -MRB_API mrb_value -mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) +static void +range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r) { - struct RRange *r; +#ifndef MRB_RANGE_EMBED + r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); +#endif +} +static struct RRange * +range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl) +{ range_check(mrb, beg, end); - r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class); - r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); - r->edges->beg = beg; - r->edges->end = end; - r->excl = excl; + + if (r) { + if (RANGE_INITIALIZED_P(r)) { + /* Ranges are immutable, so that they should be initialized only once. */ + mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice"); + } + else { + range_ptr_alloc_edges(mrb, r); + } + } + else { + r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class); + range_ptr_alloc_edges(mrb, r); + } + + RANGE_BEG(r) = beg; + RANGE_END(r) = end; + RANGE_EXCL(r) = excl; + RANGE_INITIALIZED(r); + + return r; +} + +static void +range_ptr_replace(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl) +{ + range_ptr_init(mrb, r, beg, end, excl); + mrb_write_barrier(mrb, (struct RBasic*)r); +} + +MRB_API mrb_value +mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) +{ + struct RRange *r = range_ptr_init(mrb, NULL, beg, end, excl); return mrb_range_value(r); } @@ -67,12 +107,10 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) * * Returns the first object in rng. */ -mrb_value -mrb_range_beg(mrb_state *mrb, mrb_value range) +static mrb_value +range_beg(mrb_state *mrb, mrb_value range) { - struct RRange *r = mrb_range_ptr(mrb, range); - - return r->edges->beg; + return mrb_range_beg(mrb, range); } /* @@ -86,12 +124,10 @@ mrb_range_beg(mrb_state *mrb, mrb_value range) * (1...10).end #=> 10 */ -mrb_value -mrb_range_end(mrb_state *mrb, mrb_value range) +static mrb_value +range_end(mrb_state *mrb, mrb_value range) { - struct RRange *r = mrb_range_ptr(mrb, range); - - return r->edges->end; + return mrb_range_end(mrb, range); } /* @@ -103,25 +139,9 @@ mrb_range_end(mrb_state *mrb, mrb_value range) mrb_value mrb_range_excl(mrb_state *mrb, mrb_value range) { - struct RRange *r = mrb_range_ptr(mrb, range); - - return mrb_bool_value(r->excl); + return mrb_bool_value(mrb_range_excl_p(mrb, range)); } -static void -range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end) -{ - struct RRange *r = mrb_range_raw_ptr(range); - - range_check(mrb, beg, end); - r->excl = exclude_end; - if (!r->edges) { - r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges)); - } - r->edges->beg = beg; - r->edges->end = end; - mrb_write_barrier(mrb, (struct RBasic*)r); -} /* * call-seq: * Range.new(start, end, exclusive=false) => range @@ -142,11 +162,7 @@ mrb_range_initialize(mrb_state *mrb, mrb_value range) if (n != 3) { exclusive = FALSE; } - /* Ranges are immutable, so that they should be initialized only once. */ - if (mrb_range_raw_ptr(range)->edges) { - mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice"); - } - range_init(mrb, range, beg, end, exclusive); + range_ptr_replace(mrb, mrb_range_raw_ptr(range), beg, end, exclusive); return range; } /* @@ -180,9 +196,9 @@ mrb_range_eq(mrb_state *mrb, mrb_value range) rr = mrb_range_ptr(mrb, range); ro = mrb_range_ptr(mrb, obj); - v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg); - v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end); - if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) { + v1 = mrb_funcall(mrb, RANGE_BEG(rr), "==", 1, RANGE_BEG(ro)); + v2 = mrb_funcall(mrb, RANGE_END(rr), "==", 1, RANGE_END(ro)); + if (!mrb_bool(v1) || !mrb_bool(v2) || RANGE_EXCL(rr) != RANGE_EXCL(ro)) { return mrb_false_value(); } return mrb_true_value(); @@ -242,11 +258,11 @@ mrb_range_include(mrb_state *mrb, mrb_value range) mrb_get_args(mrb, "o", &val); - beg = r->edges->beg; - end = r->edges->end; - include_p = r_le(mrb, beg, val) && /* beg <= val */ - (r->excl ? r_gt(mrb, end, val) /* end > val */ - : r_ge(mrb, end, val)); /* end >= val */ + beg = RANGE_BEG(r); + end = RANGE_END(r); + include_p = r_le(mrb, beg, val) && /* beg <= val */ + (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */ + : r_ge(mrb, end, val)); /* end >= val */ return mrb_bool_value(include_p); } @@ -260,8 +276,8 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, if (mrb_type(range) != MRB_TT_RANGE) return 0; r = mrb_range_ptr(mrb, range); - beg = mrb_int(mrb, r->edges->beg); - end = mrb_int(mrb, r->edges->end); + beg = mrb_int(mrb, RANGE_BEG(r)); + end = mrb_int(mrb, RANGE_END(r)); if (beg < 0) { beg += len; @@ -274,7 +290,7 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, } if (end < 0) end += len; - if (!r->excl && (!trunc || end < len)) + if (!RANGE_EXCL(r) && (!trunc || end < len)) end++; /* include end point */ len = end - beg; if (len < 0) len = 0; @@ -298,10 +314,10 @@ range_to_s(mrb_state *mrb, mrb_value range) mrb_value str, str2; struct RRange *r = mrb_range_ptr(mrb, range); - str = mrb_obj_as_string(mrb, r->edges->beg); - str2 = mrb_obj_as_string(mrb, r->edges->end); + str = mrb_obj_as_string(mrb, RANGE_BEG(r)); + str2 = mrb_obj_as_string(mrb, RANGE_END(r)); str = mrb_str_dup(mrb, str); - mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); + mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2); mrb_str_cat_str(mrb, str, str2); return str; @@ -323,10 +339,10 @@ range_inspect(mrb_state *mrb, mrb_value range) mrb_value str, str2; struct RRange *r = mrb_range_ptr(mrb, range); - str = mrb_inspect(mrb, r->edges->beg); - str2 = mrb_inspect(mrb, r->edges->end); + str = mrb_inspect(mrb, RANGE_BEG(r)); + str2 = mrb_inspect(mrb, RANGE_END(r)); str = mrb_str_dup(mrb, str); - mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); + mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2); mrb_str_cat_str(mrb, str, str2); return str; @@ -363,9 +379,9 @@ range_eql(mrb_state *mrb, mrb_value range) r = mrb_range_ptr(mrb, range); o = mrb_range_ptr(mrb, obj); - if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) || - !mrb_eql(mrb, r->edges->end, o->edges->end) || - (r->excl != o->excl)) { + if (!mrb_eql(mrb, RANGE_BEG(r), RANGE_BEG(o)) || + !mrb_eql(mrb, RANGE_END(r), RANGE_END(o)) || + (RANGE_EXCL(r) != RANGE_EXCL(o))) { return mrb_false_value(); } return mrb_true_value(); @@ -386,7 +402,7 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy) } r = mrb_range_ptr(mrb, src); - range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl); + range_ptr_replace(mrb, mrb_range_raw_ptr(copy), RANGE_BEG(r), RANGE_END(r), RANGE_EXCL(r)); return copy; } @@ -420,6 +436,15 @@ mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, con return result; } +void +mrb_gc_mark_range(mrb_state *mrb, struct RRange *r) +{ + if (RANGE_INITIALIZED_P(r)) { + mrb_gc_mark_value(mrb, RANGE_BEG(r)); + mrb_gc_mark_value(mrb, RANGE_END(r)); + } +} + void mrb_init_range(mrb_state *mrb) { @@ -429,15 +454,15 @@ mrb_init_range(mrb_state *mrb) mrb->range_class = r; MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE); - mrb_define_method(mrb, r, "begin", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */ - mrb_define_method(mrb, r, "end", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */ + mrb_define_method(mrb, r, "begin", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */ + mrb_define_method(mrb, r, "end", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */ mrb_define_method(mrb, r, "==", mrb_range_eq, MRB_ARGS_REQ(1)); /* 15.2.14.4.1 */ mrb_define_method(mrb, r, "===", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.2 */ mrb_define_method(mrb, r, "exclude_end?", mrb_range_excl, MRB_ARGS_NONE()); /* 15.2.14.4.6 */ - mrb_define_method(mrb, r, "first", mrb_range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */ + mrb_define_method(mrb, r, "first", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */ mrb_define_method(mrb, r, "include?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.8 */ mrb_define_method(mrb, r, "initialize", mrb_range_initialize, MRB_ARGS_ANY()); /* 15.2.14.4.9 */ - mrb_define_method(mrb, r, "last", mrb_range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */ + mrb_define_method(mrb, r, "last", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */ mrb_define_method(mrb, r, "member?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */ mrb_define_method(mrb, r, "to_s", range_to_s, MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */ diff --git a/test/t/range.rb b/test/t/range.rb index 5aee4d5cc..64e7f9d9f 100644 --- a/test/t/range.rb +++ b/test/t/range.rb @@ -93,3 +93,19 @@ assert('Range#eql?', '15.2.14.4.14') do assert_false (1..10).eql? (Range.new(1.0, 10.0)) assert_false (1..10).eql? "1..10" end + +assert('Range#initialize_copy', '15.2.14.4.15') do + assert_raise(NameError) { (0..1).__send__(:initialize_copy, 1..3) } +end + +assert('Range#dup') do + r = (1..3).dup + assert_equal r.begin, 1 + assert_equal r.end, 3 + assert_false r.exclude_end? + + r = ("a"..."z").dup + assert_equal r.begin, "a" + assert_equal r.end, "z" + assert_true r.exclude_end? +end -- 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(+) (limited to 'src/gc.c') 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 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(-) (limited to 'src/gc.c') 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 a5bda13fb76ba50c3742b24b854fb2e86c50b31d Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sat, 4 May 2019 16:38:07 +0900 Subject: Check whether object is immediate in `mrb_gc_(register|unregister)` --- src/gc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index 27f3716ec..5e7440d50 100644 --- a/src/gc.c +++ b/src/gc.c @@ -466,9 +466,12 @@ mrb_gc_protect(mrb_state *mrb, mrb_value obj) MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj) { - mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME); - mrb_value table = mrb_gv_get(mrb, root); + mrb_sym root; + mrb_value table; + if (mrb_immediate_p(obj)) return; + root = mrb_intern_lit(mrb, GC_ROOT_NAME); + table = mrb_gv_get(mrb, root); if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) { table = mrb_ary_new(mrb); mrb_gv_set(mrb, root, table); @@ -480,11 +483,14 @@ mrb_gc_register(mrb_state *mrb, mrb_value obj) MRB_API void 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); + mrb_sym root; + mrb_value table; struct RArray *a; mrb_int i; + if (mrb_immediate_p(obj)) return; + root = mrb_intern_lit(mrb, GC_ROOT_NAME); + table = mrb_gv_get(mrb, root); if (mrb_nil_p(table)) return; if (mrb_type(table) != MRB_TT_ARRAY) { mrb_gv_set(mrb, root, mrb_nil_value()); -- cgit v1.2.3 From e41f15747eea34ea45e0258f0755145fcd10293b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 18 May 2019 11:10:20 +0900 Subject: Rename `struct RIstruct` to `struct RIStruct`. --- include/mruby/istruct.h | 4 ++-- src/gc.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gc.c') diff --git a/include/mruby/istruct.h b/include/mruby/istruct.h index 4d2393ccd..23c9bfa36 100644 --- a/include/mruby/istruct.h +++ b/include/mruby/istruct.h @@ -19,12 +19,12 @@ MRB_BEGIN_DECL #define ISTRUCT_DATA_SIZE (sizeof(void*) * 3) -struct RIstruct { +struct RIStruct { MRB_OBJECT_HEADER; char inline_data[ISTRUCT_DATA_SIZE]; }; -#define RISTRUCT(obj) ((struct RIstruct*)(mrb_ptr(obj))) +#define RISTRUCT(obj) ((struct RIStruct*)(mrb_ptr(obj))) #define ISTRUCT_PTR(obj) (RISTRUCT(obj)->inline_data) MRB_INLINE mrb_int mrb_istruct_size() diff --git a/src/gc.c b/src/gc.c index 5e7440d50..6dc8e373b 100644 --- a/src/gc.c +++ b/src/gc.c @@ -110,7 +110,7 @@ typedef struct { struct RHash hash; struct RRange range; struct RData data; - struct RIstruct istruct; + struct RIStruct istruct; struct RProc proc; struct REnv env; struct RFiber fiber; -- cgit v1.2.3 From 2b81ea7ec1c7645b13b097e5b249cbc99f374da7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 28 May 2019 10:44:18 +0900 Subject: Add `mrb_alloca` again; ref #4470 This time, the allocated memory comes from the string object, which is referenced from GC arena. The memory region will be reclaimed when the C function called from VM is terminated, or the GC arena is restored. --- include/mruby.h | 2 ++ src/gc.c | 7 +++++++ 2 files changed, 9 insertions(+) (limited to 'src/gc.c') diff --git a/include/mruby.h b/include/mruby.h index 5d5c759dd..3ef399716 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1246,6 +1246,8 @@ MRB_API void mrb_pool_close(struct mrb_pool*); MRB_API void* mrb_pool_alloc(struct mrb_pool*, size_t); MRB_API void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen); MRB_API mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t); +/* temporary memory allocation, only effective while GC arena is kept */ +MRB_API void* mrb_alloca(mrb_state *mrb, size_t); MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func); diff --git a/src/gc.c b/src/gc.c index 6dc8e373b..94068c0f9 100644 --- a/src/gc.c +++ b/src/gc.c @@ -277,6 +277,13 @@ mrb_free(mrb_state *mrb, void *p) (mrb->allocf)(mrb, p, 0, mrb->allocf_ud); } +MRB_API void* +mrb_alloca(mrb_state *mrb, size_t size) +{ + mrb_value str = mrb_str_new(mrb, NULL, size); + return RSTRING_PTR(str); +} + static mrb_bool heap_p(mrb_gc *gc, struct RBasic *object) { -- cgit v1.2.3 From f71270df7736e9cd53845c45d1eb369227c853ea Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Mon, 24 Jun 2019 18:55:05 +0900 Subject: Compare obj pointer directly instead of using mrb_obj_eq in mrb_gc_unregister Because immediate values are not registered. --- src/gc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index 94068c0f9..b05d929a1 100644 --- a/src/gc.c +++ b/src/gc.c @@ -506,7 +506,7 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj) a = mrb_ary_ptr(table); mrb_ary_modify(mrb, a); for (i = 0; i < ARY_LEN(a); i++) { - if (mrb_obj_eq(mrb, ARY_PTR(a)[i], obj)) { + if (mrb_ptr(ARY_PTR(a)[i]) == mrb_ptr(obj)) { mrb_int len = ARY_LEN(a)-1; mrb_value *ptr = ARY_PTR(a); -- cgit v1.2.3