aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--internal.h1
-rw-r--r--object.c10
-rw-r--r--vm_insnhelper.c13
3 files changed, 23 insertions, 1 deletions
diff --git a/internal.h b/internal.h
index 6380adaacb..4c26bd2c13 100644
--- a/internal.h
+++ b/internal.h
@@ -1739,6 +1739,7 @@ VALUE rb_yield_lambda(VALUE values);
/* vm_insnhelper.c */
VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
+VALUE rb_eql_opt(VALUE obj1, VALUE obj2);
/* vm_method.c */
void Init_eval_method(void);
diff --git a/object.c b/object.c
index a23cd19cda..270a0a838b 100644
--- a/object.c
+++ b/object.c
@@ -99,7 +99,15 @@ rb_equal(VALUE obj1, VALUE obj2)
int
rb_eql(VALUE obj1, VALUE obj2)
{
- return RTEST(rb_funcall(obj1, id_eql, 1, obj2));
+ VALUE result;
+
+ if (obj1 == obj2) return Qtrue;
+ result = rb_eql_opt(obj1, obj2);
+ if (result == Qundef) {
+ result = rb_funcall(obj1, id_eql, 1, obj2);
+ }
+ if (RTEST(result)) return Qtrue;
+ return Qfalse;
}
/*
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 05aeefaa7d..a23983a5e0 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1351,6 +1351,19 @@ rb_equal_opt(VALUE obj1, VALUE obj2)
return opt_eq_func(obj1, obj2, &ci, &cc);
}
+VALUE
+rb_eql_opt(VALUE obj1, VALUE obj2)
+{
+ struct rb_call_info ci;
+ struct rb_call_cache cc;
+
+ ci.mid = idEqlP;
+ cc.method_state = 0;
+ cc.class_serial = 0;
+ cc.me = NULL;
+ return opt_eq_func(obj1, obj2, &ci, &cc);
+}
+
static VALUE vm_call0(rb_thread_t*, VALUE, ID, int, const VALUE*, const rb_callable_method_entry_t *);
static VALUE