From 417092360dced241f9cc04884887a55c2407e81a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 25 Jul 2016 10:32:10 +0900 Subject: Fixed crash error when #initialize is redefined for Struct; fix #3177 refactored redundant functions; removed optimized accessors for safety this fix also close #3178 --- mrbgems/mruby-struct/src/struct.c | 120 +++++++++----------------------------- 1 file changed, 27 insertions(+), 93 deletions(-) diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index f084e4031..51256c6af 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -61,9 +61,14 @@ struct_members(mrb_state *mrb, mrb_value s) mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { - mrb_raisef(mrb, E_TYPE_ERROR, - "struct size differs (%S required %S given)", - mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s))); + if (RSTRUCT_LEN(s) == 0) { /* probably uninitialized */ + mrb_ary_resize(mrb, s, RARRAY_LEN(members)); + } + else { + mrb_raisef(mrb, E_TYPE_ERROR, + "struct size differs (%S required %S given)", + mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s))); + } } return members; } @@ -98,60 +103,14 @@ mrb_struct_members(mrb_state *mrb, mrb_value obj) return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj))); } -static mrb_value -mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id) -{ - mrb_value members, slot, *ptr; - const mrb_value *ptr_members; - mrb_int i, len; - - ptr = RSTRUCT_PTR(obj); - members = struct_members(mrb, obj); - ptr_members = RARRAY_PTR(members); - slot = mrb_symbol_value(id); - len = RARRAY_LEN(members); - for (i=0; ic->ci->mid); + return struct_aref_sym(mrb, obj, mrb->c->ci->mid); } -static mrb_value mrb_struct_ref0(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[0];} -static mrb_value mrb_struct_ref1(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[1];} -static mrb_value mrb_struct_ref2(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[2];} -static mrb_value mrb_struct_ref3(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[3];} -static mrb_value mrb_struct_ref4(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[4];} -static mrb_value mrb_struct_ref5(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[5];} -static mrb_value mrb_struct_ref6(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[6];} -static mrb_value mrb_struct_ref7(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[7];} -static mrb_value mrb_struct_ref8(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[8];} -static mrb_value mrb_struct_ref9(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[9];} - -#define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) -#define N_REF_FUNC numberof(ref_func) - -static const mrb_func_t ref_func[] = { - mrb_struct_ref0, - mrb_struct_ref1, - mrb_struct_ref2, - mrb_struct_ref3, - mrb_struct_ref4, - mrb_struct_ref5, - mrb_struct_ref6, - mrb_struct_ref7, - mrb_struct_ref8, - mrb_struct_ref9, -}; - static mrb_sym mrb_id_attrset(mrb_state *mrb, mrb_sym id) { @@ -171,40 +130,24 @@ mrb_id_attrset(mrb_state *mrb, mrb_sym id) return mid; } +static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val); + static mrb_value -mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) +mrb_struct_set_m(mrb_state *mrb, mrb_value obj) { + mrb_value val; + const char *name; - mrb_int i, len, slen; + mrb_int slen; mrb_sym mid; - mrb_value members, slot, *ptr; - const mrb_value *ptr_members; + + mrb_get_args(mrb, "o", &val); /* get base id */ name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen); mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */ - members = struct_members(mrb, obj); - ptr_members = RARRAY_PTR(members); - len = RARRAY_LEN(members); - ptr = RSTRUCT_PTR(obj); - for (i=0; i