static int clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data) { VALUE newiseqval; if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) { rb_iseq_t *iseq; newiseqval = rb_iseq_clone(me->def->body.iseq->self, data->klass); GetISeqPtr(newiseqval, iseq); rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); RB_GC_GUARD(newiseqval); } else { rb_method_entry_set(data->klass, mid, me, me->flag); } return ST_CONTINUE; }
static void clone_method(VALUE klass, ID mid, const rb_method_entry_t *me) { VALUE newiseqval; if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) { rb_iseq_t *iseq; newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass); GetISeqPtr(newiseqval, iseq); OBJ_WRITE(iseq->self, &iseq->cref_stack, rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass)); rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); RB_GC_GUARD(newiseqval); } else { rb_method_entry_set(klass, mid, me, me->flag); } }
static int clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data) { switch (me->type) { case VM_METHOD_TYPE_ISEQ: { VALUE newiseqval = rb_iseq_clone(me->body.iseq->self, data->klass); rb_iseq_t *iseq; GetISeqPtr(newiseqval, iseq); rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag); break; } default: rb_add_method_me(data->klass, mid, me, me->flag); break; } return ST_CONTINUE; }
static void vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, rb_num_t is_singleton, NODE *cref) { VALUE klass = cref->nd_clss; int noex = (int)cref->nd_visi; rb_iseq_t *miseq; GetISeqPtr(iseqval, miseq); if (miseq->klass) { iseqval = rb_iseq_clone(iseqval, 0); RB_GC_GUARD(iseqval); GetISeqPtr(iseqval, miseq); } if (NIL_P(klass)) { rb_raise(rb_eTypeError, "no class/module to add method"); } if (is_singleton) { if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton method \"%s\" for %s", rb_id2name(id), rb_obj_classname(obj)); } rb_check_frozen(obj); klass = rb_singleton_class(obj); noex = NOEX_PUBLIC; } /* dup */ COPY_CREF(miseq->cref_stack, cref); miseq->cref_stack->nd_visi = NOEX_PUBLIC; miseq->klass = klass; miseq->defined_method_id = id; rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, noex); if (!is_singleton && noex == NOEX_MODFUNC) { rb_add_method(rb_singleton_class(klass), id, VM_METHOD_TYPE_ISEQ, miseq, NOEX_PUBLIC); } INC_VM_STATE_VERSION(); }