aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-20 23:49:31 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-20 23:49:31 +0000
commitba772af0a6b36713077799e5c5cbcb375d4ee1c8 (patch)
treefdd4d99a31b59f1bd4f08b5ec7d0b7537339a1c8
parent894352164853a4851f215d1f082a1627c80a43ea (diff)
downloadruby-ba772af0a6b36713077799e5c5cbcb375d4ee1c8.tar.gz
* 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
-rw-r--r--ChangeLog22
-rw-r--r--compile.c21
-rw-r--r--defs/id.def3
-rw-r--r--error.c11
-rw-r--r--insns.def17
-rw-r--r--test/ruby/test_iseq.rb1
-rw-r--r--test/ruby/test_rubyoptions.rb8
7 files changed, 62 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 1768f6b581..8c1d6ff2ac 100644
--- a/ChangeLog
+++ b/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
diff --git a/compile.c b/compile.c
index e5ec768c94..dfd4330209 100644
--- a/compile.c
+++ b/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;
diff --git a/defs/id.def b/defs/id.def
index 9d336b24a7..1ff0d9aa3d 100644
--- a/defs/id.def
+++ b/defs/id.def
@@ -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
diff --git a/error.c b/error.c
index 3dbdb5240f..816d704a1e 100644
--- a/error.c
+++ b/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);
}
diff --git a/insns.def b/insns.def
index 33aedfc83d..36a132b585 100644
--- a/insns.def
+++ b/insns.def
@@ -391,6 +391,23 @@ tostring
/**
@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
@j 文字列 str を正規表現にコンパイルしてスタックにプッシュする。
コンパイル時,opt を正規表現のオプションとする。
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index b239e0b5c1..4f7616a0db 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -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
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 7da34bd5f6..3d77d072b2 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -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