summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-20 07:17:55 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-12-20 07:17:55 +0000
commit2a70f68c05118775da45e630a96e89f6f57ceb39 (patch)
tree9aeaa9cd0198e44b88fdba51609b1bce75041bf3
parentfe8475d7df29e5b4775272754ba1989ac9a842a4 (diff)
hide iseq operand object for duphash. [Bug #15440]
* compile.c (compile_array): hide source Hash object. * hash.c (rb_hash_resurrect): introduced to dup Hash object using rb_cHash. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--compile.c3
-rw-r--r--hash.c7
-rw-r--r--insns.def2
-rw-r--r--internal.h1
-rw-r--r--test/ruby/test_literal.rb10
5 files changed, 14 insertions, 9 deletions
diff --git a/compile.c b/compile.c
index cb168438d8d..0bca4886147 100644
--- a/compile.c
+++ b/compile.c
@@ -4026,8 +4026,7 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node_ro
hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2);
rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR_TRANSIENT(ary), hash);
- rb_hash_freeze(hash);
- iseq_add_mark_object_compile_time(iseq, hash);
+ iseq_add_mark_object_compile_time(iseq, rb_obj_hide(hash));
ADD_INSN1(ret, line, duphash, hash);
}
}
diff --git a/hash.c b/hash.c
index 3809e017f26..3bba88adc7c 100644
--- a/hash.c
+++ b/hash.c
@@ -1310,6 +1310,13 @@ rb_hash_dup(VALUE hash)
return ret;
}
+MJIT_FUNC_EXPORTED VALUE
+rb_hash_resurrect(VALUE hash)
+{
+ VALUE ret = hash_dup(hash, rb_cHash, 0);
+ return ret;
+}
+
static void
rb_hash_modify_check(VALUE hash)
{
diff --git a/insns.def b/insns.def
index 73628a33762..983a20fa3f3 100644
--- a/insns.def
+++ b/insns.def
@@ -461,7 +461,7 @@ duphash
()
(VALUE val)
{
- val = rb_hash_dup(hash);
+ val = rb_hash_resurrect(hash);
}
/* if TOS is an array expand, expand it to num objects.
diff --git a/internal.h b/internal.h
index 1aad0c85a0c..b62feb9cf17 100644
--- a/internal.h
+++ b/internal.h
@@ -1573,6 +1573,7 @@ VALUE rb_hash_key_str(VALUE);
VALUE rb_hash_keys(VALUE hash);
VALUE rb_hash_values(VALUE hash);
VALUE rb_hash_rehash(VALUE hash);
+VALUE rb_hash_resurrect(VALUE hash);
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
void rb_hash_bulk_insert(long, const VALUE *, VALUE);
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index 2f3016e2498..3bb2aed65b7 100644
--- a/test/ruby/test_literal.rb
+++ b/test/ruby/test_literal.rb
@@ -290,12 +290,10 @@ class TestRubyLiteral < Test::Unit::TestCase
{0=>1,1=>4,2=>17}
end
- assert_not_include frozen_hash_literal_arg, 3
- assert_raise(FrozenError) do
- ObjectSpace.each_object(Hash) do |a|
- if a.class == Hash and !a.default_proc and a.size == 3
- a[3] = 8 if a[0] == 1 and a[1] == 4 and a[2] == 17
- end
+ ObjectSpace.each_object(Hash) do |a|
+ if a.class == Hash and !a.default_proc and a.size == 3
+ # should not be found.
+ raise
end
end
assert_not_include frozen_hash_literal_arg, 3