From 97319697c8f9f6ff27b32589947e1918e3015503 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 2 Jul 2020 10:41:03 +0900 Subject: Cancel 9cdf439 Should not free the pointer in `realloc` since it can cause use-after-free problem. --- src/gc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index 6c83911d5..e1892080f 100644 --- a/src/gc.c +++ b/src/gc.c @@ -225,7 +225,6 @@ mrb_realloc(mrb_state *mrb, void *p, size_t len) p2 = mrb_realloc_simple(mrb, p, len); if (len == 0) return p2; if (p2 == NULL) { - mrb_free(mrb, p); mrb->gc.out_of_memory = TRUE; mrb_raise_nomemory(mrb); } -- cgit v1.2.3 From 57469584704a5e65e655e05ac48d9a09e246f0c5 Mon Sep 17 00:00:00 2001 From: Rory OConnell <19547+RoryO@users.noreply.github.com> Date: Sat, 4 Jul 2020 20:33:38 -0700 Subject: fix object_id of true, false, and undef all 0 --- src/etc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/etc.c b/src/etc.c index 785f49357..74b9ab03b 100644 --- a/src/etc.c +++ b/src/etc.c @@ -107,10 +107,11 @@ mrb_obj_id(mrb_value obj) return MakeID(0); /* not define */ case MRB_TT_FALSE: if (mrb_nil_p(obj)) - return MakeID(1); - return MakeID(0); + return MakeID(4); + else + return MakeID(0); case MRB_TT_TRUE: - return MakeID(1); + return MakeID(2); case MRB_TT_SYMBOL: return MakeID(mrb_symbol(obj)); case MRB_TT_FIXNUM: -- cgit v1.2.3 From 01a8d8498fc3c1b107b303661d06b858858fce26 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 6 Jul 2020 23:11:51 +0900 Subject: Avoid infinite loop when converting objects to strings. --- src/object.c | 1 + src/string.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/object.c b/src/object.c index db9dfb568..7257f402d 100644 --- a/src/object.c +++ b/src/object.c @@ -338,6 +338,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char if (mrb_type(val) == type) return val; v = convert_type(mrb, val, tname, method, TRUE); if (mrb_type(v) != type) { + if (type == MRB_TT_STRING) return mrb_any_to_s(mrb, val); mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%s", val, tname, method); } return v; diff --git a/src/string.c b/src/string.c index f1ffbe43d..78c41c5f3 100644 --- a/src/string.c +++ b/src/string.c @@ -1121,6 +1121,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str) return mrb_sym_str(mrb, mrb_symbol(str)); case MRB_TT_FIXNUM: return mrb_fixnum_to_str(mrb, str, 10); + case MRB_TT_SCLASS: case MRB_TT_CLASS: case MRB_TT_MODULE: return mrb_mod_to_s(mrb, str); -- cgit v1.2.3 From 28e39419a589763fc2357de84d91979f2b113cd1 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 11 Jul 2020 16:12:48 +0900 Subject: Remove the prototype declaration `mrb_free_backtrace()` This function is removed by 9644ad5. --- src/state.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/state.c b/src/state.c index 533bdaa0b..790f7ca13 100644 --- a/src/state.c +++ b/src/state.c @@ -164,8 +164,6 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep) mrb_free(mrb, irep); } -void mrb_free_backtrace(mrb_state *mrb); - MRB_API void mrb_free_context(mrb_state *mrb, struct mrb_context *c) { -- cgit v1.2.3 From 41e3220539ff0150bb09968b243ce6ed96b6fe0e Mon Sep 17 00:00:00 2001 From: Rory OConnell <19547+RoryO@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:56:27 -0700 Subject: All values use page slot size in calculation --- include/mruby/gc.h | 1 + mrbgems/mruby-objectspace/src/mruby_objectspace.c | 16 +++++++++++----- src/gc.c | 7 +++++++ 3 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/include/mruby/gc.h b/include/mruby/gc.h index 4d9fb60eb..3b2ded9d4 100644 --- a/include/mruby/gc.h +++ b/include/mruby/gc.h @@ -21,6 +21,7 @@ struct mrb_state; #define MRB_EACH_OBJ_BREAK 1 typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data); void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data); +const mrb_int mrb_objspace_page_slot_size(); MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c); #ifndef MRB_GC_ARENA_SIZE diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index c0bc2b807..791bf68fe 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -251,6 +251,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_bool recurse, mrb_int* t case MRB_TT_SCLASS: case MRB_TT_ICLASS: case MRB_TT_OBJECT: { + (*t) += mrb_objspace_page_slot_size(); os_memsize_of_ivars(mrb, obj, recurse, t); if(mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "UnboundMethod"))) { os_memsize_of_method(mrb, obj, t); @@ -270,6 +271,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_bool recurse, mrb_int* t len = RARRAY_LEN(obj); /* Arrays that do not fit within an RArray perform a heap allocation * storing an array of pointers to the original objects*/ + (*t) += mrb_objspace_page_slot_size(); if(len > MRB_ARY_EMBED_LEN_MAX) (*t) += sizeof(mrb_value *) * len; if(recurse) { @@ -280,12 +282,14 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_bool recurse, mrb_int* t break; } case MRB_TT_PROC: { + (*t) += mrb_objspace_page_slot_size(); struct RProc* proc = mrb_proc_ptr(obj); (*t) += MRB_ENV_LEN(proc->e.env) * sizeof(mrb_value); if(!MRB_PROC_CFUNC_P(proc)) os_memsize_of_irep(mrb, proc->body.irep, t); break; } case MRB_TT_DATA: + (*t) += mrb_objspace_page_slot_size(); if(mrb_respond_to(mrb, obj, mrb_intern_lit(mrb, "memsize"))) { (*t) += mrb_fixnum(mrb_funcall(mrb, obj, "memsize", 0)); } @@ -293,23 +297,25 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_bool recurse, mrb_int* t #ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: #ifdef MRB_WORD_BOXING - (*t) += sizeof(struct RFloat); + (*t) += mrb_objspace_page_slot_size() + + sizeof(struct RFloat); #endif break; #endif case MRB_TT_RANGE: #ifndef MRB_RANGE_EMBED - (*t) += sizeof(struct mrb_range_edges); + (*t) += mrb_objspace_page_slot_size() + + sizeof(struct mrb_range_edges); #endif break; case MRB_TT_FIBER: { /* struct RFiber* fiber = (struct RFiber*)mrb_ptr(obj); */ (*t) += sizeof(struct mrb_context); + case MRB_TT_ISTRUCT: + (*t) += mrb_objspace_page_slot_size(); break; - } /* zero heap size types. - * immediate VM stack values, contained within mrb_state, mrb_heap_page, - * or on C stack */ + * immediate VM stack values, contained within mrb_state, or on C stack */ case MRB_TT_TRUE: case MRB_TT_FALSE: case MRB_TT_FIXNUM: diff --git a/src/gc.c b/src/gc.c index e1892080f..fd4fb2406 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1599,6 +1599,13 @@ mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, vo } } +const mrb_int +mrb_objspace_page_slot_size() +{ + const mrb_int i = sizeof(RVALUE); + return i; +} + #ifdef GC_TEST #ifdef GC_DEBUG static mrb_value gc_test(mrb_state *, mrb_value); -- cgit v1.2.3 From e7bd7d0eaf677f62d86f27c2e9a917faa5a7d419 Mon Sep 17 00:00:00 2001 From: Rory OConnell <19547+RoryO@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:58:50 -0700 Subject: Use size of hash's table in calculation --- include/mruby/hash.h | 1 + mrbgems/mruby-objectspace/src/mruby_objectspace.c | 9 ++++++--- src/hash.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/include/mruby/hash.h b/include/mruby/hash.h index 0052a1105..cd53f6aeb 100644 --- a/include/mruby/hash.h +++ b/include/mruby/hash.h @@ -23,6 +23,7 @@ struct RHash { #define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v))) #define mrb_hash_value(p) mrb_obj_value((void*)(p)) +mrb_int os_memsize_of_hash_table(mrb_value obj); MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa); MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash); MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index 791bf68fe..b0a3e0d89 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -262,8 +262,12 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_bool recurse, mrb_int* t break; } case MRB_TT_HASH: { - /*struct htable* htable = RHASH_TBL(obj); - * Need htable & segment struct defs */ + (*t) += mrb_objspace_page_slot_size() + + os_memsize_of_hash_table(obj); + if(recurse) { + os_memsize_of_object(mrb, mrb_hash_keys(mrb, obj), recurse, t); + os_memsize_of_object(mrb, mrb_hash_values(mrb, obj), recurse, t); + } break; } case MRB_TT_ARRAY: { @@ -325,7 +329,6 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_bool recurse, mrb_int* t case MRB_TT_FREE: case MRB_TT_UNDEF: case MRB_TT_ENV: - case MRB_TT_ISTRUCT: /* never used, silences compiler warning * not having a default: clause lets the compiler tell us when there is a new * TT not accounted for */ diff --git a/src/hash.c b/src/hash.c index 4d5310903..7c90758c0 100644 --- a/src/hash.c +++ b/src/hash.c @@ -518,6 +518,20 @@ ht_foreach(mrb_state *mrb, htable *t, mrb_hash_foreach_func *func, void *p) } } +mrb_int +os_memsize_of_hash_table(mrb_value obj) +{ + struct htable *h = mrb_hash_ptr(obj)->ht; + mrb_int segkv_size = 0; + + if(h->index) segkv_size = (sizeof(struct segkv) * h->index->capa); + + return sizeof(htable) + + sizeof(segindex) + + (sizeof(segment) * h->size) + + segkv_size; +} + /* Iterates over the hash table. */ MRB_API void mrb_hash_foreach(mrb_state *mrb, struct RHash *hash, mrb_hash_foreach_func *func, void *p) -- cgit v1.2.3 From 6f945a09b4a09828667da6d4bad85b8ef50baf9c Mon Sep 17 00:00:00 2001 From: Rory OConnell <19547+RoryO@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:59:24 -0700 Subject: Use object iv table size in calculation --- include/mruby/variable.h | 1 + mrbgems/mruby-objectspace/src/mruby_objectspace.c | 2 +- src/variable.c | 9 +++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/include/mruby/variable.h b/include/mruby/variable.h index 6e918cf57..5559f6606 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -35,6 +35,7 @@ mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym); void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value); mrb_value mrb_vm_const_get(mrb_state*, mrb_sym); void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); +mrb_int mrb_obj_iv_tbl_memsize(mrb_state*, mrb_value); MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym); diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index b0a3e0d89..e48ac5b11 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -192,7 +192,7 @@ os_memsize_ivar_cb(mrb_state *mrb, mrb_sym _name, mrb_value obj, void *data) static void os_memsize_of_ivars(mrb_state* mrb, mrb_value obj, mrb_bool recurse, mrb_int *t) { - /* need iv segment table size */ + (*t) += mrb_obj_iv_tbl_memsize(mrb, obj); if(recurse) { mrb_int r = (mrb_int)recurse; mrb_int *cb_data[2] = { &r, t }; diff --git a/src/variable.c b/src/variable.c index 030aa7b00..0755f7d92 100644 --- a/src/variable.c +++ b/src/variable.c @@ -4,6 +4,7 @@ ** See Copyright Notice in mruby.h */ +#include #include #include #include @@ -1128,6 +1129,14 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c) return path; } +mrb_int +mrb_obj_iv_tbl_memsize(mrb_state* mrb, mrb_value obj) +{ + return sizeof(iv_tbl) + + (sizeof(segment) * ceil(iv_size(mrb, mrb_obj_ptr(obj)->iv)/ + MRB_IV_SEGMENT_SIZE)); +} + #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) mrb_bool -- cgit v1.2.3 From f74d370c1574fba53330c032ec6ac4716fee4a07 Mon Sep 17 00:00:00 2001 From: Rory O'Connell <19547+RoryO@users.noreply.github.com> Date: Wed, 15 Jul 2020 19:57:22 -0700 Subject: mrb_ prefix convention --- include/mruby/hash.h | 2 +- mrbgems/mruby-objectspace/src/mruby_objectspace.c | 2 +- src/hash.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/include/mruby/hash.h b/include/mruby/hash.h index cd53f6aeb..04b265ec3 100644 --- a/include/mruby/hash.h +++ b/include/mruby/hash.h @@ -23,7 +23,7 @@ struct RHash { #define mrb_hash_ptr(v) ((struct RHash*)(mrb_ptr(v))) #define mrb_hash_value(p) mrb_obj_value((void*)(p)) -mrb_int os_memsize_of_hash_table(mrb_value obj); +mrb_int mrb_os_memsize_of_hash_table(mrb_value obj); MRB_API mrb_value mrb_hash_new_capa(mrb_state *mrb, mrb_int capa); MRB_API mrb_value mrb_ensure_hash_type(mrb_state *mrb, mrb_value hash); MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash); diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index 9fbfd0d54..7892c6a1b 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -270,7 +270,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_value recurse, mrb_int* } case MRB_TT_HASH: { (*t) += mrb_objspace_page_slot_size() + - os_memsize_of_hash_table(obj); + mrb_os_memsize_of_hash_table(obj); if(!mrb_nil_p(recurse)) { os_memsize_of_object(mrb, mrb_hash_keys(mrb, obj), recurse, t); os_memsize_of_object(mrb, mrb_hash_values(mrb, obj), recurse, t); diff --git a/src/hash.c b/src/hash.c index 7c90758c0..79b61d8b2 100644 --- a/src/hash.c +++ b/src/hash.c @@ -519,7 +519,7 @@ ht_foreach(mrb_state *mrb, htable *t, mrb_hash_foreach_func *func, void *p) } mrb_int -os_memsize_of_hash_table(mrb_value obj) +mrb_os_memsize_of_hash_table(mrb_value obj) { struct htable *h = mrb_hash_ptr(obj)->ht; mrb_int segkv_size = 0; -- cgit v1.2.3 From 1952004d5a4a3c0758036baca6158aa51e93d4d3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 17 Jul 2020 16:15:47 +0900 Subject: Use `proc->env` to check `block_given?` if possible; fix #5039 This bug has been there since mruby 1.4.0 (2018-04). --- src/kernel.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/kernel.c b/src/kernel.c index 8f0c9c7b5..a74f8a8ed 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -99,6 +99,18 @@ mrb_obj_id_m(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(mrb_obj_id(self)); } +static int +env_bidx(struct REnv *e) +{ + int bidx; + + /* use saved block arg position */ + bidx = MRB_ENV_BIDX(e); + /* bidx may be useless (e.g. define_method) */ + if (bidx >= MRB_ENV_LEN(e)) return -1; + return bidx; +} + /* 15.3.1.2.2 */ /* 15.3.1.2.5 */ /* 15.3.1.3.6 */ @@ -129,6 +141,8 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) mrb_callinfo *ci = &mrb->c->ci[-1]; mrb_callinfo *cibase = mrb->c->cibase; mrb_value *bp; + int bidx; + struct REnv *e = NULL; struct RProc *p; if (ci <= cibase) { @@ -139,29 +153,36 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) /* search method/class/module proc */ while (p) { if (MRB_PROC_SCOPE_P(p)) break; + e = MRB_PROC_ENV(p); p = p->upper; } if (p == NULL) return mrb_false_value(); + if (e) { + bidx = env_bidx(e); + if (bidx < 0) return mrb_false_value(); + bp = &e->stack[bidx]; + goto block_given; + } /* search ci corresponding to proc */ while (cibase < ci) { if (ci->proc == p) break; ci--; } if (ci == cibase) { - return mrb_false_value(); + /* proc is closure */ + if (!MRB_PROC_ENV_P(p)) return mrb_false_value(); + e = MRB_PROC_ENV(p); + bidx = env_bidx(e); + if (bidx < 0) return mrb_false_value(); + bp = &e->stack[bidx]; } else if (ci->env) { - struct REnv *e = ci->env; - int bidx; - + e = ci->env; /* top-level does not have block slot (always false) */ - if (e->stack == mrb->c->stbase) - return mrb_false_value(); - /* use saved block arg position */ - bidx = MRB_ENV_BIDX(e); + if (e->stack == mrb->c->stbase) return mrb_false_value(); + bidx = env_bidx(e); /* bidx may be useless (e.g. define_method) */ - if (bidx >= MRB_ENV_LEN(e)) - return mrb_false_value(); + if (bidx < 0) return mrb_false_value(); bp = &e->stack[bidx]; } else { @@ -173,6 +194,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) bp++; } } + block_given: if (mrb_nil_p(*bp)) return mrb_false_value(); return mrb_true_value(); -- cgit v1.2.3 From d023adcb12191de7d8ae8144f100db46db887e1a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 19 Jul 2020 07:45:16 +0900 Subject: Add new specifier `c` to `mrb_get_args`. `C` retrieves a `mrb_value` that refers a class/module. `c` retrieves a `struct RClass*` pointer to a class/module. --- src/class.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src') diff --git a/src/class.c b/src/class.c index 1a36c1333..30dc4c17a 100644 --- a/src/class.c +++ b/src/class.c @@ -587,6 +587,7 @@ void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); s: String [char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil z: String [char*] NUL terminated string; z! gives NULL for nil a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil + c: Class/Module [strcut RClass*] f: Fixnum/Float [mrb_float] i: Fixnum/Float [mrb_int] b: boolean [mrb_bool] @@ -713,6 +714,22 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } break; + case 'c': + { + struct RClass **p; + + p = va_arg(ap, struct RClass**); + if (i < argc) { + mrb_value ss; + + ss = argv[i++]; + if (!class_ptr_p(ss)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", ss); + } + *p = mrb_class_ptr(ss); + } + } + break; case 'S': { mrb_value *p; -- cgit v1.2.3 From f76defd310c03ace8750abec22938ed3427fceee Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 19 Jul 2020 07:47:07 +0900 Subject: Use `c` specifier for `mrb_get_args`. --- mrbgems/mruby-objectspace/src/mruby_objectspace.c | 12 +++--------- src/class.c | 12 ++++++------ src/kernel.c | 12 ++++++------ 3 files changed, 15 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index b02e01919..16c520732 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -166,12 +166,8 @@ os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud) static mrb_value os_each_object(mrb_state *mrb, mrb_value self) { - mrb_value cls = mrb_nil_value(); - struct os_each_object_data d; - mrb_get_args(mrb, "&!|C", &d.block, &cls); - - d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls); - d.count = 0; + struct os_each_object_data d = {0}; + mrb_get_args(mrb, "&!|c", &d.block, &d.target_module); mrb_objspace_each_objects(mrb, os_each_object_cb, &d); return mrb_fixnum_value(d.count); } @@ -379,10 +375,8 @@ os_memsize_of_all_cb(mrb_state *mrb, struct RBasic *obj, void *d) static mrb_value os_memsize_of_all(mrb_state *mrb, mrb_value self) { - mrb_value type = mrb_nil_value(); struct os_memsize_of_all_cb_data data = { 0 }; - mrb_get_args(mrb, "|C", &type); - data.type = mrb_class_ptr(type); + mrb_get_args(mrb, "|c", &data.type); mrb_objspace_each_objects(mrb, os_memsize_of_all_cb, &data); return mrb_fixnum_value(data.t); } diff --git a/src/class.c b/src/class.c index 30dc4c17a..fc8a38ff9 100644 --- a/src/class.c +++ b/src/class.c @@ -1168,22 +1168,22 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) static mrb_value mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod) { - mrb_value klass; + struct RClass *c; mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "C", &klass); - mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); + mrb_get_args(mrb, "c", &c); + mrb_prepend_module(mrb, c, mrb_class_ptr(mod)); return mod; } static mrb_value mrb_mod_append_features(mrb_state *mrb, mrb_value mod) { - mrb_value klass; + struct RClass *c; mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "C", &klass); - mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); + mrb_get_args(mrb, "c", &c); + mrb_include_module(mrb, c, mrb_class_ptr(mod)); return mod; } diff --git a/src/kernel.c b/src/kernel.c index a74f8a8ed..682feb13c 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -520,11 +520,11 @@ mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c) static mrb_value obj_is_instance_of(mrb_state *mrb, mrb_value self) { - mrb_value arg; + struct RClass *c; - mrb_get_args(mrb, "C", &arg); + mrb_get_args(mrb, "c", &c); - return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg))); + return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, c)); } /* 15.3.1.3.24 */ @@ -557,11 +557,11 @@ obj_is_instance_of(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) { - mrb_value arg; + struct RClass *c; - mrb_get_args(mrb, "C", &arg); + mrb_get_args(mrb, "c", &c); - return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg))); + return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, c)); } KHASH_DECLARE(st, mrb_sym, char, FALSE) -- cgit v1.2.3 From 6334949ba69363cb909a57d6871895bd6d98bb6b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 21 Jul 2020 12:47:35 +0900 Subject: Fix the VM stack handling bug in 'mrb_yield_with_class()`; fix #5042 --- src/vm.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/vm.c b/src/vm.c index 136ea2fcf..f74be7edd 100644 --- a/src/vm.c +++ b/src/vm.c @@ -754,16 +754,25 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ci = cipush(mrb); ci->mid = mid; ci->proc = p; - ci->stackent = mrb->c->stack; - 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->stackent = mrb->c->stack; + mrb->c->stack += n; + if (argc >= CALL_MAXARGS) { + ci->argc = -1; + n = 3; + } + else { + ci->argc = (int)argc; + n = argc + 2; + } mrb_stack_extend(mrb, n); - mrb->c->stack[0] = self; - if (argc > 0) { + if (ci->argc < 0) { + mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); + argc = 1; + } + else if (argc > 0) { stack_copy(mrb->c->stack+1, argv, argc); } mrb->c->stack[argc+1] = mrb_nil_value(); -- cgit v1.2.3 From 670622f45dae813e6e80759b9389309abf98ec8a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 21 Jul 2020 15:55:51 +0900 Subject: Skip unnecessary `mark_context` if `mrb->c == mrb->root_c`. --- src/gc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index fd4fb2406..135d7416d 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1076,7 +1076,9 @@ final_marking_phase(mrb_state *mrb, mrb_gc *gc) } mrb_gc_mark_gv(mrb); mark_context(mrb, mrb->c); - mark_context(mrb, mrb->root_c); + if (mrb->c != mrb->root_c) { + mark_context(mrb, mrb->root_c); + } mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); gc_mark_gray_list(mrb, gc); mrb_assert(gc->gray_list == NULL); -- cgit v1.2.3 From 5533c2983373a9fca5a97074ebe9258841ce4d00 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Jul 2020 14:21:05 +0900 Subject: Use `mrb_field_write_barrier` instead of `mrb_write_barrier` for `push`. When the array is very big, the simpler `mrb_write_barrier` causes calling `gc_mark_children` for big arrays repeatedly. That would hinder performance very badly. --- src/array.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/array.c b/src/array.c index dae2fbf34..eb94fc6c7 100644 --- a/src/array.c +++ b/src/array.c @@ -522,8 +522,10 @@ mrb_ary_push_m(mrb_state *mrb, mrb_value self) } array_copy(ARY_PTR(a)+len, argv, alen); ARY_SET_LEN(a, len2); - mrb_write_barrier(mrb, (struct RBasic*)a); - + while (alen--) { + mrb_field_write_barrier_value(mrb, (struct RBasic*)a, *argv); + argv++; + } return self; } -- cgit v1.2.3 From 097f525817d0825f12780adfc8542bb7f3db1302 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Jul 2020 14:23:10 +0900 Subject: Avoid using `mrb_ary_modify` from the internal function. `mrb_ary_modify` calls `mrb_write_barrier`, so can cause the same problem of the past `push`. It is provided for use-level API. --- src/array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/array.c b/src/array.c index eb94fc6c7..ef8588d31 100644 --- a/src/array.c +++ b/src/array.c @@ -943,7 +943,7 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) mrb_value v1, v2, v3; mrb_int i, len; - mrb_ary_modify(mrb, mrb_ary_ptr(self)); + ary_modify(mrb, mrb_ary_ptr(self)); if (mrb_get_argc(mrb) == 2) { mrb_value *vs = mrb_get_argv(mrb); v1 = vs[0]; v2 = vs[1]; -- cgit v1.2.3 From c99bb756c4d57df5466d4ff0b4749397041aab1a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Jul 2020 14:25:01 +0900 Subject: Move `gray_list` update from `gc_mark_children`. The responsibility moved to caller to avoid confusion. Currently the function is called from only 2 places, so it is relatively easy to ensure not to update `gray_list` in the caller. But the assumption may change in the future. --- src/gc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index 135d7416d..d21b7f9fc 100644 --- a/src/gc.c +++ b/src/gc.c @@ -667,7 +667,6 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) { mrb_assert(is_gray(obj)); paint_black(obj); - gc->gray_list = obj->gcnext; mrb_gc_mark(mrb, (struct RBasic*)obj->c); switch (obj->tt) { case MRB_TT_ICLASS: @@ -1043,10 +1042,9 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) static void gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) { while (gc->gray_list) { - if (is_gray(gc->gray_list)) - gc_mark_children(mrb, gc, gc->gray_list); - else - gc->gray_list = gc->gray_list->gcnext; + struct RBasic *obj = gc->gray_list; + gc->gray_list = obj->gcnext; + gc_mark_children(mrb, gc, obj); } } @@ -1058,6 +1056,7 @@ incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) while (gc->gray_list && tried_marks < limit) { struct RBasic *obj = gc->gray_list; + gc->gray_list = obj->gcnext; gc_mark_children(mrb, gc, obj); tried_marks += gc_gray_counts(mrb, gc, obj); } -- cgit v1.2.3 From 491aa1bfe5809146eec85b7d2915f3d389eb59b5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Jul 2020 14:28:24 +0900 Subject: Use more local variables. To make debugging easy, and to improve the performance little bit. --- src/gc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index d21b7f9fc..e92516ca7 100644 --- a/src/gc.c +++ b/src/gc.c @@ -730,10 +730,11 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; - size_t i, e; + size_t i, e=ARY_LEN(a); + mrb_value *p = ARY_PTR(a); - for (i=0,e=ARY_LEN(a); i Date: Wed, 22 Jul 2020 14:31:07 +0900 Subject: Use more `mrb_field_write_barrier` for instance variables. --- src/variable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/variable.c b/src/variable.c index 0755f7d92..0c94f412e 100644 --- a/src/variable.c +++ b/src/variable.c @@ -350,7 +350,7 @@ mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value obj->iv = iv_new(mrb); } iv_put(mrb, obj->iv, sym, v); - mrb_write_barrier(mrb, (struct RBasic*)obj); + mrb_field_write_barrier_value(mrb, (struct RBasic*)obj, v); } MRB_API void @@ -680,7 +680,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v) if (iv_get(mrb, t, sym, NULL)) { mrb_check_frozen(mrb, c); iv_put(mrb, t, sym, v); - mrb_write_barrier(mrb, (struct RBasic*)c); + mrb_field_write_barrier_value(mrb, (struct RBasic*)c, v); return; } c = c->super; @@ -712,7 +712,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v) } iv_put(mrb, c->iv, sym, v); - mrb_write_barrier(mrb, (struct RBasic*)c); + mrb_field_write_barrier_value(mrb, (struct RBasic*)c, v); } MRB_API void -- cgit v1.2.3 From e7599050dc7055bc013b4114401e62670bf86828 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 23 Jul 2020 07:06:35 +0900 Subject: Fix a bug with `ht_index` called with `size==0`; fix #5046 It happens when a hash made empty calls `rehash`. --- src/hash.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hash.c b/src/hash.c index 79b61d8b2..9a690bf1a 100644 --- a/src/hash.c +++ b/src/hash.c @@ -174,6 +174,11 @@ ht_index(mrb_state *mrb, htable *t) segment *seg; size_t i; + if (size == 0) { + t->index = NULL; + mrb_free(mrb, index); + return; + } /* allocate index table */ if (index && index->size >= UPPER_BOUND(index->capa)) { size = index->capa+1; @@ -194,7 +199,7 @@ ht_index(mrb_state *mrb, htable *t) index->table[i] = NULL; } - /* rebuld index */ + /* rebuild index */ mask = HT_MASK(index); seg = t->rootseg; while (seg) { -- cgit v1.2.3 From 5c2b11d21581cf472929b21f28f1a388a16f0865 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 Jul 2020 23:55:26 +0900 Subject: Avoid using FPU with `mruby-os-memsize`; ref #5032 And, in the calculation of the instance variable size, the fraction was always rounded down because of division of integers, so fix it. At the same time, test items that are no longer passed due to this change are deleted. --- mrbgems/mruby-os-memsize/test/memsize.rb | 14 -------------- src/variable.c | 7 +++---- 2 files changed, 3 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/mrbgems/mruby-os-memsize/test/memsize.rb b/mrbgems/mruby-os-memsize/test/memsize.rb index 9e8d41165..6be8f1b06 100644 --- a/mrbgems/mruby-os-memsize/test/memsize.rb +++ b/mrbgems/mruby-os-memsize/test/memsize.rb @@ -22,20 +22,6 @@ assert 'ObjectSpace.memsize_of' do empty_class_def_size = ObjectSpace.memsize_of Class.new assert_not_equal empty_class_def_size, 0, 'Class def not zero' - class_without_methods = Class.new do - @a = 1 - @b = 2 - end - class_total_size = empty_class_def_size + (int_size * 2) - assert_equal ObjectSpace.memsize_of(class_without_methods), class_total_size, 'class without methods size' - - module_without_methods = Module.new do - @a = 1 - @b = 2 - end - module_total_size = empty_class_def_size + (int_size * 2) - assert_equal ObjectSpace.memsize_of(module_without_methods), module_total_size, 'module without methods size' - proc_size = ObjectSpace.memsize_of Proc.new { x = 1; x } assert_not_equal proc_size, 0 diff --git a/src/variable.c b/src/variable.c index 0755f7d92..8c16b2d4f 100644 --- a/src/variable.c +++ b/src/variable.c @@ -4,7 +4,6 @@ ** See Copyright Notice in mruby.h */ -#include #include #include #include @@ -1132,9 +1131,9 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c) mrb_int mrb_obj_iv_tbl_memsize(mrb_state* mrb, mrb_value obj) { - return sizeof(iv_tbl) + - (sizeof(segment) * ceil(iv_size(mrb, mrb_obj_ptr(obj)->iv)/ - MRB_IV_SEGMENT_SIZE)); + size_t ivsize = iv_size(mrb, mrb_obj_ptr(obj)->iv); + size_t ivsegs = (ivsize + MRB_IV_SEGMENT_SIZE - 1) / MRB_IV_SEGMENT_SIZE; + return sizeof(iv_tbl) + (sizeof(segment) * ivsegs); } #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) -- cgit v1.2.3 From ccd5f203bf1e7c54cb08fc9eecfe2772277b5a58 Mon Sep 17 00:00:00 2001 From: dearblue Date: Wed, 22 Jul 2020 00:18:28 +0900 Subject: Improve prototype for `mrb_objspace_page_slot_size()`; ref #5032 If it qualify a return type that is not a pointer with `const`, the compiler ignores it. --- include/mruby/gc.h | 2 +- src/gc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/include/mruby/gc.h b/include/mruby/gc.h index 3b2ded9d4..1beffba2a 100644 --- a/include/mruby/gc.h +++ b/include/mruby/gc.h @@ -21,7 +21,7 @@ struct mrb_state; #define MRB_EACH_OBJ_BREAK 1 typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data); void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data); -const mrb_int mrb_objspace_page_slot_size(); +mrb_int mrb_objspace_page_slot_size(void); MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c); #ifndef MRB_GC_ARENA_SIZE diff --git a/src/gc.c b/src/gc.c index fd4fb2406..fa7f30889 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1599,8 +1599,8 @@ mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, vo } } -const mrb_int -mrb_objspace_page_slot_size() +mrb_int +mrb_objspace_page_slot_size(void) { const mrb_int i = sizeof(RVALUE); return i; -- cgit v1.2.3 From f868d7d357d7456f15fa4c1d0219784aa1c8c2c6 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 24 Jul 2020 13:13:06 +0900 Subject: Change the logic to calculate object (`iv_tbl`) size; #5045 --- src/variable.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/variable.c b/src/variable.c index 8b4bdf0ce..f05fcee90 100644 --- a/src/variable.c +++ b/src/variable.c @@ -1131,9 +1131,16 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c) mrb_int mrb_obj_iv_tbl_memsize(mrb_state* mrb, mrb_value obj) { - size_t ivsize = iv_size(mrb, mrb_obj_ptr(obj)->iv); - size_t ivsegs = (ivsize + MRB_IV_SEGMENT_SIZE - 1) / MRB_IV_SEGMENT_SIZE; - return sizeof(iv_tbl) + (sizeof(segment) * ivsegs); + size_t nseg = 0; + segment *seg; + + if (mrb_obj_ptr(obj)->iv == NULL) return 0; + seg = mrb_obj_ptr(obj)->iv->rootseg; + while (seg) { + nseg++; + seg = seg->next; + } + return sizeof(iv_tbl) + sizeof(segment)*nseg; } #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) -- cgit v1.2.3 From 0c88c717861a4ec182e41f2c290ec0ef31029967 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sat, 25 Jul 2020 16:59:02 +0900 Subject: Use type tag for hash code in `ht_hash_func()` The function corresponding to `ht_hash_func()` was as follows in the days of khash implementation (before d78acc7a). ```c mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key) { enum mrb_vtype t = mrb_type(key); ... switch (t) { ... default: hv = mrb_funcall(mrb, key, "hash", 0); h = (khint_t)t ^ (khint_t)mrb_fixnum(hv); break; } ... } ``` When switched to the segmented list implementation (d78acc7a), this function was changed as follows. ```c sg_hash_func(mrb_state *mrb, seglist *t, mrb_value key) { enum mrb_vtype tt = mrb_type(key); ... switch (tt) { ... default: hv = mrb_funcall(mrb, key, "hash", 0); h = (size_t)t ^ (size_t)mrb_fixnum(hv); break; } ... } ``` Since the argument `t` was added, the variable for type tag was changed from `t` to `tt`, but the variable used in the expression of `h` remained `t`. Probably this is an omission of change, so fixed it. --- src/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hash.c b/src/hash.c index 9a690bf1a..128836fce 100644 --- a/src/hash.c +++ b/src/hash.c @@ -73,7 +73,7 @@ ht_hash_func(mrb_state *mrb, htable *t, mrb_value key) default: hv = mrb_funcall(mrb, key, "hash", 0); - h = (size_t)t ^ (size_t)mrb_fixnum(hv); + h = (size_t)tt ^ (size_t)mrb_fixnum(hv); break; } if (index && (index != t->index || capa != index->capa)) { -- cgit v1.2.3 From d96be5c1b2304c21ab9f15023a96e21b9ea279c6 Mon Sep 17 00:00:00 2001 From: dearblue Date: Wed, 29 Apr 2020 18:02:17 +0900 Subject: Extend the `cipush()` and `cipop()` functions - Returns the updated call info. - Unify the processing around `cipush()`. - `cipop()` restores the stack. --- src/vm.c | 130 +++++++++++++++------------------------------------------------ 1 file changed, 30 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/vm.c b/src/vm.c index f74be7edd..79bb3ed60 100644 --- a/src/vm.c +++ b/src/vm.c @@ -269,14 +269,13 @@ top_proc(mrb_state *mrb, struct RProc *proc) #define CI_ACC_RESUMED -3 static inline mrb_callinfo* -cipush(mrb_state *mrb) +cipush(mrb_state *mrb, const mrb_code *pc, int push_stacks, int acc, + struct RClass *target_class, struct RProc *proc, mrb_sym mid, int argc) { struct mrb_context *c = mrb->c; static const mrb_callinfo ci_zero = { 0 }; mrb_callinfo *ci = c->ci; - int ridx = ci->ridx; - if (ci + 1 == c->ciend) { ptrdiff_t size = ci - c->cibase; @@ -286,8 +285,16 @@ cipush(mrb_state *mrb) } ci = ++c->ci; *ci = ci_zero; - ci->epos = mrb->c->eidx; - ci->ridx = ridx; + ci->mid = mid; + ci->proc = proc; + ci->stackent = c->stack; + ci->epos = c->eidx; + ci->ridx = ci[-1].ridx; + ci->pc = pc; + ci->argc = argc; + ci->acc = acc; + ci->target_class = target_class; + c->stack += push_stacks; return ci; } @@ -313,14 +320,16 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e) } } -static inline void +static inline mrb_callinfo* cipop(mrb_state *mrb) { struct mrb_context *c = mrb->c; struct REnv *env = c->ci->env; + mrb->c->stack = c->ci->stackent; c->ci--; if (env) mrb_env_unshare(mrb, env); + return c->ci; } void mrb_exc_set(mrb_state *mrb, mrb_value exc); @@ -356,16 +365,9 @@ ecall(mrb_state *mrb) nregs = ci->proc->body.irep->nregs; } cioff = ci - c->cibase; - ci = cipush(mrb); - ci->stackent = mrb->c->stack; - ci->mid = ci[-1].mid; - ci->acc = CI_ACC_SKIP; - ci->argc = 0; - ci->proc = p; - ci->target_class = MRB_PROC_TARGET_CLASS(p); + ci = cipush(mrb, NULL, nregs, CI_ACC_SKIP, MRB_PROC_TARGET_CLASS(p), p, ci->mid, 0); env = MRB_PROC_ENV(p); mrb_assert(env); - c->stack += nregs; exc = mrb->exc; mrb->exc = 0; if (exc) { mrb_gc_protect(mrb, mrb_obj_value(exc)); @@ -447,7 +449,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc } MRB_CATCH(&c_jmp) { /* error */ while (nth_ci < (mrb->c->ci - mrb->c->cibase)) { - mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); } mrb->jmp = 0; @@ -486,12 +487,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } - ci = cipush(mrb); - ci->mid = mid; - ci->stackent = mrb->c->stack; - ci->argc = (int)argc; - ci->target_class = c; - mrb->c->stack = mrb->c->stack + n; + ci = cipush(mrb, NULL, n, 0, c, NULL, mid, argc); if (argc < 0) argc = 1; if (mrb->c->stbase <= argv && argv < mrb->c->stend) { voff = argv - mrb->c->stbase; @@ -524,7 +520,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (MRB_METHOD_CFUNC_P(m)) { ci->acc = CI_ACC_DIRECT; val = MRB_METHOD_CFUNC(m)(mrb, self); - mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); } else { @@ -565,11 +560,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) stack_clear(mrb->c->stack+keep, nregs-keep); } - ci = cipush(mrb); - ci->target_class = 0; - ci->pc = p->body.irep->iseq; - ci->stackent = mrb->c->stack; - ci->acc = 0; + cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); return self; } @@ -671,11 +662,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb->c->stack[0] = self; mrb->c->stack[1] = self; stack_clear(mrb->c->stack+2, nregs-2); - ci = cipush(mrb); - ci->target_class = 0; - ci->pc = p->body.irep->iseq; - ci->stackent = mrb->c->stack; - ci->acc = 0; + ci = cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); return self; } @@ -751,13 +738,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } p = mrb_proc_ptr(b); - ci = cipush(mrb); - ci->mid = mid; - ci->proc = p; - ci->target_class = c; - ci->acc = CI_ACC_SKIP; - ci->stackent = mrb->c->stack; - mrb->c->stack += n; + ci = cipush(mrb, NULL, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */); if (argc >= CALL_MAXARGS) { ci->argc = -1; n = 3; @@ -779,7 +760,6 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value if (MRB_PROC_CFUNC_P(p)) { val = MRB_PROC_CFUNC(p)(mrb, self); - mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); } else { @@ -1328,15 +1308,7 @@ RETRY_TRY_BLOCK: mrb->c->ensure[epos+n] = NULL; if (proc == NULL) continue; irep = proc->body.irep; - ci = cipush(mrb); - ci->mid = ci[-1].mid; - ci->argc = 0; - ci->proc = proc; - ci->stackent = mrb->c->stack; - ci->target_class = target_class; - ci->pc = pc; - ci->acc = nregs; - mrb->c->stack += ci->acc; + ci = cipush(mrb, pc, nregs, nregs, target_class, proc, ci->mid, 0); mrb_stack_extend(mrb, irep->nregs); regs[0] = self; pc = irep->iseq; @@ -1418,17 +1390,7 @@ RETRY_TRY_BLOCK: } /* push callinfo */ - ci = cipush(mrb); - ci->mid = mid; - ci->stackent = mrb->c->stack; - ci->target_class = cls; - ci->argc = argc; - - ci->pc = pc; - ci->acc = a; - - /* prepare stack */ - mrb->c->stack += a; + ci = cipush(mrb, pc, a, a, cls, NULL, mid, argc); if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { @@ -1470,7 +1432,6 @@ RETRY_TRY_BLOCK: } mrb->c->stack[0] = recv; /* pop stackpos */ - mrb->c->stack = ci->stackent; pc = ci->pc; cipop(mrb); JUMP; @@ -1508,10 +1469,9 @@ RETRY_TRY_BLOCK: if (mrb->exc) goto L_RAISE; /* pop stackpos */ ci = mrb->c->ci; - mrb->c->stack = ci->stackent; - regs[ci->acc] = recv; pc = ci->pc; cipop(mrb); + regs[ci->acc] = recv; irep = mrb->c->ci->proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1617,15 +1577,9 @@ RETRY_TRY_BLOCK: } /* push callinfo */ - ci = cipush(mrb); - ci->mid = mid; - ci->stackent = mrb->c->stack; - ci->target_class = cls; - ci->pc = pc; - ci->argc = argc; + ci = cipush(mrb, pc, a, 0, cls, NULL, mid, argc); /* prepare stack */ - mrb->c->stack += a; mrb->c->stack[0] = recv; if (MRB_METHOD_CFUNC_P(m)) { @@ -1652,8 +1606,6 @@ RETRY_TRY_BLOCK: } } mrb->c->stack[0] = v; - /* pop stackpos */ - mrb->c->stack = ci->stackent; pc = ci->pc; cipop(mrb); JUMP; @@ -1954,13 +1906,11 @@ RETRY_TRY_BLOCK: goto L_RESCUE; } while (ci[0].ridx == ci[-1].ridx) { - cipop(mrb); - mrb->c->stack = ci->stackent; - if (ci->acc == CI_ACC_SKIP && prev_jmp) { + ci = cipop(mrb); + if (ci[1].acc == CI_ACC_SKIP && prev_jmp) { mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } - ci = mrb->c->ci; if (ci == mrb->c->cibase) { if (ci->ridx == 0) { L_FTOP: /* fiber top */ @@ -2142,15 +2092,13 @@ RETRY_TRY_BLOCK: return v; } acc = ci->acc; - mrb->c->stack = ci->stackent; - cipop(mrb); + ci = cipop(mrb); if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) { mrb_gc_arena_restore(mrb, ai); mrb->jmp = prev_jmp; return v; } - pc = ci->pc; - ci = mrb->c->ci; + pc = ci[1].pc; DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); proc = mrb->c->ci->proc; irep = proc->body.irep; @@ -2664,7 +2612,6 @@ RETRY_TRY_BLOCK: } CASE(OP_EXEC, BB) { - mrb_callinfo *ci; mrb_value recv = regs[a]; struct RProc *p; mrb_irep *nirep = irep->reps[b]; @@ -2677,19 +2624,7 @@ RETRY_TRY_BLOCK: p->flags |= MRB_PROC_SCOPE; /* prepare call stack */ - ci = cipush(mrb); - ci->pc = pc; - ci->acc = a; - ci->mid = 0; - ci->stackent = mrb->c->stack; - ci->argc = 0; - ci->target_class = mrb_class_ptr(recv); - - /* prepare stack */ - mrb->c->stack += a; - - /* setup block to call */ - ci->proc = p; + cipush(mrb, pc, a, a, mrb_class_ptr(recv), p, 0, 0); irep = p->body.irep; pool = irep->pool; @@ -2834,7 +2769,6 @@ 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_callinfo *ci; mrb_value v; if (!mrb->c->cibase) { @@ -2844,11 +2778,7 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta mrb->c->ci->env = NULL; return mrb_vm_run(mrb, proc, self, stack_keep); } - ci = cipush(mrb); - ci->stackent = mrb->c->stack; - ci->mid = 0; - ci->acc = CI_ACC_SKIP; - ci->target_class = mrb->object_class; + cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); v = mrb_vm_run(mrb, proc, self, stack_keep); return v; -- cgit v1.2.3 From faed5054f8a1503b8b755ea5be8575fc8b68e110 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 3 Aug 2020 15:53:50 +0900 Subject: Initialized local variables in `mrb_hash_shift()`. --- src/hash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hash.c b/src/hash.c index 128836fce..fd338d53b 100644 --- a/src/hash.c +++ b/src/hash.c @@ -1072,7 +1072,8 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash) mrb_hash_modify(mrb, hash); if (t && t->size > 0) { - mrb_value del_key, del_val; + mrb_value del_key = mrb_nil_value(); + mrb_value del_val = mrb_nil_value(); ht_shift(mrb, t, &del_key, &del_val); mrb_gc_protect(mrb, del_key); -- cgit v1.2.3