summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--insns.def6
-rw-r--r--test/ruby/test_regexp.rb12
-rw-r--r--vm.c4
-rw-r--r--vm_insnhelper.h4
5 files changed, 41 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 6a38aa954a..6e9917c0d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Thu Sep 26 16:24:00 2013 Charlie Somerville <charliesome@ruby-lang.org>
+
+ * insns.def (opt_regexpmatch1): check Regexp#=~ is not defined before
+ calling rb_reg_match()
+
+ * test/ruby/test_regexp.rb: add test
+
+ * vm.c (ruby_vm_redefined_flag): change type to short[]
+
+ * vm.c (vm_redefinition_check_flag): return REGEXP_REDEFINED_OP_FLAG if
+ klass == rb_cRegexp
+
+ * vm.c (vm_init_redefined_flag): setup BOP flag for Regexp#=~
+
+ * vm_insnhelper.h: add REGEXP_REDEFINED_OP_FLAG
+
+ [ruby-core:57385] [Bug #8953]
+
Thu Sep 26 14:46:49 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* gc.c (mark_locations_array): disable AddressSanitizer. based on a
diff --git a/insns.def b/insns.def
index 53e22223cd..a73501f245 100644
--- a/insns.def
+++ b/insns.def
@@ -2080,7 +2080,11 @@ opt_regexpmatch1
(VALUE obj)
(VALUE val)
{
- val = rb_reg_match(r, obj);
+ if (BASIC_OP_UNREDEFINED_P(BOP_MATCH, REGEXP_REDEFINED_OP_FLAG)) {
+ val = rb_reg_match(r, obj);
+ } else {
+ val = rb_funcall(r, idEqTilde, 1, obj);
+ }
}
/**
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index 7937fe8867..b8c08e38ca 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -1011,6 +1011,18 @@ class TestRegexp < Test::Unit::TestCase
assert_equal(1, pr4.call(1))
end
+ def test_eq_tilde_can_be_overridden
+ assert_in_out_err([], <<-RUBY, ["foo"], [])
+ class Regexp
+ def =~(str)
+ "foo"
+ end
+ end
+
+ puts // =~ ""
+ RUBY
+ end
+
# This assertion is for porting x2() tests in testpy.py of Onigmo.
def assert_match_at(re, str, positions, msg = nil)
re = Regexp.new(re) unless re.is_a?(Regexp)
diff --git a/vm.c b/vm.c
index 3c50daa2fe..d647ab4a2a 100644
--- a/vm.c
+++ b/vm.c
@@ -99,7 +99,7 @@ VALUE rb_cEnv;
VALUE rb_mRubyVMFrozenCore;
VALUE ruby_vm_const_missing_count = 0;
-char ruby_vm_redefined_flag[BOP_LAST_];
+short ruby_vm_redefined_flag[BOP_LAST_];
rb_thread_t *ruby_current_thread = 0;
rb_vm_t *ruby_current_vm = 0;
rb_event_flag_t ruby_vm_event_flags;
@@ -1016,6 +1016,7 @@ vm_redefinition_check_flag(VALUE klass)
if (klass == rb_cBignum) return BIGNUM_REDEFINED_OP_FLAG;
if (klass == rb_cSymbol) return SYMBOL_REDEFINED_OP_FLAG;
if (klass == rb_cTime) return TIME_REDEFINED_OP_FLAG;
+ if (klass == rb_cRegexp) return REGEXP_REDEFINED_OP_FLAG;
return 0;
}
@@ -1094,6 +1095,7 @@ vm_init_redefined_flag(void)
OP(Size, SIZE), (C(Array), C(String), C(Hash));
OP(EmptyP, EMPTY_P), (C(Array), C(String), C(Hash));
OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
+ OP(EqTilde, MATCH), (C(Regexp));
#undef C
#undef OP
}
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 220404cfb5..73e88e5a42 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -55,11 +55,12 @@ enum {
BOP_GE,
BOP_NOT,
BOP_NEQ,
+ BOP_MATCH,
BOP_LAST_
};
-extern char ruby_vm_redefined_flag[BOP_LAST_];
+extern short ruby_vm_redefined_flag[BOP_LAST_];
extern VALUE ruby_vm_const_missing_count;
#if VM_COLLECT_USAGE_DETAILS
@@ -237,6 +238,7 @@ enum vm_regan_acttype {
#define BIGNUM_REDEFINED_OP_FLAG (1 << 5)
#define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
#define TIME_REDEFINED_OP_FLAG (1 << 7)
+#define REGEXP_REDEFINED_OP_FLAG (1 << 8)
#define BASIC_OP_UNREDEFINED_P(op, klass) (LIKELY((ruby_vm_redefined_flag[(op)]&(klass)) == 0))