save_attr_loc.patch
| method.h (working copy) | ||
|---|---|---|
| 49 | 49 |
int argc; |
| 50 | 50 |
} rb_method_cfunc_t; |
| 51 | 51 | |
| 52 |
typedef struct rb_method_attr_struct {
|
|
| 53 |
ID id; |
|
| 54 |
VALUE location; |
|
| 55 |
} rb_method_attr_t; |
|
| 56 | ||
| 52 | 57 |
typedef struct rb_iseq_struct rb_iseq_t; |
| 53 | 58 | |
| 54 | 59 |
typedef struct rb_method_definition_struct {
|
| ... | ... | |
| 57 | 62 |
union {
|
| 58 | 63 |
rb_iseq_t *iseq; /* should be mark */ |
| 59 | 64 |
rb_method_cfunc_t cfunc; |
| 60 |
ID attr_id;
|
|
| 65 |
rb_method_attr_t attr;
|
|
| 61 | 66 |
VALUE proc; /* should be mark */ |
| 62 | 67 |
enum method_optimized_type {
|
| 63 | 68 |
OPTIMIZED_METHOD_TYPE_SEND, |
| vm_eval.c (working copy) | ||
|---|---|---|
| 89 | 89 |
if (argc != 1) {
|
| 90 | 90 |
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); |
| 91 | 91 |
} |
| 92 |
val = rb_ivar_set(recv, def->body.attr_id, argv[0]);
|
|
| 92 |
val = rb_ivar_set(recv, def->body.attr.id, argv[0]);
|
|
| 93 | 93 |
break; |
| 94 | 94 |
} |
| 95 | 95 |
case VM_METHOD_TYPE_IVAR: {
|
| 96 | 96 |
if (argc != 0) {
|
| 97 | 97 |
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc); |
| 98 | 98 |
} |
| 99 |
val = rb_attr_get(recv, def->body.attr_id);
|
|
| 99 |
val = rb_attr_get(recv, def->body.attr.id);
|
|
| 100 | 100 |
break; |
| 101 | 101 |
} |
| 102 | 102 |
case VM_METHOD_TYPE_BMETHOD: {
|
| proc.c (working copy) | ||
|---|---|---|
| 1634 | 1634 |
return rb_mod_method_arity(CLASS_OF(obj), id); |
| 1635 | 1635 |
} |
| 1636 | 1636 | |
| 1637 |
rb_iseq_t *
|
|
| 1638 |
rb_method_get_iseq(VALUE method)
|
|
| 1637 |
static inline rb_method_definition_t *
|
|
| 1638 |
method_get_def(VALUE method)
|
|
| 1639 | 1639 |
{
|
| 1640 | 1640 |
struct METHOD *data; |
| 1641 |
rb_method_definition_t *def; |
|
| 1642 | 1641 | |
| 1643 | 1642 |
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); |
| 1644 |
def = data->me.def; |
|
| 1643 |
return data->me.def; |
|
| 1644 |
} |
|
| 1645 | 1645 | |
| 1646 |
static rb_iseq_t * |
|
| 1647 |
method_get_iseq(rb_method_definition_t *def) |
|
| 1648 |
{
|
|
| 1646 | 1649 |
switch (def->type) {
|
| 1647 | 1650 |
case VM_METHOD_TYPE_BMETHOD: |
| 1648 | 1651 |
return get_proc_iseq(def->body.proc, 0); |
| ... | ... | |
| 1653 | 1656 |
} |
| 1654 | 1657 |
} |
| 1655 | 1658 | |
| 1659 |
rb_iseq_t * |
|
| 1660 |
rb_method_get_iseq(VALUE method) |
|
| 1661 |
{
|
|
| 1662 |
return method_get_iseq(method_get_def(method)); |
|
| 1663 |
} |
|
| 1664 | ||
| 1656 | 1665 |
/* |
| 1657 | 1666 |
* call-seq: |
| 1658 | 1667 |
* meth.source_location => [String, Fixnum] |
| ... | ... | |
| 1664 | 1673 |
VALUE |
| 1665 | 1674 |
rb_method_location(VALUE method) |
| 1666 | 1675 |
{
|
| 1667 |
return iseq_location(rb_method_get_iseq(method)); |
|
| 1676 |
rb_method_definition_t *def = method_get_def(method); |
|
| 1677 |
if (def->type == VM_METHOD_TYPE_ATTRSET || def->type == VM_METHOD_TYPE_IVAR) {
|
|
| 1678 |
if (!def->body.attr.location) |
|
| 1679 |
return Qnil; |
|
| 1680 |
return rb_ary_dup(def->body.attr.location); |
|
| 1681 |
} |
|
| 1682 |
return iseq_location(method_get_iseq(def)); |
|
| 1668 | 1683 |
} |
| 1669 | 1684 | |
| 1670 | 1685 |
/* |
| vm_method.c (working copy) | ||
|---|---|---|
| 260 | 260 |
rb_method_entry_t * |
| 261 | 261 |
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex) |
| 262 | 262 |
{
|
| 263 |
rb_thread_t *th; |
|
| 264 |
rb_control_frame_t *cfp; |
|
| 265 |
int line; |
|
| 263 | 266 |
rb_method_entry_t *me = rb_add_method_def(klass, mid, type, 0, noex); |
| 264 | 267 |
rb_method_definition_t *def = ALLOC(rb_method_definition_t); |
| 265 | 268 |
me->def = def; |
| ... | ... | |
| 275 | 278 |
break; |
| 276 | 279 |
case VM_METHOD_TYPE_ATTRSET: |
| 277 | 280 |
case VM_METHOD_TYPE_IVAR: |
| 278 |
def->body.attr_id = (ID)opts; |
|
| 281 |
def->body.attr.id = (ID)opts; |
|
| 282 |
th = GET_THREAD(); |
|
| 283 |
cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); |
|
| 284 |
if (cfp && (line = rb_vm_get_sourceline(cfp))) {
|
|
| 285 |
VALUE location = rb_ary_new3(2, cfp->iseq->filename, INT2FIX(line)); |
|
| 286 |
def->body.attr.location = rb_ary_freeze(location); |
|
| 287 |
} else {
|
|
| 288 |
def->body.attr.location = Qfalse; |
|
| 289 |
} |
|
| 279 | 290 |
break; |
| 280 | 291 |
case VM_METHOD_TYPE_BMETHOD: |
| 281 | 292 |
def->body.proc = (VALUE)opts; |
| ... | ... | |
| 838 | 849 |
d1->body.cfunc.argc == d2->body.cfunc.argc; |
| 839 | 850 |
case VM_METHOD_TYPE_ATTRSET: |
| 840 | 851 |
case VM_METHOD_TYPE_IVAR: |
| 841 |
return d1->body.attr_id == d2->body.attr_id;
|
|
| 852 |
return d1->body.attr.id == d2->body.attr.id;
|
|
| 842 | 853 |
case VM_METHOD_TYPE_BMETHOD: |
| 843 | 854 |
return RTEST(rb_equal(d1->body.proc, d2->body.proc)); |
| 844 | 855 |
case VM_METHOD_TYPE_MISSING: |
| gc.c (working copy) | ||
|---|---|---|
| 1423 | 1423 |
case VM_METHOD_TYPE_BMETHOD: |
| 1424 | 1424 |
gc_mark(objspace, def->body.proc, lev); |
| 1425 | 1425 |
break; |
| 1426 |
case VM_METHOD_TYPE_ATTRSET: |
|
| 1427 |
case VM_METHOD_TYPE_IVAR: |
|
| 1428 |
gc_mark(objspace, def->body.attr.location, lev); |
|
| 1429 |
break; |
|
| 1426 | 1430 |
default: |
| 1427 | 1431 |
break; /* ignore */ |
| 1428 | 1432 |
} |
| vm_insnhelper.c (working copy) | ||
|---|---|---|
| 505 | 505 |
if (num != 1) {
|
| 506 | 506 |
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", num); |
| 507 | 507 |
} |
| 508 |
val = rb_ivar_set(recv, me->def->body.attr_id, *(cfp->sp - 1));
|
|
| 508 |
val = rb_ivar_set(recv, me->def->body.attr.id, *(cfp->sp - 1));
|
|
| 509 | 509 |
cfp->sp -= 2; |
| 510 | 510 |
break; |
| 511 | 511 |
} |
| ... | ... | |
| 513 | 513 |
if (num != 0) {
|
| 514 | 514 |
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", num); |
| 515 | 515 |
} |
| 516 |
val = rb_attr_get(recv, me->def->body.attr_id);
|
|
| 516 |
val = rb_attr_get(recv, me->def->body.attr.id);
|
|
| 517 | 517 |
cfp->sp -= 1; |
| 518 | 518 |
break; |
| 519 | 519 |
} |