aboutsummaryrefslogtreecommitdiffstats
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-02 19:49:22 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-06-02 19:49:22 +0000
commit91ee3c580532bf23dd0264a75417e4031fbda5cf (patch)
tree6edb86d4e77240bdcf025647ea7bb49eaf7dfb1d /vm_insnhelper.c
parent12bba62a82d246d9416aed17e40f57b6c1dd7d16 (diff)
downloadruby-91ee3c580532bf23dd0264a75417e4031fbda5cf.tar.gz
* vm_insnhelper.c (vm_defined): check respond_to_missing?
at defined?(func()). * test/ruby/test_defined.rb: add a test for this fix. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50738 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 619de32dce..eba27f42cc 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -2409,6 +2409,22 @@ FUNC_FASTCALL(rb_vm_opt_struct_aset)(rb_thread_t *th, rb_control_frame_t *reg_cf
/* defined insn */
+static enum defined_type
+check_resopnd_to_missing(VALUE obj, VALUE v)
+{
+ VALUE args[2];
+ VALUE r;
+
+ args[0] = obj; args[1] = Qfalse;
+ r = rb_check_funcall(v, idRespond_to_missing, 2, args);
+ if (r != Qundef && RTEST(r)) {
+ return DEFINED_METHOD;
+ }
+ else {
+ return 0;
+ }
+}
+
static VALUE
vm_defined(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE obj, VALUE needstr, VALUE v)
{
@@ -2449,6 +2465,9 @@ vm_defined(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE
if (rb_method_boundp(klass, SYM2ID(obj), 0)) {
expr_type = DEFINED_METHOD;
}
+ else {
+ expr_type = check_resopnd_to_missing(obj, v);
+ }
break;
case DEFINED_METHOD:{
VALUE klass = CLASS_OF(v);
@@ -2462,13 +2481,7 @@ vm_defined(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE
}
}
else {
- VALUE args[2];
- VALUE r;
-
- args[0] = obj; args[1] = Qfalse;
- r = rb_check_funcall(v, idRespond_to_missing, 2, args);
- if (r != Qundef && RTEST(r))
- expr_type = DEFINED_METHOD;
+ expr_type = check_resopnd_to_missing(obj, v);
}
break;
}