* 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]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43050 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
charliesome 2013-09-26 07:39:48 +00:00
Родитель 4190cdddbb
Коммит b18151cf53
5 изменённых файлов: 41 добавлений и 3 удалений

Просмотреть файл

@ -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> Thu Sep 26 14:46:49 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* gc.c (mark_locations_array): disable AddressSanitizer. based on a * gc.c (mark_locations_array): disable AddressSanitizer. based on a

Просмотреть файл

@ -2080,7 +2080,11 @@ opt_regexpmatch1
(VALUE obj) (VALUE obj)
(VALUE val) (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);
}
} }
/** /**

Просмотреть файл

@ -1011,6 +1011,18 @@ class TestRegexp < Test::Unit::TestCase
assert_equal(1, pr4.call(1)) assert_equal(1, pr4.call(1))
end 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. # This assertion is for porting x2() tests in testpy.py of Onigmo.
def assert_match_at(re, str, positions, msg = nil) def assert_match_at(re, str, positions, msg = nil)
re = Regexp.new(re) unless re.is_a?(Regexp) re = Regexp.new(re) unless re.is_a?(Regexp)

4
vm.c
Просмотреть файл

@ -99,7 +99,7 @@ VALUE rb_cEnv;
VALUE rb_mRubyVMFrozenCore; VALUE rb_mRubyVMFrozenCore;
VALUE ruby_vm_const_missing_count = 0; 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_thread_t *ruby_current_thread = 0;
rb_vm_t *ruby_current_vm = 0; rb_vm_t *ruby_current_vm = 0;
rb_event_flag_t ruby_vm_event_flags; 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_cBignum) return BIGNUM_REDEFINED_OP_FLAG;
if (klass == rb_cSymbol) return SYMBOL_REDEFINED_OP_FLAG; if (klass == rb_cSymbol) return SYMBOL_REDEFINED_OP_FLAG;
if (klass == rb_cTime) return TIME_REDEFINED_OP_FLAG; if (klass == rb_cTime) return TIME_REDEFINED_OP_FLAG;
if (klass == rb_cRegexp) return REGEXP_REDEFINED_OP_FLAG;
return 0; return 0;
} }
@ -1094,6 +1095,7 @@ vm_init_redefined_flag(void)
OP(Size, SIZE), (C(Array), C(String), C(Hash)); OP(Size, SIZE), (C(Array), C(String), C(Hash));
OP(EmptyP, EMPTY_P), (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(Succ, SUCC), (C(Fixnum), C(String), C(Time));
OP(EqTilde, MATCH), (C(Regexp));
#undef C #undef C
#undef OP #undef OP
} }

Просмотреть файл

@ -55,11 +55,12 @@ enum {
BOP_GE, BOP_GE,
BOP_NOT, BOP_NOT,
BOP_NEQ, BOP_NEQ,
BOP_MATCH,
BOP_LAST_ 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; extern VALUE ruby_vm_const_missing_count;
#if VM_COLLECT_USAGE_DETAILS #if VM_COLLECT_USAGE_DETAILS
@ -237,6 +238,7 @@ enum vm_regan_acttype {
#define BIGNUM_REDEFINED_OP_FLAG (1 << 5) #define BIGNUM_REDEFINED_OP_FLAG (1 << 5)
#define SYMBOL_REDEFINED_OP_FLAG (1 << 6) #define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
#define TIME_REDEFINED_OP_FLAG (1 << 7) #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)) #define BASIC_OP_UNREDEFINED_P(op, klass) (LIKELY((ruby_vm_redefined_flag[(op)]&(klass)) == 0))