diff --git a/compile.c b/compile.c index 7ba0604699..5cf7f750fc 100644 --- a/compile.c +++ b/compile.c @@ -29,6 +29,9 @@ #undef RUBY_UNTYPED_DATA_WARNING #define RUBY_UNTYPED_DATA_WARNING 0 +rb_control_frame_t * + FUNC_FASTCALL(rb_vm_str_intern)(rb_thread_t *, rb_control_frame_t *); + #define ISEQ_TYPE_ONCE_GUARD ISEQ_TYPE_DEFINED_GUARD #define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG)) @@ -6571,7 +6574,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp case NODE_DSYM:{ compile_dstr(iseq, ret, node); if (!popped) { - ADD_SEND(ret, line, idIntern, INT2FIX(0)); + ADD_INSN1(ret, line, opt_call_c_function, rb_vm_str_intern); } else { ADD_INSN(ret, line, pop); diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb index 4a447d59fc..9645e3234b 100644 --- a/test/ruby/test_literal.rb +++ b/test/ruby/test_literal.rb @@ -119,6 +119,21 @@ class TestRubyLiteral < Test::Unit::TestCase assert_equal :a3c, :"a#{1+2}c" end + def test_dsymbol_redefined_intern + assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}") + begin; + class String + alias _intern intern + def intern + "<#{upcase}>" + end + end + mesg = "literal symbol should not be affected by method redefinition" + str = "foo" + assert_equal(:foo, :"#{str}", mesg) + end; + end + def test_xstring assert_equal "foo\n", `echo foo` s = 'foo' diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 1678100eab..d11529ed75 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2794,6 +2794,13 @@ FUNC_FASTCALL(rb_vm_opt_struct_aset)(rb_thread_t *th, rb_control_frame_t *reg_cf return reg_cfp; } +rb_control_frame_t * +FUNC_FASTCALL(rb_vm_str_intern)(rb_thread_t *th, rb_control_frame_t *reg_cfp) +{ + TOPN(0) = rb_str_intern(TOPN(0)); + return reg_cfp; +} + /* defined insn */ static enum defined_type