なかだです。

At Thu, 12 Feb 2009 10:34:51 +0900,
Yukihiro Matsumoto wrote in [ruby-dev:37969]:
>   * ObjectSpaceは裏技。やる方が悪い(からバグじゃない)
>   * 禁止できるものなら禁止した方がよい(からバグ)
> 
> の両方の考え方ができると思います。
> 
> ....
> 
> いろいろ考えましたが、過去にもObjectSpaceの「まずいこと」に
> 手当てしてきた経緯がありますし、バグとみなすことにします。で、
> その場合の修正方法ですが、freezeで構わないと思います。

freeze以前に、ObjectSpaceから不可視であるべきではないかと思いま
す。また、隠しオブジェクトから通常のStringを作るために
rb_str_replace()を使っていますが、これはintern.hで公開してもかま
わないんではないでしょうか。


Index: compile.c =================================================================== --- compile.c (revision 22249) +++ compile.c (working copy) @@ -296,4 +296,5 @@ PRINTF_ARGS(void ruby_debug_printf(const (name##_body__.last = &name##_body__.anchor, name = &name##_body__) +#define hide_obj(obj) (void)(RBASIC(obj)->klass = 0) #include "optinsn.inc" @@ -2231,5 +2232,5 @@ compile_array_(rb_iseq_t *iseq, LINK_ANC if (opt_p == Qtrue) { if (!poped) { - VALUE ary = rb_ary_new(); + VALUE ary = rb_ary_tmp_new(len); node = node_root; while (node) { @@ -2710,4 +2711,5 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHO if (needstr != Qfalse) { VALUE str = rb_str_new2(estr); + hide_obj(str); ADD_INSN1(ret, nd_line(node), putstring, str); iseq_add_mark_object_compile_time(iseq, str); @@ -4354,4 +4356,5 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ debugp_param("nd_lit", node->nd_lit); if (!poped) { + hide_obj(node->nd_lit); ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit); } Index: string.c =================================================================== --- string.c (revision 22249) +++ string.c (working copy) @@ -816,6 +816,4 @@ rb_obj_as_string(VALUE obj) } -static VALUE rb_str_replace(VALUE, VALUE); - VALUE rb_str_dup(VALUE str) @@ -3723,5 +3721,5 @@ rb_str_gsub(int argc, VALUE *argv, VALUE */ -static VALUE +VALUE rb_str_replace(VALUE str, VALUE str2) { Index: insns.def =================================================================== --- insns.def (revision 22249) +++ insns.def (working copy) @@ -374,5 +374,6 @@ putstring (VALUE val) { - val = rb_str_new3(str); + VALUE rb_str_replace(VALUE, VALUE); + val = rb_str_replace(rb_str_new(0, 0), str); } @@ -461,5 +462,5 @@ duparray (VALUE val) { - val = rb_ary_dup(ary); + val = rb_ary_replace(rb_ary_new2(0), ary); } Index: include/ruby/intern.h =================================================================== --- include/ruby/intern.h (revision 22249) +++ include/ruby/intern.h (working copy) @@ -618,4 +618,5 @@ VALUE rb_str_equal(VALUE str1, VALUE str VALUE rb_str_drop_bytes(VALUE, long); void rb_str_update(VALUE, long, long, VALUE); +VALUE rb_str_replace(VALUE, VALUE); VALUE rb_str_inspect(VALUE); VALUE rb_str_dump(VALUE);
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦