summaryrefslogtreecommitdiff
path: root/vm_eval.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-15 01:29:34 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-15 01:29:34 +0000
commitafcd5562ae7a61479b128845360151adc3c5397c (patch)
treeae5bf8a5c2f23ec3227b4698bf89b6762b0e4a38 /vm_eval.c
parent50a470b853dfc9dd72f80cbffbbe6fa5079d9970 (diff)
merge revision(s) r32855,r32857,r33493,r34554:
* vm_eval.c (check_funcall): try respond_to? first if redefined. [Bug #5158] * test/ruby/test_object.rb: tests that respond_to? returns false. * vm_eval.c (check_funcall): set array elements one-by-one to fix compile error with Fujitsu C Compiler 5.6 on Solaris 10 on Sparc. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@34615 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_eval.c')
-rw-r--r--vm_eval.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/vm_eval.c b/vm_eval.c
index a7e15918b5..cfa75a46b3 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -204,7 +204,7 @@ stack_check(void)
}
static inline rb_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
-static inline int rb_method_call_status(rb_thread_t *th, rb_method_entry_t *me, call_type scope, VALUE self);
+static inline int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self);
#define NOEX_OK NOEX_NOSUPER
/*!
@@ -266,12 +266,26 @@ check_funcall_failed(struct rescue_funcall_args *args, VALUE e)
static VALUE
check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
{
- rb_method_entry_t *me = rb_search_method_entry(recv, mid);
+ VALUE klass = CLASS_OF(recv);
+ const rb_method_entry_t *me;
rb_thread_t *th = GET_THREAD();
- int call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef);
+ int call_status;
+
+ me = rb_method_entry(klass, idRespond_to);
+ if (me && !(me->flag & NOEX_BASIC)) {
+ VALUE args[2];
+
+ args[0] = ID2SYM(mid);
+ args[1] = Qtrue;
+ if (!RTEST(vm_call0(th, recv, idRespond_to, 2, args, me))) {
+ return Qundef;
+ }
+ }
+ me = rb_search_method_entry(recv, mid);
+ call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef);
if (call_status != NOEX_OK) {
- if (rb_method_basic_definition_p(CLASS_OF(recv), idMethodMissing)) {
+ if (rb_method_basic_definition_p(klass, idMethodMissing)) {
return Qundef;
}
else {
@@ -376,7 +390,7 @@ rb_search_method_entry(VALUE recv, ID mid)
}
static inline int
-rb_method_call_status(rb_thread_t *th, rb_method_entry_t *me, call_type scope, VALUE self)
+rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self)
{
VALUE klass;
ID oid;