mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* compile.c (iseq_compile_each): add debug information to NODE_STR
strings as default. [Feature #11725] * insns.def (freezestring): add new instruction to support adding debug information for dynamically constracted strings. * compile.c (iseq_compile_each): support adding debug information for NODE_DSTR with freezestring instruction. * error.c (rb_error_frozen): change the debug information ID name id_debug_created_info and this field should have a 2 element array containing path and line information. * defs/id.def: ditto. * test/ruby/test_rubyoptions.rb: catch up this fix. * test/ruby/test_iseq.rb: now frozen strings are not same. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52688 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8943521648
commit
ba772af0a6
7 changed files with 62 additions and 21 deletions
22
ChangeLog
22
ChangeLog
|
@ -1,3 +1,25 @@
|
|||
Sat Nov 21 08:44:21 2015 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* compile.c (iseq_compile_each): add debug information to NODE_STR
|
||||
strings as default.
|
||||
[Feature #11725]
|
||||
|
||||
* insns.def (freezestring): add new instruction to support adding
|
||||
debug information for dynamically constracted strings.
|
||||
|
||||
* compile.c (iseq_compile_each): support adding debug information
|
||||
for NODE_DSTR with freezestring instruction.
|
||||
|
||||
* error.c (rb_error_frozen): change the debug information ID name
|
||||
id_debug_created_info and this field should have a 2 element array
|
||||
containing path and line information.
|
||||
|
||||
* defs/id.def: ditto.
|
||||
|
||||
* test/ruby/test_rubyoptions.rb: catch up this fix.
|
||||
|
||||
* test/ruby/test_iseq.rb: now frozen strings are not same.
|
||||
|
||||
Sat Nov 21 04:34:16 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* symbol.c (rb_str_intern): should not freeze the receiver itself
|
||||
|
|
21
compile.c
21
compile.c
|
@ -5233,15 +5233,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||
ADD_INSN1(ret, line, putstring, node->nd_lit);
|
||||
}
|
||||
else {
|
||||
if (!iseq->compile_data->option->frozen_string_literal_debug) {
|
||||
ADD_INSN1(ret, line, putobject, node->nd_lit); /* already frozen */
|
||||
}
|
||||
else {
|
||||
VALUE str = rb_str_dup(node->nd_lit);
|
||||
rb_ivar_set(str, id_debug_created_path, iseq->body->location.path);
|
||||
rb_ivar_set(str, id_debug_created_line, INT2FIX(line));
|
||||
ADD_INSN1(ret, line, putobject, rb_obj_freeze(str));
|
||||
}
|
||||
VALUE str = rb_str_dup(node->nd_lit);
|
||||
VALUE debug_info = rb_ary_new_from_args(2, iseq->body->location.path, INT2FIX(line));
|
||||
rb_ivar_set(str, id_debug_created_info, rb_obj_freeze(debug_info));
|
||||
ADD_INSN1(ret, line, putobject, rb_obj_freeze(str));
|
||||
iseq_add_mark_object_compile_time(iseq, str);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -5254,7 +5250,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||
}
|
||||
else {
|
||||
if (iseq->compile_data->option->frozen_string_literal) {
|
||||
ADD_SEND (ret, line, idFreeze, INT2FIX(0));
|
||||
VALUE debug_info = Qnil;
|
||||
if (iseq->compile_data->option->frozen_string_literal_debug || RTEST(ruby_debug)) {
|
||||
debug_info = rb_ary_new_from_args(2, iseq->body->location.path, INT2FIX(line));
|
||||
iseq_add_mark_object_compile_time(iseq, rb_obj_freeze(debug_info));
|
||||
}
|
||||
ADD_INSN1(ret, line, freezestring, debug_info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -61,8 +61,7 @@ firstline, predefined = __LINE__+1, %[\
|
|||
core#hash_merge_ptr
|
||||
core#hash_merge_kwd
|
||||
|
||||
- debug#created_path
|
||||
- debug#created_line
|
||||
- debug#created_info
|
||||
]
|
||||
|
||||
# VM ID OP Parser Token
|
||||
|
|
11
error.c
11
error.c
|
@ -2241,12 +2241,13 @@ rb_error_frozen(const char *what)
|
|||
void
|
||||
rb_error_frozen_object(VALUE frozen_obj)
|
||||
{
|
||||
VALUE path, line;
|
||||
const ID created_path = id_debug_created_path;
|
||||
const ID created_line = id_debug_created_line;
|
||||
VALUE debug_info;
|
||||
const ID created_info = id_debug_created_info;
|
||||
|
||||
if (!NIL_P(debug_info = rb_attr_get(frozen_obj, created_info))) {
|
||||
VALUE path = rb_ary_entry(debug_info, 0);
|
||||
VALUE line = rb_ary_entry(debug_info, 1);
|
||||
|
||||
if (!NIL_P(path = rb_attr_get(frozen_obj, created_path)) &&
|
||||
!NIL_P(line = rb_attr_get(frozen_obj, created_line))) {
|
||||
rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
|
||||
CLASS_OF(frozen_obj), path, line);
|
||||
}
|
||||
|
|
17
insns.def
17
insns.def
|
@ -389,6 +389,23 @@ tostring
|
|||
val = rb_obj_as_string(val);
|
||||
}
|
||||
|
||||
/**
|
||||
@c put
|
||||
@e Freeze (dynamically) created strings.
|
||||
@j (埋め込み)文字列を freeze する。もし、debug_info が与えられていれば、それを設定する。
|
||||
*/
|
||||
DEFINE_INSN
|
||||
freezestring
|
||||
(VALUE debug_info)
|
||||
(VALUE str)
|
||||
(VALUE str)
|
||||
{
|
||||
if (!NIL_P(debug_info)) {
|
||||
rb_ivar_set(str, id_debug_created_info, debug_info);
|
||||
}
|
||||
rb_str_freeze(str);
|
||||
}
|
||||
|
||||
/**
|
||||
@c put
|
||||
@e to Regexp
|
||||
|
|
|
@ -177,7 +177,6 @@ class TestISeq < Test::Unit::TestCase
|
|||
assert_predicate(s2, :frozen?)
|
||||
assert_predicate(s3, :frozen?)
|
||||
assert_predicate(s4, :frozen?)
|
||||
assert_same(s1, s2)
|
||||
end
|
||||
|
||||
def test_safe_call_chain
|
||||
|
|
|
@ -807,12 +807,14 @@ class TestRubyOptions < Test::Unit::TestCase
|
|||
|
||||
def test_frozen_string_literal_debug
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", "--enable-frozen-string-literal-debug" ], '"foo" << "bar"', [], /created at/)
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", "--disable-frozen-string-literal-debug"], '"foo" << "bar"', [], /can\'t modify frozen String \(RuntimeError\)\n\z/)
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", "--disable-frozen-string-literal-debug"], '"foo" << "bar"', [], /created at/)
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", "--enable-frozen-string-literal-debug" ], '"foo#{123}bar" << "bar"', [], /created at/)
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", "--disable-frozen-string-literal-debug"], '"foo#{123}bar" << "bar"', [], /can\'t modify frozen String \(RuntimeError\)\n\z/)
|
||||
assert_in_out_err(["--disable=gems", "--disable-frozen-string-literal", "--enable-frozen-string-literal-debug" ], '"foo" << "bar"', [], [])
|
||||
assert_in_out_err(["--disable=gems", "--disable-frozen-string-literal", "--disable-frozen-string-literal-debug"], '"foo" << "bar"', [], [])
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal-debug" ], '"foo" << "bar"', [], [])
|
||||
assert_in_out_err(["--disable=gems", "--disable-frozen-string-literal-debug"], '"foo" << "bar"', [], [])
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", ], '"foo" << "bar"', [], /can\'t modify frozen String \(RuntimeError\)\n\z/)
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", ], '"foo" << "bar"', [], /can\'t modify frozen String \(RuntimeError\)\n\z/)
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", ], '"foo" << "bar"', [], /created at/)
|
||||
assert_in_out_err(["--disable=gems", "--enable-frozen-string-literal", ], '"foo#{123}bar" << "bar"', [], /can\'t modify frozen String \(RuntimeError\)\n\z/)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue