[ruby-core:16238]$B$N8!>Z(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

e$B%U%i%s%9HG%Q%C%A%b%s%9%?!<$G$"$k$H$3$m$Ne(BGuy Decouxe$B$K$h$k%Q%Ce(B
e$B%Ae(B[ruby-core:16238]e$B$re(B1.8.7e$B$K<h$j9~$_$?$$$s$G$9$,!"$3$l$N%A%’%Ce(B
e$B%/$r9T$&;~4V$N$"$k?M$O$$$^$9$+!)e(B

e$B;d<+?H$Oe(B1.8.7e$B$K4V$K9g$&$h$&$K;~4V$,<h$l$k<+?.$,$"$j$^$;$s!#e(B

At Fri, 25 Apr 2008 22:11:27 +0900,
I wrote:

いいかもしれません。
 ruby_1_8 の方に commit しました。

 しばらくテストしてみて ruby_1_8_7 にも適用し、 preview3 に
入れるつもりです。

At Fri, 25 Apr 2008 18:12:39 +0900,
matz wrote:

フランス版パッチモンスターであるところのGuy Decouxによるパッ
チ[ruby-core:16238]を1.8.7に取り込みたいんですが、これのチェッ
クを行う時間のある人はいますか?

私自身は1.8.7に間に合うように時間が取れる自信がありません。

 若干スタイルを修正しつつ、差分がわかりやすいようにするとこんな
感じです。BASE との差分よりも、適用後に PREV との差分を見た方が
いいかもしれません。

 BoundMethod, UnboundMethod の対応、 cref の伝達、 klass の修正、
でしょうかね。大丈夫そうですが、(ここで本家モンスターやRHG読書会
ãƒ¡ãƒ³ãƒãƒ¼ãŒç™»å ´)

Index: intern.h

— intern.h (revision 16192)
+++ intern.h (working copy)
@@ -193,6 +193,8 @@
void rb_obj_call_init _((VALUE, int, VALUE*));
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
VALUE rb_block_proc _((void));
+VALUE rb_block_dup _((VALUE, VALUE, VALUE));
+VALUE rb_method_dup _((VALUE, VALUE, VALUE));
VALUE rb_f_lambda _((void));
VALUE rb_proc_call _((VALUE, VALUE));
VALUE rb_obj_method _((VALUE, VALUE));
Index: eval.c

— eval.c (revision 16192)
+++ eval.c (working copy)
@@ -8414,6 +8414,19 @@
return bind;
}

+VALUE
+rb_block_dup(self, klass, cref)

  • VALUE self, klass, cref;
    +{
  • struct BLOCK *block;
  • VALUE obj = proc_dup(self);
  • Data_Get_Struct(obj, struct BLOCK, block);
  • block->klass = klass;
  • block->cref = NEW_NODE(nd_type(block->cref), cref,
    block->cref->u2.node,
  •     block->cref->u3.node);
    
  • return obj;
    +}

/*

  • call-seq:
  • binding -> a_binding
    

@@ -9340,6 +9353,29 @@
return clone;
}

+VALUE
+rb_method_dup(self, klass, cref)

  • VALUE self;
  • VALUE klass;
  • VALUE cref;
    +{
  • VALUE clone;
  • struct METHOD *orig, *data;
  • Data_Get_Struct(self, struct METHOD, orig);
  • clone = Data_Make_Struct(CLASS_OF(self),struct METHOD, bm_mark,
    free, data);
  • *data = *orig;
  • data->rklass = klass;
  • if (data->body->nd_rval) {
  • NODE *tmp = NEW_NODE(nd_type(data->body->u2.node), cref,
  •       data->body->u2.node->u2.node,
    
  •       data->body->u2.node->u3.node);
    
  • data->body = NEW_NODE(nd_type(data->body), data->body->u1.node, tmp,
  •        data->body->u3.node);
    
  • }
  • return clone;
    +}

/*

  • call-seq:
  • meth.call(args, ...)    => obj
    

Index: class.c

— class.c (revision 16192)
+++ class.c (working copy)
@@ -51,6 +51,7 @@
struct clone_method_data {
st_table *tbl;
VALUE klass;

  • VALUE cref;
    };

static int
@@ -61,16 +62,33 @@
{
NODE *fbody = body->nd_body;

  • if (fbody && nd_type(fbody) == NODE_SCOPE) {
  • VALUE cref = data->klass ?
  •  (VALUE)NEW_NODE(NODE_CREF,data->klass,0,fbody->nd_rval) :
    
  •  fbody->nd_rval;
    
  • fbody = NEW_NODE(NODE_SCOPE, fbody->nd_tbl, cref, fbody->nd_next);
  • if (fbody && data->cref) {
  • VALUE body;
  • switch (nd_type(fbody)) {
  • case NODE_SCOPE:
  •  if (fbody->nd_rval) {
    
  • NODE *tmp = NEW_NODE(nd_type(fbody->u2.node), data->cref,
  •         fbody->u2.node->u2.node, fbody->u2.node->u3.node);
    
  • fbody = NEW_NODE(nd_type(fbody), fbody->u1.node, tmp,
    fbody->u3.node);
  •  }
    
  •  break;
    
  • case NODE_BMETHOD:
  •  body = rb_block_dup(fbody->nd_cval, data->klass, data->cref);
    
  •  fbody = NEW_BMETHOD(body);
    
  •  break;
    
  • case NODE_DMETHOD:
  •  body = rb_method_dup(fbody->nd_cval, data->klass, data->cref);
    
  •  fbody = NEW_DMETHOD(body);
    
  •  break;
    
  • }
    }
    st_insert(data->tbl, mid, (st_data_t)NEW_METHOD(fbody,
    body->nd_noex));
    return ST_CONTINUE;
    }

+static VALUE singleton_class_clone_int _((VALUE, VALUE));
+
/* :nodoc: */
VALUE
rb_mod_init_copy(clone, orig)
@@ -78,8 +96,7 @@
{
rb_obj_init_copy(clone, orig);
if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {

  • RBASIC(clone)->klass = RBASIC(orig)->klass;
  • RBASIC(clone)->klass = rb_singleton_class_clone(clone);
  • RBASIC(clone)->klass = singleton_class_clone_int(orig, clone);
    }
    RCLASS(clone)->super = RCLASS(orig)->super;
    if (RCLASS(orig)->iv_tbl) {
    @@ -94,9 +111,10 @@
    if (RCLASS(orig)->m_tbl) {
    struct clone_method_data data;
  • data.tbl = RCLASS(clone)->m_tbl = st_init_numtable();
  • data.klass = (VALUE)clone;
  • RCLASS(clone)->m_tbl = st_init_numtable();
  • data.tbl = RCLASS(clone)->m_tbl;
  • data.klass = clone;
  • data.cref = clone;
    st_foreach(RCLASS(orig)->m_tbl, clone_method, (st_data_t)&data);
    }

@@ -117,15 +135,16 @@
return rb_mod_init_copy(clone, orig);
}

-VALUE
-rb_singleton_class_clone(obj)

  • VALUE obj;
    +static VALUE
    +singleton_class_clone_int(obj, cref)
  • VALUE obj, cref;
    {
    VALUE klass = RBASIC(obj)->klass;

    if (!FL_TEST(klass, FL_SINGLETON))
    return klass;
    else {

  • struct clone_method_data data;
    /* copy singleton(unnamed) class */
    NEWOBJ(clone, struct RClass);
    OBJSETUP(clone, 0, RBASIC(klass)->flags);
    @@ -143,28 +162,24 @@
    if (RCLASS(klass)->iv_tbl) {
    clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
    }

  • {
  •  struct clone_method_data data;
    
  •  data.tbl = clone->m_tbl = st_init_numtable();
    
  •  switch (TYPE(obj)) {
    
  •    case T_CLASS:
    
  •    case T_MODULE:
    
  • data.klass = obj;
  • break;
  •    default:
    
  • data.klass = 0;
  • break;
  •  }
    
  •  st_foreach(RCLASS(klass)->m_tbl, clone_method, (st_data_t)&data);
    
  • }
  • clone->m_tbl = st_init_numtable();
  • data.tbl = clone->m_tbl;
  • data.klass = (VALUE)clone;
  • data.cref = cref;
  • st_foreach(RCLASS(klass)->m_tbl, clone_method, (st_data_t)&data);
    rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
    FL_SET(clone, FL_SINGLETON);
    return (VALUE)clone;
    }
    }

+VALUE
+rb_singleton_class_clone(obj)

  • VALUE obj;
    +{
  • return singleton_class_clone_int(obj, 0);
    +}

void
rb_singleton_class_attached(klass, obj)
VALUE klass, obj;

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:34514] Re: [ruby-core:16238]e$B$N8!>Ze(B”
on Fri, 25 Apr 2008 22:11:27 +0900, “Akinori MUSHA”
[email protected] writes:

|> e$B;d<+?H$Oe(B1.8.7e$B$K4V$K9g$&$h$&$K;~4V$,<h$l$k<+?.$,$“$j$^$;$s!#e(B
|
|e$B!!<c43%9%?%$%k$r=$@5$7$D$D!”:9J,$,$o$+$j$d$9$$$h$&$K$9$k$H$3$s$Je(B
|e$B46$8$G$9!#e(BBASE e$B$H$N:9J,$h$j$b!"E,MQ8e$Ke(B PREV e$B$H$N:9J,$r8+$?J}$,e(B
|e$B$$$$$+$b$7$l$^$;$s!#e(B
|
|e$B!!e(BBoundMethod, UnboundMethod e$B$NBP1~!"e(B cref e$B$NEAC#!"e(B klass e$B$N=$@5!"e(B
|e$B$G$7$g$&$+$M!#Bg>fIW$=$&$G$9$,!"e(B(e$B$3$3$GK\2H%b%s%9%?!<$de(BRHGe$BFI=q2qe(B
|e$B%a%s%P!<$,EP>le(B)

e$B$A$g$C$H8+$F$_$^$7$?!#Bg>fIW$=$&$J$N$G<h$j9~$s$G$$$?$@$1$^$;e(B
e$B$s$G$7$g$&$+!#e(B