rb_method_entry_t *
rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_flag_t noex)
{
    rb_method_type_t type = me->def ? me->def->type : VM_METHOD_TYPE_UNDEF;
    rb_method_entry_t *newme = rb_method_entry_make(klass, mid, type, me->def, noex);
    method_added(klass, mid);
    return newme;
}
rb_method_entry_t *
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
{
    rb_thread_t *th;
    rb_control_frame_t *cfp;
    int line;
    rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, 0, noex);
    rb_method_definition_t *def = ALLOC(rb_method_definition_t);
    me->def = def;
    def->type = type;
    def->original_id = mid;
    def->alias_count = 0;
    switch (type) {
      case VM_METHOD_TYPE_ISEQ:
	def->body.iseq = (rb_iseq_t *)opts;
	break;
      case VM_METHOD_TYPE_CFUNC:
	def->body.cfunc = *(rb_method_cfunc_t *)opts;
	break;
      case VM_METHOD_TYPE_ATTRSET:
      case VM_METHOD_TYPE_IVAR:
	def->body.attr.id = (ID)opts;
	def->body.attr.location = Qfalse;
	th = GET_THREAD();
	cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
	if (cfp && (line = rb_vm_get_sourceline(cfp))) {
	    VALUE location = rb_ary_new3(2, cfp->iseq->filename, INT2FIX(line));
	    def->body.attr.location = rb_ary_freeze(location);
	}
	break;
      case VM_METHOD_TYPE_BMETHOD:
	def->body.proc = (VALUE)opts;
	break;
      case VM_METHOD_TYPE_NOTIMPLEMENTED:
	def->body.cfunc.func = rb_f_notimplement;
	def->body.cfunc.argc = -1;
	break;
      case VM_METHOD_TYPE_OPTIMIZED:
	def->body.optimize_type = (enum method_optimized_type)opts;
	break;
      case VM_METHOD_TYPE_ZSUPER:
      case VM_METHOD_TYPE_UNDEF:
	break;
      default:
	rb_bug("rb_add_method: unsupported method type (%d)\n", type);
    }
    if (type != VM_METHOD_TYPE_UNDEF) {
	method_added(klass, mid);
    }
    return me;
}
Example #3
0
rb_method_entry_t *
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
{
    rb_thread_t *th;
    rb_control_frame_t *cfp;
    int line;
    rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, 0, noex, klass);
    rb_method_definition_t *def = ALLOC(rb_method_definition_t);
    if (me->def && me->def->type == VM_METHOD_TYPE_REFINED) {
	me->def->body.orig_me->def = def;
    }
    else {
	me->def = def;
    }
    def->type = type;
    def->original_id = mid;
    def->alias_count = 0;
    switch (type) {
      case VM_METHOD_TYPE_ISEQ: {
	  rb_iseq_t *iseq = (rb_iseq_t *)opts;
	  *(rb_iseq_t **)&def->body.iseq = iseq;
	  RB_OBJ_WRITTEN(klass, Qundef, iseq->self);
	  break;
      }
      case VM_METHOD_TYPE_CFUNC:
	{
	    rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
	    setup_method_cfunc_struct(&def->body.cfunc, cfunc->func, cfunc->argc);
	}
	break;
      case VM_METHOD_TYPE_ATTRSET:
      case VM_METHOD_TYPE_IVAR:
	def->body.attr.id = (ID)(VALUE)opts;
	RB_OBJ_WRITE(klass, &def->body.attr.location, Qfalse);
	th = GET_THREAD();
	cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
	if (cfp && (line = rb_vm_get_sourceline(cfp))) {
	    VALUE location = rb_ary_new3(2, cfp->iseq->location.path, INT2FIX(line));
	    RB_OBJ_WRITE(klass, &def->body.attr.location, rb_ary_freeze(location));
	}
	break;
      case VM_METHOD_TYPE_BMETHOD:
	RB_OBJ_WRITE(klass, &def->body.proc, (VALUE)opts);
	break;
      case VM_METHOD_TYPE_NOTIMPLEMENTED:
	setup_method_cfunc_struct(&def->body.cfunc, rb_f_notimplement, -1);
	break;
      case VM_METHOD_TYPE_OPTIMIZED:
	def->body.optimize_type = (enum method_optimized_type)opts;
	break;
      case VM_METHOD_TYPE_ZSUPER:
      case VM_METHOD_TYPE_UNDEF:
	break;
      case VM_METHOD_TYPE_REFINED:
	def->body.orig_me = (rb_method_entry_t *) opts;
	break;
      default:
	rb_bug("rb_add_method: unsupported method type (%d)\n", type);
    }
    if (type != VM_METHOD_TYPE_UNDEF && type != VM_METHOD_TYPE_REFINED) {
	method_added(klass, mid);
    }
    return me;
}