mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ruby.c: introduce --enable-frozen-string-literal-debug option.
If this option is enabled, the modify error will be: can't modify frozen String (RuntimeError) => can't modify frozen String, created at test.rb:3 (RuntimeError) * iseq.h: add compile option frozen_string_literal_debug. * compile.c: catch up this fix. * error.c (rb_error_frozen): ditto. * iseq.c (set_compile_option_from_hash): ditto. * test/ruby/test_rubyoptions.rb: add a test for this fix. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52257 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
31f21aed2c
commit
54716fe7eb
7 changed files with 60 additions and 5 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
Sat Oct 24 03:58:02 2015 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* ruby.c: introduce --enable-frozen-string-literal-debug option.
|
||||
If this option is enabled, the modify error will be:
|
||||
can't modify frozen String (RuntimeError) =>
|
||||
can't modify frozen String, created at test.rb:3 (RuntimeError)
|
||||
|
||||
* iseq.h: add compile option frozen_string_literal_debug.
|
||||
|
||||
* compile.c: catch up this fix.
|
||||
|
||||
* error.c (rb_error_frozen): ditto.
|
||||
|
||||
* iseq.c (set_compile_option_from_hash): ditto.
|
||||
|
||||
* test/ruby/test_rubyoptions.rb: add a test for this fix.
|
||||
|
||||
Sat Oct 24 02:02:24 2015 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* vm_insnhelper.c: introduce new call handler for simple ISeqs.
|
||||
|
|
12
compile.c
12
compile.c
|
@ -5107,11 +5107,19 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||
debugp_param("nd_lit", node->nd_lit);
|
||||
if (!poped) {
|
||||
node->nd_lit = rb_fstring(node->nd_lit);
|
||||
if (iseq->compile_data->option->frozen_string_literal) {
|
||||
if (!iseq->compile_data->option->frozen_string_literal) {
|
||||
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 {
|
||||
ADD_INSN1(ret, line, putstring, node->nd_lit);
|
||||
VALUE str = rb_str_dup(node->nd_lit);
|
||||
rb_iv_set(str, "__object_created_path__", iseq->body->location.path);
|
||||
rb_iv_set(str, "__object_created_line__", INT2FIX(line));
|
||||
ADD_INSN1(ret, line, putobject, rb_obj_freeze(str));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
8
error.c
8
error.c
|
@ -2226,8 +2226,16 @@ rb_error_frozen(const char *what)
|
|||
void
|
||||
rb_error_frozen_object(VALUE frozen_obj)
|
||||
{
|
||||
VALUE path, line;
|
||||
if ((path = rb_iv_get(frozen_obj, "__object_created_path__")) != Qnil &&
|
||||
(line = rb_iv_get(frozen_obj, "__object_created_line__")) != Qnil) {
|
||||
rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
|
||||
CLASS_OF(frozen_obj), path, line);
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE,
|
||||
CLASS_OF(frozen_obj));
|
||||
}
|
||||
}
|
||||
|
||||
#undef rb_check_frozen
|
||||
|
|
1
iseq.c
1
iseq.c
|
@ -366,6 +366,7 @@ set_compile_option_from_hash(rb_compile_option_t *option, VALUE opt)
|
|||
SET_COMPILE_OPTION(option, opt, stack_caching);
|
||||
SET_COMPILE_OPTION(option, opt, trace_instruction);
|
||||
SET_COMPILE_OPTION(option, opt, frozen_string_literal);
|
||||
SET_COMPILE_OPTION(option, opt, frozen_string_literal_debug);
|
||||
SET_COMPILE_OPTION_NUM(option, opt, debug_level);
|
||||
#undef SET_COMPILE_OPTION
|
||||
#undef SET_COMPILE_OPTION_NUM
|
||||
|
|
1
iseq.h
1
iseq.h
|
@ -67,6 +67,7 @@ struct rb_compile_option_struct {
|
|||
int stack_caching;
|
||||
int trace_instruction;
|
||||
int frozen_string_literal;
|
||||
int frozen_string_literal_debug;
|
||||
int debug_level;
|
||||
};
|
||||
|
||||
|
|
9
ruby.c
9
ruby.c
|
@ -69,6 +69,7 @@ enum feature_flag_bits {
|
|||
feature_did_you_mean,
|
||||
feature_rubyopt,
|
||||
feature_frozen_string_literal,
|
||||
feature_frozen_string_literal_debug,
|
||||
feature_flag_count
|
||||
};
|
||||
|
||||
|
@ -126,6 +127,7 @@ cmdline_options_init(struct cmdline_options *opt)
|
|||
opt->features &= ~FEATURE_BIT(gems);
|
||||
#endif
|
||||
opt->features &= ~FEATURE_BIT(frozen_string_literal);
|
||||
opt->features &= ~FEATURE_BIT(frozen_string_literal_debug);
|
||||
return opt;
|
||||
}
|
||||
|
||||
|
@ -739,6 +741,7 @@ enable_option(const char *str, int len, void *arg)
|
|||
SET_WHEN_ENABLE(did_you_mean);
|
||||
SET_WHEN_ENABLE(rubyopt);
|
||||
SET_WHEN_ENABLE(frozen_string_literal);
|
||||
SET_WHEN_ENABLE(frozen_string_literal_debug);
|
||||
if (NAME_MATCH_P("all", str, len)) {
|
||||
*(unsigned int *)arg = ~0U;
|
||||
return;
|
||||
|
@ -754,6 +757,7 @@ disable_option(const char *str, int len, void *arg)
|
|||
UNSET_WHEN_DISABLE(did_you_mean);
|
||||
UNSET_WHEN_DISABLE(rubyopt);
|
||||
UNSET_WHEN_DISABLE(frozen_string_literal);
|
||||
UNSET_WHEN_DISABLE(frozen_string_literal_debug);
|
||||
if (NAME_MATCH_P("all", str, len)) {
|
||||
*(unsigned int *)arg = 0U;
|
||||
return;
|
||||
|
@ -1474,6 +1478,11 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
|
|||
rb_hash_aset(option, ID2SYM(rb_intern_const("frozen_string_literal")), Qtrue);
|
||||
rb_funcallv(rb_cISeq, rb_intern_const("compile_option="), 1, &option);
|
||||
}
|
||||
if (opt->features & FEATURE_BIT(frozen_string_literal_debug)) {
|
||||
VALUE option = rb_hash_new();
|
||||
rb_hash_aset(option, ID2SYM(rb_intern_const("frozen_string_literal_debug")), Qtrue);
|
||||
rb_funcallv(rb_cISeq, rb_intern_const("compile_option="), 1, &option);
|
||||
}
|
||||
#if UTF8_PATH
|
||||
opt->script_name = str_conv_enc(opt->script_name, rb_utf8_encoding(), lenc);
|
||||
opt->script = RSTRING_PTR(opt->script_name);
|
||||
|
|
|
@ -804,4 +804,15 @@ class TestRubyOptions < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
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", "--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/)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue