static void ary_modify_check(mrb_state *mrb, struct RArray *a) { if (MRB_FROZEN_P(a)) { mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array"); } }
static void mrb_hash_modify(mrb_state *mrb, mrb_value hash) { if (MRB_FROZEN_P(mrb_hash_ptr(hash))) { mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash"); } mrb_hash_tbl(mrb, hash); }
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)); }
static inline mrb_value mrb_hash_ht_key(mrb_state *mrb, mrb_value key) { if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) { key = mrb_str_dup(mrb, key); MRB_SET_FROZEN_FLAG(mrb_str_ptr(key)); } return key; }
MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) { iv_tbl *t = obj->iv; if (MRB_FROZEN_P(obj)) { mrb_raisef(mrb, E_RUNTIME_ERROR, "can't modify frozen %S", mrb_obj_value(obj)); } if (!t) { t = obj->iv = iv_new(mrb); } mrb_write_barrier(mrb, (struct RBasic*)obj); iv_put(mrb, t, sym, v); }
MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) { iv_tbl *t; if (MRB_FROZEN_P(obj)) { mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %S", mrb_obj_value(obj)); } assign_class_name(mrb, obj, sym, v); if (!obj->iv) { obj->iv = iv_new(mrb); } t = obj->iv; iv_put(mrb, t, sym, v); mrb_write_barrier(mrb, (struct RBasic*)obj); }
static void ary_replace(mrb_state *mrb, struct RArray *a, struct RArray *b) { mrb_int len = ARY_LEN(b); ary_modify_check(mrb, a); if (a == b) return; if (ARY_SHARED_P(a)) { mrb_ary_decref(mrb, a->as.heap.aux.shared); a->as.heap.aux.capa = 0; a->as.heap.len = 0; a->as.heap.ptr = NULL; ARY_UNSET_SHARED_FLAG(a); } if (ARY_SHARED_P(b)) { shared_b: if (ARY_EMBED_P(a)) { ARY_UNSET_EMBED_FLAG(a); } else { mrb_free(mrb, a->as.heap.ptr); } a->as.heap.ptr = b->as.heap.ptr; a->as.heap.len = len; a->as.heap.aux.shared = b->as.heap.aux.shared; a->as.heap.aux.shared->refcnt++; ARY_SET_SHARED_FLAG(a); mrb_write_barrier(mrb, (struct RBasic*)a); return; } if (!MRB_FROZEN_P(b) && len > ARY_REPLACE_SHARED_MIN) { ary_make_shared(mrb, b); goto shared_b; } if (ARY_CAPA(a) < len) ary_expand_capa(mrb, a, len); array_copy(ARY_PTR(a), ARY_PTR(b), len); mrb_write_barrier(mrb, (struct RBasic*)a); ARY_SET_LEN(a, len); }
static mrb_value mrb_obj_frozen(mrb_state *mrb, mrb_value self) { struct RBasic *b; switch (mrb_type(self)) { case MRB_TT_FALSE: case MRB_TT_TRUE: case MRB_TT_FIXNUM: case MRB_TT_SYMBOL: case MRB_TT_FLOAT: return mrb_true_value(); default: break; } b = mrb_basic_ptr(self); if (!MRB_FROZEN_P(b)) { return mrb_false_value(); } return mrb_true_value(); }
static mrb_value mrb_obj_freeze(mrb_state *mrb, mrb_value self) { struct RBasic *b; switch (mrb_type(self)) { case MRB_TT_FALSE: case MRB_TT_TRUE: case MRB_TT_FIXNUM: case MRB_TT_SYMBOL: case MRB_TT_FLOAT: return self; default: break; } b = mrb_basic_ptr(self); if (!MRB_FROZEN_P(b)) { MRB_SET_FROZEN_FLAG(b); } return self; }