зеркало из https://github.com/github/ruby.git
class.c: always clear tables first
* class.c (rb_mod_init_copy): always clear instance variable, constant and method tables first, regardless the source tables. [ruby-dev:48182] [Bug #9813] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
97cd982a3e
Коммит
7c072b35d1
|
@ -1,3 +1,9 @@
|
||||||
|
Thu May 8 14:34:29 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* class.c (rb_mod_init_copy): always clear instance variable,
|
||||||
|
constant and method tables first, regardless the source tables.
|
||||||
|
[ruby-dev:48182] [Bug #9813]
|
||||||
|
|
||||||
Thu May 8 10:53:14 2014 NARUSE, Yui <naruse@ruby-lang.org>
|
Thu May 8 10:53:14 2014 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* configure.in: OpenBSD needs to include sys/param.h before include
|
* configure.in: OpenBSD needs to include sys/param.h before include
|
||||||
|
|
22
class.c
22
class.c
|
@ -328,12 +328,21 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
|
||||||
}
|
}
|
||||||
RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
|
RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig));
|
||||||
RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
|
RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
|
||||||
|
if (RCLASS_IV_TBL(clone)) {
|
||||||
|
st_free_table(RCLASS_IV_TBL(clone));
|
||||||
|
RCLASS_IV_TBL(clone) = 0;
|
||||||
|
}
|
||||||
|
if (RCLASS_CONST_TBL(clone)) {
|
||||||
|
rb_free_const_table(RCLASS_CONST_TBL(clone));
|
||||||
|
RCLASS_CONST_TBL(clone) = 0;
|
||||||
|
}
|
||||||
|
if (RCLASS_M_TBL_WRAPPER(clone)) {
|
||||||
|
rb_free_m_tbl_wrapper(RCLASS_M_TBL_WRAPPER(clone));
|
||||||
|
RCLASS_M_TBL_WRAPPER(clone) = 0;
|
||||||
|
}
|
||||||
if (RCLASS_IV_TBL(orig)) {
|
if (RCLASS_IV_TBL(orig)) {
|
||||||
st_data_t id;
|
st_data_t id;
|
||||||
|
|
||||||
if (RCLASS_IV_TBL(clone)) {
|
|
||||||
st_free_table(RCLASS_IV_TBL(clone));
|
|
||||||
}
|
|
||||||
RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(orig));
|
RCLASS_IV_TBL(clone) = rb_st_copy(clone, RCLASS_IV_TBL(orig));
|
||||||
CONST_ID(id, "__tmp_classpath__");
|
CONST_ID(id, "__tmp_classpath__");
|
||||||
st_delete(RCLASS_IV_TBL(clone), &id, 0);
|
st_delete(RCLASS_IV_TBL(clone), &id, 0);
|
||||||
|
@ -344,18 +353,13 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
|
||||||
}
|
}
|
||||||
if (RCLASS_CONST_TBL(orig)) {
|
if (RCLASS_CONST_TBL(orig)) {
|
||||||
struct clone_const_arg arg;
|
struct clone_const_arg arg;
|
||||||
if (RCLASS_CONST_TBL(clone)) {
|
|
||||||
rb_free_const_table(RCLASS_CONST_TBL(clone));
|
|
||||||
}
|
|
||||||
RCLASS_CONST_TBL(clone) = st_init_numtable();
|
RCLASS_CONST_TBL(clone) = st_init_numtable();
|
||||||
arg.klass = clone;
|
arg.klass = clone;
|
||||||
arg.tbl = RCLASS_CONST_TBL(clone);
|
arg.tbl = RCLASS_CONST_TBL(clone);
|
||||||
st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)&arg);
|
st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)&arg);
|
||||||
}
|
}
|
||||||
if (RCLASS_M_TBL(orig)) {
|
if (RCLASS_M_TBL(orig)) {
|
||||||
if (RCLASS_M_TBL_WRAPPER(clone)) {
|
|
||||||
rb_free_m_tbl_wrapper(RCLASS_M_TBL_WRAPPER(clone));
|
|
||||||
}
|
|
||||||
RCLASS_M_TBL_INIT(clone);
|
RCLASS_M_TBL_INIT(clone);
|
||||||
st_foreach(RCLASS_M_TBL(orig), clone_method_i, (st_data_t)clone);
|
st_foreach(RCLASS_M_TBL(orig), clone_method_i, (st_data_t)clone);
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,6 +375,25 @@ class TestModule < Test::Unit::TestCase
|
||||||
assert_equal(:ok, Object.new.extend(m).foo, bug9535)
|
assert_equal(:ok, Object.new.extend(m).foo, bug9535)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_initialize_copy_empty
|
||||||
|
bug9813 = '[ruby-dev:48182] [Bug #9813]'
|
||||||
|
m = Module.new do
|
||||||
|
def x
|
||||||
|
end
|
||||||
|
const_set(:X, 1)
|
||||||
|
@x = 2
|
||||||
|
end
|
||||||
|
assert_equal([:x], m.instance_methods)
|
||||||
|
assert_equal([:@x], m.instance_variables)
|
||||||
|
assert_equal([:X], m.constants)
|
||||||
|
m.module_eval do
|
||||||
|
initialize_copy(Module.new)
|
||||||
|
end
|
||||||
|
assert_empty(m.instance_methods, bug9813)
|
||||||
|
assert_empty(m.instance_variables, bug9813)
|
||||||
|
assert_empty(m.constants, bug9813)
|
||||||
|
end
|
||||||
|
|
||||||
def test_dup
|
def test_dup
|
||||||
bug6454 = '[ruby-core:45132]'
|
bug6454 = '[ruby-core:45132]'
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче