mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Fix name assignment to frozen anonymous class/module
Fix the following issues: A = Class.new.freeze #=> FrozenError Module.new::B = Class.new.freeze #=> FrozenError String::B = Module.new.freeze #=> FrozenError
This commit is contained in:
@@ -117,6 +117,7 @@ MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_
|
||||
MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v);
|
||||
MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym);
|
||||
mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*);
|
||||
void mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
|
||||
mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod);
|
||||
mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
|
||||
|
||||
+3
-3
@@ -66,15 +66,15 @@ mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb
|
||||
name = mrb_class_path(mrb, outer);
|
||||
if (mrb_nil_p(name)) { /* unnamed outer class */
|
||||
if (outer != mrb->object_class && outer != c) {
|
||||
mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
|
||||
mrb_obj_value(outer));
|
||||
mrb_obj_iv_set_force(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
|
||||
mrb_obj_value(outer));
|
||||
}
|
||||
return;
|
||||
}
|
||||
mrb_str_cat_cstr(mrb, name, "::");
|
||||
mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id));
|
||||
}
|
||||
mrb_obj_iv_set(mrb, (struct RObject*)c, nsym, name);
|
||||
mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+12
-9
@@ -341,21 +341,24 @@ mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym)
|
||||
|
||||
static inline void assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
|
||||
|
||||
MRB_API void
|
||||
mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
|
||||
void
|
||||
mrb_obj_iv_set_force(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
|
||||
{
|
||||
iv_tbl *t;
|
||||
|
||||
mrb_check_frozen(mrb, 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);
|
||||
iv_put(mrb, obj->iv, sym, v);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)obj);
|
||||
}
|
||||
|
||||
MRB_API void
|
||||
mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
|
||||
{
|
||||
mrb_check_frozen(mrb, obj);
|
||||
mrb_obj_iv_set_force(mrb, obj, sym, v);
|
||||
}
|
||||
|
||||
/* Iterates over the instance variable table. */
|
||||
MRB_API void
|
||||
mrb_iv_foreach(mrb_state *mrb, mrb_value obj, mrb_iv_foreach_func *func, void *p)
|
||||
@@ -385,10 +388,10 @@ assign_class_name(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
|
||||
|
||||
if (mrb_nil_p(o)) {
|
||||
if ((struct RClass *)obj == mrb->object_class) {
|
||||
mrb_obj_iv_set(mrb, c, id_classname, mrb_symbol_value(sym));
|
||||
mrb_obj_iv_set_force(mrb, c, id_classname, mrb_symbol_value(sym));
|
||||
}
|
||||
else {
|
||||
mrb_obj_iv_set(mrb, c, id_outer, mrb_obj_value(obj));
|
||||
mrb_obj_iv_set_force(mrb, c, id_outer, mrb_obj_value(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,6 +653,10 @@ assert('Module#to_s') do
|
||||
|
||||
assert_match "#<Module:0x*>", Module.new.to_s
|
||||
assert_match "#<Class:0x*>", Class.new.to_s
|
||||
|
||||
assert_equal "FrozenClassToS", (FrozenClassToS = Class.new.freeze).to_s
|
||||
assert_equal "Outer::A", (Outer::A = Module.new.freeze).to_s
|
||||
assert_match "#<Module:0x*>::A", (Module.new::A = Class.new.freeze).to_s
|
||||
end
|
||||
|
||||
assert('Module#inspect') do
|
||||
|
||||
Reference in New Issue
Block a user