Feature #2084 ยป save_attr_loc.patch
| method.h (working copy) | ||
|---|---|---|
|
int argc;
|
||
|
} rb_method_cfunc_t;
|
||
|
typedef struct rb_method_attr_struct {
|
||
|
ID id;
|
||
|
VALUE location;
|
||
|
} rb_method_attr_t;
|
||
|
typedef struct rb_iseq_struct rb_iseq_t;
|
||
|
typedef struct rb_method_definition_struct {
|
||
| ... | ... | |
|
union {
|
||
|
rb_iseq_t *iseq; /* should be mark */
|
||
|
rb_method_cfunc_t cfunc;
|
||
|
ID attr_id;
|
||
|
rb_method_attr_t attr;
|
||
|
VALUE proc; /* should be mark */
|
||
|
enum method_optimized_type {
|
||
|
OPTIMIZED_METHOD_TYPE_SEND,
|
||
| vm_eval.c (working copy) | ||
|---|---|---|
|
if (argc != 1) {
|
||
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
|
||
|
}
|
||
|
val = rb_ivar_set(recv, def->body.attr_id, argv[0]);
|
||
|
val = rb_ivar_set(recv, def->body.attr.id, argv[0]);
|
||
|
break;
|
||
|
}
|
||
|
case VM_METHOD_TYPE_IVAR: {
|
||
|
if (argc != 0) {
|
||
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
|
||
|
}
|
||
|
val = rb_attr_get(recv, def->body.attr_id);
|
||
|
val = rb_attr_get(recv, def->body.attr.id);
|
||
|
break;
|
||
|
}
|
||
|
case VM_METHOD_TYPE_BMETHOD: {
|
||
| proc.c (working copy) | ||
|---|---|---|
|
return rb_mod_method_arity(CLASS_OF(obj), id);
|
||
|
}
|
||
|
rb_iseq_t *
|
||
|
rb_method_get_iseq(VALUE method)
|
||
|
static inline rb_method_definition_t *
|
||
|
method_get_def(VALUE method)
|
||
|
{
|
||
|
struct METHOD *data;
|
||
|
rb_method_definition_t *def;
|
||
|
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
|
||
|
def = data->me.def;
|
||
|
return data->me.def;
|
||
|
}
|
||
|
static rb_iseq_t *
|
||
|
method_get_iseq(rb_method_definition_t *def)
|
||
|
{
|
||
|
switch (def->type) {
|
||
|
case VM_METHOD_TYPE_BMETHOD:
|
||
|
return get_proc_iseq(def->body.proc, 0);
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
rb_iseq_t *
|
||
|
rb_method_get_iseq(VALUE method)
|
||
|
{
|
||
|
return method_get_iseq(method_get_def(method));
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
|
* meth.source_location => [String, Fixnum]
|
||
| ... | ... | |
|
VALUE
|
||
|
rb_method_location(VALUE method)
|
||
|
{
|
||
|
return iseq_location(rb_method_get_iseq(method));
|
||
|
rb_method_definition_t *def = method_get_def(method);
|
||
|
if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
|
||
|
if (!def->body.attr.location)
|
||
|
return Qnil;
|
||
|
return rb_ary_dup(def->body.attr.location);
|
||
|
}
|
||
|
return iseq_location(method_get_iseq(def));
|
||
|
}
|
||
|
/*
|
||
| vm_method.c (working copy) | ||
|---|---|---|
|
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_add_method_def(klass, mid, type, 0, noex);
|
||
|
rb_method_definition_t *def = ALLOC(rb_method_definition_t);
|
||
|
me->def = def;
|
||
| ... | ... | |
|
break;
|
||
|
case VM_METHOD_TYPE_ATTRSET:
|
||
|
case VM_METHOD_TYPE_IVAR:
|
||
|
def->body.attr_id = (ID)opts;
|
||
|
def->body.attr.id = (ID)opts;
|
||
|
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);
|
||
|
} else {
|
||
|
def->body.attr.location = Qfalse;
|
||
|
}
|
||
|
break;
|
||
|
case VM_METHOD_TYPE_BMETHOD:
|
||
|
def->body.proc = (VALUE)opts;
|
||
| ... | ... | |
|
d1->body.cfunc.argc == d2->body.cfunc.argc;
|
||
|
case VM_METHOD_TYPE_ATTRSET:
|
||
|
case VM_METHOD_TYPE_IVAR:
|
||
|
return d1->body.attr_id == d2->body.attr_id;
|
||
|
return d1->body.attr.id == d2->body.attr.id;
|
||
|
case VM_METHOD_TYPE_BMETHOD:
|
||
|
return RTEST(rb_equal(d1->body.proc, d2->body.proc));
|
||
|
case VM_METHOD_TYPE_MISSING:
|
||
| gc.c (working copy) | ||
|---|---|---|
|
case VM_METHOD_TYPE_BMETHOD:
|
||
|
gc_mark(objspace, def->body.proc, lev);
|
||
|
break;
|
||
|
case VM_METHOD_TYPE_ATTRSET:
|
||
|
case VM_METHOD_TYPE_IVAR:
|
||
|
gc_mark(objspace, def->body.attr.location, lev);
|
||
|
break;
|
||
|
default:
|
||
|
break; /* ignore */
|
||
|
}
|
||
| vm_insnhelper.c (working copy) | ||
|---|---|---|
|
if (num != 1) {
|
||
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", num);
|
||
|
}
|
||
|
val = rb_ivar_set(recv, me->def->body.attr_id, *(cfp->sp - 1));
|
||
|
val = rb_ivar_set(recv, me->def->body.attr.id, *(cfp->sp - 1));
|
||
|
cfp->sp -= 2;
|
||
|
break;
|
||
|
}
|
||
| ... | ... | |
|
if (num != 0) {
|
||
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", num);
|
||
|
}
|
||
|
val = rb_attr_get(recv, me->def->body.attr_id);
|
||
|
val = rb_attr_get(recv, me->def->body.attr.id);
|
||
|
cfp->sp -= 1;
|
||
|
break;
|
||
|
}
|
||