summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-12 05:55:06 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-12 05:55:06 +0000
commitde5d332b0a2c76ff48e552eeef99c384ac0f5a62 (patch)
tree62ac39f6330d9c77612cefa5931497c6d06e15a8
parentb8b3a82d903272ad6ff12770c25ed1799608eda4 (diff)
downloadruby-de5d332b0a2c76ff48e552eeef99c384ac0f5a62.tar.gz
ruby-de5d332b0a2c76ff48e552eeef99c384ac0f5a62.tar.xz
ruby-de5d332b0a2c76ff48e552eeef99c384ac0f5a62.zip
* insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h: check
definition of (classes)#=== for case/when optimization. Fix Bug #1376 [ruby-core:23190]. * string.c (Init_String), bignum.c (Init_Bignum), numeric.c (Init_Numeric): define String#===, Symbol#===, Bignum#===, Fixnum#===, Float#=== as same as (classes)#==. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@24511 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--bignum.c1
-rw-r--r--insns.def19
-rw-r--r--numeric.c2
-rw-r--r--string.c2
-rw-r--r--vm.c1
-rw-r--r--vm_insnhelper.c18
-rw-r--r--vm_insnhelper.h1
8 files changed, 50 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index a517a2808..34ccc15de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Wed Aug 12 Wed Aug 12 14:54:34 2009 Koichi Sasada <ko1@atdot.net>
+
+ * insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h: check
+ definition of (classes)#=== for case/when optimization.
+ Fix Bug #1376 [ruby-core:23190].
+
+ * string.c (Init_String), bignum.c (Init_Bignum),
+ numeric.c (Init_Numeric): define String#===, Symbol#===,
+ Bignum#===, Fixnum#===, Float#=== as same as (classes)#==.
+
Wed Aug 12 14:14:42 2009 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/win32.c (readdir_internal): free old temporary filename.
diff --git a/bignum.c b/bignum.c
index 00433cc40..f2104f042 100644
--- a/bignum.c
+++ b/bignum.c
@@ -3253,6 +3253,7 @@ Init_Bignum(void)
rb_define_method(rb_cBignum, "<=>", rb_big_cmp, 1);
rb_define_method(rb_cBignum, "==", rb_big_eq, 1);
+ rb_define_method(rb_cBignum, "===", rb_big_eq, 1);
rb_define_method(rb_cBignum, "eql?", rb_big_eql, 1);
rb_define_method(rb_cBignum, "hash", rb_big_hash, 0);
rb_define_method(rb_cBignum, "to_f", rb_big_to_f, 0);
diff --git a/insns.def b/insns.def
index 98f0dcd14..dfae799b3 100644
--- a/insns.def
+++ b/insns.def
@@ -1233,10 +1233,7 @@ opt_case_dispatch
(..., VALUE key)
() // inc += -1;
{
- if (0) {
- /* TODO: if some === method is overrided */
- }
- else {
+ if (BASIC_OP_UNREDEFINED_P(BOP_EQQ)) {
VALUE val;
if (st_lookup(RHASH_TBL(hash), key, &val)) {
JUMP(FIX2INT(val));
@@ -1245,6 +1242,20 @@ opt_case_dispatch
JUMP(else_offset);
}
}
+ else {
+ struct opt_case_dispatch_i_arg arg = {
+ key, -1
+ };
+
+ st_foreach(RHASH_TBL(hash), opt_case_dispatch_i, &arg);
+
+ if (arg.label != -1) {
+ JUMP(arg.label);
+ }
+ else {
+ JUMP(else_offset);
+ }
+ }
}
/**
diff --git a/numeric.c b/numeric.c
index 3c64fc81c..ecaf9c503 100644
--- a/numeric.c
+++ b/numeric.c
@@ -3222,6 +3222,7 @@ Init_Numeric(void)
rb_define_method(rb_cFixnum, "magnitude", fix_abs, 0);
rb_define_method(rb_cFixnum, "==", fix_equal, 1);
+ rb_define_method(rb_cFixnum, "===", fix_equal, 1);
rb_define_method(rb_cFixnum, "<=>", fix_cmp, 1);
rb_define_method(rb_cFixnum, ">", fix_gt, 1);
rb_define_method(rb_cFixnum, ">=", fix_ge, 1);
@@ -3275,6 +3276,7 @@ Init_Numeric(void)
rb_define_method(rb_cFloat, "divmod", flo_divmod, 1);
rb_define_method(rb_cFloat, "**", flo_pow, 1);
rb_define_method(rb_cFloat, "==", flo_eq, 1);
+ rb_define_method(rb_cFloat, "===", flo_eq, 1);
rb_define_method(rb_cFloat, "<=>", flo_cmp, 1);
rb_define_method(rb_cFloat, ">", flo_gt, 1);
rb_define_method(rb_cFloat, ">=", flo_ge, 1);
diff --git a/string.c b/string.c
index 39df54b19..7ac3bc6af 100644
--- a/string.c
+++ b/string.c
@@ -7418,6 +7418,7 @@ Init_String(void)
rb_define_method(rb_cString, "initialize_copy", rb_str_replace, 1);
rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1);
rb_define_method(rb_cString, "==", rb_str_equal, 1);
+ rb_define_method(rb_cString, "===", rb_str_equal, 1);
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
@@ -7547,6 +7548,7 @@ Init_String(void)
rb_define_singleton_method(rb_cSymbol, "all_symbols", rb_sym_all_symbols, 0); /* in parse.y */
rb_define_method(rb_cSymbol, "==", sym_equal, 1);
+ rb_define_method(rb_cSymbol, "===", sym_equal, 1);
rb_define_method(rb_cSymbol, "inspect", sym_inspect, 0);
rb_define_method(rb_cSymbol, "to_s", rb_sym_to_s, 0);
rb_define_method(rb_cSymbol, "id2name", rb_sym_to_s, 0);
diff --git a/vm.c b/vm.c
index 2a1a98198..c84c0c826 100644
--- a/vm.c
+++ b/vm.c
@@ -968,6 +968,7 @@ vm_init_redefined_flag(void)
OP(DIV, DIV), (C(Fixnum), C(Float));
OP(MOD, MOD), (C(Fixnum), C(Float));
OP(Eq, EQ), (C(Fixnum), C(Float), C(String));
+ OP(Eqq, EQQ), (C(Fixnum), C(Bignum), C(Float), C(Symbol), C(String));
OP(LT, LT), (C(Fixnum));
OP(LE, LE), (C(Fixnum));
OP(LTLT, LTLT), (C(String), C(Array));
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 3053fda1d..07aa24468 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1592,3 +1592,21 @@ opt_eq_func(VALUE recv, VALUE obj, IC ic)
return val;
}
+
+struct opt_case_dispatch_i_arg {
+ VALUE obj;
+ int label;
+};
+
+static int
+opt_case_dispatch_i(st_data_t key, st_data_t data, struct opt_case_dispatch_i_arg *arg)
+{
+ if (RTEST(rb_funcall((VALUE)key, idEqq, 1, arg->obj))) {
+ arg->label = FIX2INT((VALUE)data);
+ return ST_STOP;
+ }
+ else {
+ return ST_CONTINUE;
+ }
+}
+
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index a6d3f0469..d40f3de0a 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -41,6 +41,7 @@ enum {
BOP_DIV,
BOP_MOD,
BOP_EQ,
+ BOP_EQQ,
BOP_LT,
BOP_LE,
BOP_LTLT,