зеркало из https://github.com/github/ruby.git
__callee__ fix
* eval.c (rb_frame_callee, rb_f_callee_name): fix to return the called id. * vm_insnhelper.c (vm_push_frame): set proper method entry. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36301 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
07132e0675
Коммит
a7e1820a9f
|
@ -1,3 +1,10 @@
|
|||
Wed Jul 4 11:11:28 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* eval.c (rb_frame_callee, rb_f_callee_name): fix to return the called
|
||||
id.
|
||||
|
||||
* vm_insnhelper.c (vm_push_frame): set proper method entry.
|
||||
|
||||
Wed Jul 4 08:29:31 2012 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* array.c (rb_ary_aref): Updated documentation to indicate the
|
||||
|
|
72
eval.c
72
eval.c
|
@ -874,27 +874,66 @@ frame_func_id(rb_control_frame_t *cfp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ID
|
||||
frame_called_id(rb_control_frame_t *cfp)
|
||||
{
|
||||
const rb_method_entry_t *me_local;
|
||||
rb_iseq_t *iseq = cfp->iseq;
|
||||
if (cfp->me) {
|
||||
return cfp->me->called_id;
|
||||
}
|
||||
while (iseq) {
|
||||
if (RUBY_VM_IFUNC_P(iseq)) {
|
||||
NODE *ifunc = (NODE *)iseq;
|
||||
if (ifunc->nd_aid) return ifunc->nd_aid;
|
||||
return rb_intern("<ifunc>");
|
||||
}
|
||||
me_local = method_entry_of_iseq(cfp, iseq);
|
||||
if (me_local) {
|
||||
cfp->me = me_local;
|
||||
return me_local->called_id;
|
||||
}
|
||||
if (iseq->defined_method_id) {
|
||||
return iseq->defined_method_id;
|
||||
}
|
||||
if (iseq->local_iseq == iseq) {
|
||||
break;
|
||||
}
|
||||
iseq = iseq->parent_iseq;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ID
|
||||
rb_frame_this_func(void)
|
||||
{
|
||||
return frame_func_id(GET_THREAD()->cfp);
|
||||
}
|
||||
|
||||
ID
|
||||
rb_frame_callee(void)
|
||||
static rb_control_frame_t *
|
||||
previous_frame(rb_thread_t *th)
|
||||
{
|
||||
return frame_func_id(GET_THREAD()->cfp);
|
||||
}
|
||||
|
||||
static ID
|
||||
rb_frame_caller(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
|
||||
/* check if prev_cfp can be accessible */
|
||||
if ((void *)(th->stack + th->stack_size) == (void *)(prev_cfp)) {
|
||||
return 0;
|
||||
}
|
||||
return prev_cfp;
|
||||
}
|
||||
|
||||
ID
|
||||
rb_frame_callee(void)
|
||||
{
|
||||
rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
|
||||
if (!prev_cfp) return 0;
|
||||
return frame_called_id(prev_cfp);
|
||||
}
|
||||
|
||||
static ID
|
||||
rb_frame_caller(void)
|
||||
{
|
||||
rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
|
||||
if (!prev_cfp) return 0;
|
||||
return frame_func_id(prev_cfp);
|
||||
}
|
||||
|
||||
|
@ -1248,6 +1287,19 @@ rb_f_method_name(void)
|
|||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_f_callee_name(void)
|
||||
{
|
||||
ID fname = rb_frame_callee(); /* need *callee* ID */
|
||||
|
||||
if (fname) {
|
||||
return ID2SYM(fname);
|
||||
}
|
||||
else {
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Init_eval(void)
|
||||
{
|
||||
|
@ -1260,7 +1312,7 @@ Init_eval(void)
|
|||
rb_define_global_function("global_variables", rb_f_global_variables, 0); /* in variable.c */
|
||||
|
||||
rb_define_global_function("__method__", rb_f_method_name, 0);
|
||||
rb_define_global_function("__callee__", rb_f_method_name, 0);
|
||||
rb_define_global_function("__callee__", rb_f_callee_name, 0);
|
||||
|
||||
rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
|
||||
rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
|
||||
|
|
|
@ -974,7 +974,7 @@ defineclass
|
|||
vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS,
|
||||
klass, VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
|
||||
class_iseq->iseq_encoded, GET_SP(),
|
||||
class_iseq->local_size);
|
||||
class_iseq->local_size, 0);
|
||||
RESTORE_REGS();
|
||||
|
||||
INC_VM_STATE_VERSION();
|
||||
|
|
|
@ -90,6 +90,20 @@ class TestMethod < Test::Unit::TestCase
|
|||
assert_equal(:m, Class.new {define_method(:m) {__method__}}.new.m)
|
||||
assert_equal(:m, Class.new {define_method(:m) {tap{return __method__}}}.new.m)
|
||||
assert_nil(eval("class TestCallee; __method__; end"))
|
||||
|
||||
assert_equal(:test_callee, __callee__)
|
||||
[
|
||||
["method", Class.new {def m; __callee__; end},],
|
||||
["block", Class.new {def m; tap{return __callee__}; end},],
|
||||
["define_method", Class.new {define_method(:m) {__callee__}}],
|
||||
["define_method block", Class.new {define_method(:m) {tap{return __callee__}}}],
|
||||
].each do |mesg, c|
|
||||
c.class_eval {alias m2 m}
|
||||
o = c.new
|
||||
assert_equal(:m, o.m, mesg)
|
||||
assert_equal(:m2, o.m2, mesg)
|
||||
end
|
||||
assert_nil(eval("class TestCallee; __callee__; end"))
|
||||
end
|
||||
|
||||
def test_method_in_define_method_block
|
||||
|
|
15
vm.c
15
vm.c
|
@ -137,7 +137,7 @@ vm_set_top_stack(rb_thread_t * th, VALUE iseqval)
|
|||
CHECK_STACK_OVERFLOW(th->cfp, iseq->local_size + iseq->stack_max);
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
|
||||
th->top_self, VM_ENVVAL_BLOCK_PTR(0), iseq->iseq_encoded,
|
||||
th->cfp->sp, iseq->local_size);
|
||||
th->cfp->sp, iseq->local_size, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -149,7 +149,7 @@ vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref, rb_block_t
|
|||
CHECK_STACK_OVERFLOW(th->cfp, iseq->local_size + iseq->stack_max);
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL | VM_FRAME_FLAG_FINISH, base_block->self,
|
||||
VM_ENVVAL_PREV_EP_PTR(base_block->ep), iseq->iseq_encoded,
|
||||
th->cfp->sp, iseq->local_size);
|
||||
th->cfp->sp, iseq->local_size, 0);
|
||||
|
||||
if (cref) {
|
||||
th->cfp->ep[-1] = (VALUE)cref;
|
||||
|
@ -598,8 +598,8 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
|
|||
|
||||
ncfp = vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH,
|
||||
self, VM_ENVVAL_PREV_EP_PTR(block->ep),
|
||||
iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, iseq->local_size - arg_size);
|
||||
ncfp->me = th->passed_me;
|
||||
iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, iseq->local_size - arg_size,
|
||||
th->passed_me);
|
||||
th->passed_me = 0;
|
||||
th->passed_block = blockptr;
|
||||
|
||||
|
@ -1304,7 +1304,8 @@ vm_exec(rb_thread_t *th)
|
|||
cfp->sp[0] = err;
|
||||
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_BLOCK,
|
||||
cfp->self, VM_ENVVAL_PREV_EP_PTR(cfp->ep), catch_iseq->iseq_encoded,
|
||||
cfp->sp + 1 /* push value */, catch_iseq->local_size - 1);
|
||||
cfp->sp + 1 /* push value */, catch_iseq->local_size - 1,
|
||||
cfp->me);
|
||||
|
||||
state = 0;
|
||||
th->state = 0;
|
||||
|
@ -1438,7 +1439,7 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
|
|||
VALUE val;
|
||||
|
||||
vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
|
||||
recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1);
|
||||
recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1, 0);
|
||||
|
||||
val = (*func)(arg);
|
||||
|
||||
|
@ -1782,7 +1783,7 @@ th_init(rb_thread_t *th, VALUE self)
|
|||
th->cfp = (void *)(th->stack + th->stack_size);
|
||||
|
||||
vm_push_frame(th, 0 /* dummy iseq */, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
|
||||
Qnil /* dummy self */, VM_ENVVAL_BLOCK_PTR(0), 0 /* dummy pc */, th->stack, 1);
|
||||
Qnil /* dummy self */, VM_ENVVAL_BLOCK_PTR(0), 0 /* dummy pc */, th->stack, 1, 0);
|
||||
|
||||
th->status = THREAD_RUNNABLE;
|
||||
th->errinfo = Qnil;
|
||||
|
|
|
@ -71,7 +71,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
|
|||
rb_control_frame_t *reg_cfp = th->cfp;
|
||||
rb_control_frame_t *cfp =
|
||||
vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
|
||||
recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1);
|
||||
recv, VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1, me);
|
||||
|
||||
cfp->me = me;
|
||||
val = call_cfunc(def->body.cfunc.func, recv, def->body.cfunc.argc, argc, argv);
|
||||
|
|
|
@ -30,7 +30,8 @@ vm_push_frame(rb_thread_t *th,
|
|||
VALUE specval,
|
||||
const VALUE *pc,
|
||||
VALUE *sp,
|
||||
int local_size)
|
||||
int local_size,
|
||||
const rb_method_entry_t *me)
|
||||
{
|
||||
rb_control_frame_t *const cfp = th->cfp - 1;
|
||||
int i;
|
||||
|
@ -62,7 +63,7 @@ vm_push_frame(rb_thread_t *th,
|
|||
cfp->self = self;
|
||||
cfp->block_iseq = 0;
|
||||
cfp->proc = 0;
|
||||
cfp->me = 0;
|
||||
cfp->me = me;
|
||||
|
||||
if (VMDEBUG == 2) {
|
||||
SDR();
|
||||
|
@ -423,9 +424,8 @@ vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
|
|||
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->klass);
|
||||
|
||||
cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv,
|
||||
VM_ENVVAL_BLOCK_PTR(blockptr), 0, th->cfp->sp, 1);
|
||||
VM_ENVVAL_BLOCK_PTR(blockptr), 0, th->cfp->sp, 1, me);
|
||||
|
||||
cfp->me = me;
|
||||
reg_cfp->sp -= num + 1;
|
||||
|
||||
val = call_cfunc(def->body.cfunc.func, recv, (int)def->body.cfunc.argc, num, reg_cfp->sp + 1);
|
||||
|
@ -508,7 +508,7 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp,
|
|||
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv,
|
||||
VM_ENVVAL_BLOCK_PTR(blockptr),
|
||||
iseq->iseq_encoded + opt_pc, sp, 0);
|
||||
iseq->iseq_encoded + opt_pc, sp, 0, me);
|
||||
|
||||
cfp->sp = rsp - 1 /* recv */;
|
||||
}
|
||||
|
@ -531,7 +531,7 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp,
|
|||
|
||||
vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, recv,
|
||||
VM_ENVVAL_BLOCK_PTR(blockptr),
|
||||
iseq->iseq_encoded + opt_pc, sp, 0);
|
||||
iseq->iseq_encoded + opt_pc, sp, 0, me);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -760,7 +760,7 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
|
|||
}
|
||||
|
||||
cfp = vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
|
||||
VM_ENVVAL_PREV_EP_PTR(block->ep), 0, th->cfp->sp, 1);
|
||||
VM_ENVVAL_PREV_EP_PTR(block->ep), 0, th->cfp->sp, 1, 0);
|
||||
|
||||
if (blockargptr) {
|
||||
VM_CF_LEP(cfp)[0] = VM_ENVVAL_BLOCK_PTR(blockargptr);
|
||||
|
@ -980,7 +980,7 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n
|
|||
VM_ENVVAL_PREV_EP_PTR(block->ep),
|
||||
iseq->iseq_encoded + opt_pc,
|
||||
rsp + arg_size,
|
||||
iseq->local_size - arg_size);
|
||||
iseq->local_size - arg_size, 0);
|
||||
|
||||
return Qundef;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче