diff options
Diffstat (limited to 'mrbgems/mruby-struct/src')
| -rw-r--r-- | mrbgems/mruby-struct/src/struct.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 93bd1e2b2..67762a948 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -13,8 +13,8 @@ #include <mruby/hash.h> #include <mruby/range.h> -#define RSTRUCT_LEN(st) mrb_ary_ptr(st)->len -#define RSTRUCT_PTR(st) mrb_ary_ptr(st)->ptr +#define RSTRUCT_LEN(st) RARRAY_LEN(st) +#define RSTRUCT_PTR(st) RARRAY_PTR(st) static struct RClass * struct_class(mrb_state *mrb) @@ -84,6 +84,16 @@ mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass) return ary; } +static void +mrb_struct_modify(mrb_state *mrb, mrb_value strct) +{ + if (MRB_FROZEN_P(mrb_basic_ptr(strct))) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct"); + } + + mrb_write_barrier(mrb, mrb_basic_ptr(strct)); +} + /* 15.2.18.4.6 */ /* * call-seq: @@ -266,7 +276,6 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass) mrb_int argc; name = mrb_nil_value(); - rest = mrb_nil_value(); mrb_get_args(mrb, "*&", &argv, &argc, &b); if (argc == 0) { /* special case to avoid crash */ rest = mrb_ary_new(mrb); @@ -336,7 +345,7 @@ mrb_struct_initialize(mrb_state *mrb, mrb_value self) mrb_value *argv; mrb_int argc; - mrb_get_args(mrb, "*", &argv, &argc); + mrb_get_args(mrb, "*!", &argv, &argc); return mrb_struct_initialize_withArg(mrb, argc, argv, self); } @@ -448,6 +457,7 @@ mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { if (mrb_symbol(ptr_members[i]) == id) { + mrb_struct_modify(mrb, s); ptr[i] = val; return val; } @@ -511,6 +521,7 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) "offset %S too large for struct(size:%S)", mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); } + mrb_struct_modify(mrb, s); return RSTRUCT_PTR(s)[i] = val; } @@ -636,7 +647,7 @@ mrb_struct_to_h(mrb_state *mrb, mrb_value self) mrb_value members, ret; mrb_int i; - members = struct_s_members(mrb, mrb_class(mrb, self)); + members = struct_members(mrb, self); ret = mrb_hash_new_capa(mrb, RARRAY_LEN(members)); for (i = 0; i < RARRAY_LEN(members); ++i) { @@ -677,6 +688,7 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) { struct RClass *st; st = mrb_define_class(mrb, "Struct", mrb->object_class); + MRB_SET_INSTANCE_TT(st, MRB_TT_ARRAY); mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ |
