error.c: a new function mrb_check_frozen_value()

This commit is contained in:
Yukihiro "Matz" Matsumoto
2023-05-31 08:31:13 +09:00
parent 8b39a7825d
commit ccdf75c1c2
3 changed files with 24 additions and 7 deletions
+1 -1
View File
@@ -1434,7 +1434,7 @@ MRB_INLINE void mrb_check_frozen(mrb_state *mrb, void *o)
{
if (mrb_frozen_p((struct RBasic*)o)) mrb_frozen_error(mrb, o);
}
MRB_API void mrb_check_frozen_value(mrb_state *mrb, mrb_value v);
MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *c, const char *a, const char *b);
MRB_API void mrb_define_alias_id(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b);
MRB_API const char *mrb_class_name(mrb_state *mrb, struct RClass* klass);
+8 -5
View File
@@ -756,7 +756,13 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_
MRB_CLASS_ORIGIN(c);
h = c->mt;
mrb_check_frozen(mrb, c);
if (c->tt == MRB_TT_SCLASS && mrb_frozen_p(c)) {
mrb_value v = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__));
mrb_check_frozen_value(mrb, v);
}
else {
mrb_check_frozen(mrb, c);
}
if (!h) h = c->mt = mt_new(mrb);
if (MRB_METHOD_PROC_P(m)) {
struct RProc *p = MRB_METHOD_PROC(m);
@@ -1011,10 +1017,7 @@ get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap)
if (i < argc) {
pickarg = &argv[i++];
if (needmodify && !mrb_nil_p(*pickarg)) {
if (mrb_immediate_p(*pickarg)) {
mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", *pickarg);
}
mrb_check_frozen(mrb, mrb_obj_ptr(*pickarg));
mrb_check_frozen_value(mrb, *pickarg);
}
}
else {
+15 -1
View File
@@ -518,10 +518,24 @@ mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt,
mrb_exc_raise(mrb, exc);
}
static mrb_noreturn void
frozen_error(mrb_state *mrb, mrb_value v)
{
mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", v);
}
MRB_API mrb_noreturn void
mrb_frozen_error(mrb_state *mrb, void *frozen_obj)
{
mrb_raisef(mrb, E_FROZEN_ERROR, "can't modify frozen %t", mrb_obj_value(frozen_obj));
frozen_error(mrb, mrb_obj_value(frozen_obj));
}
MRB_API void
mrb_check_frozen_value(mrb_state *mrb, mrb_value v)
{
if (mrb_immediate_p(v) || mrb_frozen_p(mrb_basic_ptr(v))) {
frozen_error(mrb, v);
}
}
MRB_API mrb_noreturn void