summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-12 10:42:36 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-02-12 10:42:36 +0000
commite52da919872f8cf71c90a27b470cef724204eece (patch)
tree2d425228fcba503e2f0a82726548f477cefc5da0
parent48149dff328079a25b9f17d47999a513b14389c6 (diff)
* compile.c (compile_array_, defined_expr, iseq_compile_each): hide
and freeze internal literal objects, to prevent from modifying. [ruby-dev:37959] * iseq.c (insn_operand_intern): copy internal literal objects. * insns.def (putstring, duparray): ditto. * string.c (rb_str_replace): exported. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22255 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--compile.c5
-rw-r--r--include/ruby/intern.h1
-rw-r--r--insns.def4
-rw-r--r--iseq.c12
-rw-r--r--string.c18
6 files changed, 41 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index c9e0005fbd..2cfd0fc7f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Thu Feb 12 19:42:33 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * compile.c (compile_array_, defined_expr, iseq_compile_each): hide
+ and freeze internal literal objects, to prevent from modifying.
+ [ruby-dev:37959]
+
+ * iseq.c (insn_operand_intern): copy internal literal objects.
+
+ * insns.def (putstring, duparray): ditto.
+
+ * string.c (rb_str_replace): exported.
+
Thu Feb 12 17:17:51 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/stringio/stringio.c (strio_ungetc): calculates new position
diff --git a/compile.c b/compile.c
index 3e1d7fb92d..05572233ad 100644
--- a/compile.c
+++ b/compile.c
@@ -295,6 +295,7 @@ PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2);
#define INIT_ANCHOR(name) \
(name##_body__.last = &name##_body__.anchor, name = &name##_body__)
+#define hide_obj(obj) (void)(OBJ_FREEZE(obj), RBASIC(obj)->klass = 0)
#include "optinsn.inc"
#if OPT_INSTRUCTIONS_UNIFICATION
@@ -2230,7 +2231,7 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
if (opt_p == Qtrue) {
if (!poped) {
- VALUE ary = rb_ary_new();
+ VALUE ary = rb_ary_tmp_new(len);
node = node_root;
while (node) {
rb_ary_push(ary, node->nd_head->nd_lit);
@@ -2709,6 +2710,7 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
if (estr != 0) {
if (needstr != Qfalse) {
VALUE str = rb_str_new2(estr);
+ hide_obj(str);
ADD_INSN1(ret, nd_line(node), putstring, str);
iseq_add_mark_object_compile_time(iseq, str);
}
@@ -4353,6 +4355,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_STR:{
debugp_param("nd_lit", node->nd_lit);
if (!poped) {
+ hide_obj(node->nd_lit);
ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit);
}
break;
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index 100b6c0975..e268428579 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -617,6 +617,7 @@ int rb_str_cmp(VALUE, VALUE);
VALUE rb_str_equal(VALUE str1, VALUE str2);
VALUE rb_str_drop_bytes(VALUE, long);
void rb_str_update(VALUE, long, long, VALUE);
+VALUE rb_str_replace(VALUE, VALUE);
VALUE rb_str_inspect(VALUE);
VALUE rb_str_dump(VALUE);
VALUE rb_str_split(VALUE, const char*);
diff --git a/insns.def b/insns.def
index cd779d1393..4eef8f64fa 100644
--- a/insns.def
+++ b/insns.def
@@ -373,7 +373,7 @@ putstring
()
(VALUE val)
{
- val = rb_str_new3(str);
+ val = rb_str_replace(rb_str_new(0, 0), str);
}
/**
@@ -460,7 +460,7 @@ duparray
()
(VALUE val)
{
- val = rb_ary_dup(ary);
+ val = rb_ary_replace(rb_ary_new2(0), ary);
}
/**
diff --git a/iseq.c b/iseq.c
index 967b142425..de0bae7234 100644
--- a/iseq.c
+++ b/iseq.c
@@ -21,6 +21,8 @@
VALUE rb_cISeq;
+#define hidden_obj_p(obj) (!SPECIAL_CONST_P(obj) && !RBASIC(obj)->klass)
+
static void
compile_data_free(struct iseq_compile_data *compile_data)
{
@@ -699,6 +701,16 @@ insn_operand_intern(rb_iseq_t *iseq,
op = ID2SYM(op);
case TS_VALUE: /* VALUE */
+ if (hidden_obj_p(op)) {
+ switch (BUILTIN_TYPE(op)) {
+ case T_STRING:
+ op = rb_str_replace(rb_str_new(0, 0), op);
+ break;
+ case T_ARRAY:
+ op = rb_ary_replace(rb_ary_new2(0), op);
+ break;
+ }
+ }
ret = rb_inspect(op);
if (CLASS_OF(op) == rb_cISeq) {
rb_ary_push(child, op);
diff --git a/string.c b/string.c
index 802e9379bf..8eb83efcec 100644
--- a/string.c
+++ b/string.c
@@ -815,14 +815,18 @@ rb_obj_as_string(VALUE obj)
return str;
}
-static VALUE rb_str_replace(VALUE, VALUE);
+static VALUE
+str_duplicate(VALUE klass, VALUE str)
+{
+ VALUE dup = str_alloc(klass);
+ rb_str_replace(dup, str);
+ return dup;
+}
VALUE
rb_str_dup(VALUE str)
{
- VALUE dup = str_alloc(rb_obj_class(str));
- rb_str_replace(dup, str);
- return dup;
+ return str_duplicate(rb_obj_class(str), str);
}
@@ -3722,7 +3726,7 @@ rb_str_gsub(int argc, VALUE *argv, VALUE str)
* s.replace "world" #=> "world"
*/
-static VALUE
+VALUE
rb_str_replace(VALUE str, VALUE str2)
{
long len;
@@ -4024,9 +4028,7 @@ static VALUE
rb_str_to_s(VALUE str)
{
if (rb_obj_class(str) != rb_cString) {
- VALUE dup = str_alloc(rb_cString);
- rb_str_replace(dup, str);
- return dup;
+ return str_duplicate(rb_cString, str);
}
return str;
}