summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-26 06:28:38 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-26 06:28:38 +0000
commit2881374caf647e0d982bead451d4c2a96e6f8516 (patch)
treec8ed7044ef9bd9c89e0c88529c04c74be5858cde /vm_insnhelper.c
parentad0f8ff76cb6c698e75dbde6011a9251d5efd13b (diff)
Symbol support for opt_eql_func too
* vm_insnhelper.c (comparable_by_identity): extract the condition where comparable by identity. currently both are same types, Fixnum, Flonum, or Symbol. * vm_insnhelper.c (opt_eql_func): support Symbol too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58896 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c97
1 files changed, 50 insertions, 47 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index f0832eac74..777ba840f4 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1295,9 +1295,43 @@ check_cfunc(const rb_callable_method_entry_t *me, VALUE (*func)())
}
}
+static inline int
+vm_method_cfunc_is(CALL_INFO ci, CALL_CACHE cc,
+ VALUE recv, VALUE (*func)())
+{
+ vm_search_method(ci, cc, recv);
+ return check_cfunc(cc->me, func);
+}
+
+static VALUE
+opt_equal_fallback(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc)
+{
+ if (vm_method_cfunc_is(ci, cc, recv, rb_obj_equal)) {
+ return recv == obj ? Qtrue : Qfalse;
+ }
+
+ return Qundef;
+}
+
#define BUILTIN_CLASS_P(x, k) (!SPECIAL_CONST_P(x) && RBASIC_CLASS(x) == k)
#define EQ_UNREDEFINED_P(t) BASIC_OP_UNREDEFINED_P(BOP_EQ, t##_REDEFINED_OP_FLAG)
+/* 1: compare by identity, 0: not applicable, -1: redefined */
+static inline int
+comparable_by_identity(VALUE recv, VALUE obj)
+{
+ if (FIXNUM_2_P(recv, obj)) {
+ return (EQ_UNREDEFINED_P(INTEGER) != 0) * 2 - 1;
+ }
+ if (FLONUM_2_P(recv, obj)) {
+ return (EQ_UNREDEFINED_P(FLOAT) != 0) * 2 - 1;
+ }
+ if (SYMBOL_P(recv) && SYMBOL_P(obj)) {
+ return (EQ_UNREDEFINED_P(SYMBOL) != 0) * 2 - 1;
+ }
+ return 0;
+}
+
static
#ifndef NO_BIG_INLINE
inline
@@ -1305,15 +1339,13 @@ inline
VALUE
opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc)
{
- if (FIXNUM_2_P(recv, obj)) {
- if (EQ_UNREDEFINED_P(INTEGER)) {
- return (recv == obj) ? Qtrue : Qfalse;
- }
+ switch (comparable_by_identity(recv, obj)) {
+ case 1:
+ return (recv == obj) ? Qtrue : Qfalse;
+ case -1:
+ goto fallback;
}
- else if (FLONUM_2_P(recv, obj)) {
- if (EQ_UNREDEFINED_P(FLOAT)) {
- return (recv == obj) ? Qtrue : Qfalse;
- }
+ if (0) {
}
else if (BUILTIN_CLASS_P(recv, rb_cFloat)) {
if (EQ_UNREDEFINED_P(FLOAT)) {
@@ -1325,21 +1357,9 @@ opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc)
return rb_str_equal(recv, obj);
}
}
- else if (SYMBOL_P(recv) && SYMBOL_P(obj)) {
- if (EQ_UNREDEFINED_P(SYMBOL)) {
- return (recv == obj) ? Qtrue : Qfalse;
- }
- }
-
- {
- vm_search_method(ci, cc, recv);
-
- if (check_cfunc(cc->me, rb_obj_equal)) {
- return recv == obj ? Qtrue : Qfalse;
- }
- }
- return Qundef;
+ fallback:
+ return opt_equal_fallback(recv, obj, ci, cc);
}
static
@@ -1349,15 +1369,13 @@ inline
VALUE
opt_eql_func(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc)
{
- if (FIXNUM_2_P(recv, obj)) {
- if (EQ_UNREDEFINED_P(INTEGER)) {
- return (recv == obj) ? Qtrue : Qfalse;
- }
+ switch (comparable_by_identity(recv, obj)) {
+ case 1:
+ return (recv == obj) ? Qtrue : Qfalse;
+ case -1:
+ goto fallback;
}
- else if (FLONUM_2_P(recv, obj)) {
- if (EQ_UNREDEFINED_P(FLOAT)) {
- return (recv == obj) ? Qtrue : Qfalse;
- }
+ if (0) {
}
else if (BUILTIN_CLASS_P(recv, rb_cFloat)) {
if (EQ_UNREDEFINED_P(FLOAT)) {
@@ -1370,15 +1388,8 @@ opt_eql_func(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc)
}
}
- {
- vm_search_method(ci, cc, recv);
-
- if (check_cfunc(cc->me, rb_obj_equal)) {
- return recv == obj ? Qtrue : Qfalse;
- }
- }
-
- return Qundef;
+ fallback:
+ return opt_equal_fallback(recv, obj, ci, cc);
}
#undef BUILTIN_CLASS_P
#undef EQ_UNREDEFINED_P
@@ -3465,14 +3476,6 @@ vm_opt_mod(VALUE recv, VALUE obj)
}
}
-static inline int
-vm_method_cfunc_is(CALL_INFO ci, CALL_CACHE cc,
- VALUE recv, VALUE (*func)())
-{
- vm_search_method(ci, cc, recv);
- return check_cfunc(cc->me, func);
-}
-
static VALUE
vm_opt_neq(CALL_INFO ci, CALL_CACHE cc,
CALL_INFO ci_eq, CALL_CACHE cc_eq,