diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-05-25 09:44:44 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-05-25 09:44:44 +0000 |
commit | 25be39306eb05ff940cc870161f13ad99fbd7e2f (patch) | |
tree | ed33f493d253fc4e5cce41e2248a6b98015e4bd6 | |
parent | 4f6841496ab79e0b0759684ecb8ce2d69e450e97 (diff) |
* variable.c (rb_const_get_0): Fix previous change. There were
possibilities when an autoload-specified library lacks
definition of the constant it was bound to. Once after such
library had already beed loaded, the autoload engine shall not
reload it. Instead the interpreter have to consider such
constant nonexistent. It results in a const_missing situation.
* variable.c (rb_autoload_load): ditto.
* variable.c (autoload_node): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@31734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | variable.c | 52 |
2 files changed, 51 insertions, 14 deletions
@@ -1,3 +1,16 @@ +Wed May 25 18:40:47 2011 URABE Shyouhei <shyouhei@ruby-lang.org> + + * variable.c (rb_const_get_0): Fix previous change. There were + possibilities when an autoload-specified library lacks + definition of the constant it was bound to. Once after such + library had already beed loaded, the autoload engine shall not + reload it. Instead the interpreter have to consider such + constant nonexistent. It results in a const_missing situation. + + * variable.c (rb_autoload_load): ditto. + + * variable.c (autoload_node): ditto. + Wed May 25 14:35:02 2011 URABE Shyouhei <shyouhei@ruby-lang.org> * variable.c (rb_autoload_load): There is a race condition while diff --git a/variable.c b/variable.c index 7f5064521f..54bb153e2b 100644 --- a/variable.c +++ b/variable.c @@ -1352,16 +1352,29 @@ autoload_node(mod, id) ID id; { st_data_t val, load, n = id; - struct st_table *p = RCLASS(mod)->iv_tbl; + struct st_table *p, *q; - if (p && st_lookup(p, autoload, &val)) { - st_table *q = check_autoload_table((VALUE)val); - - if (q && st_lookup(q, n, &load)) { - return (NODE *)load; - } + if ((p = RCLASS(mod)->iv_tbl) == 0) { + return 0; + } + else if (!st_lookup(p, n, &val)) { + return 0; + } + else if (val != Qundef) { + return 0; + } + else if (!st_lookup(p, autoload, &val)) { + return 0; + } + else if ((q = check_autoload_table((VALUE)val)) == 0) { + return 0; + } + else if (!st_lookup(q, n, &load)) { + return 0; + } + else { + return (NODE *)load; } - return 0; } VALUE @@ -1372,12 +1385,16 @@ rb_autoload_load(klass, id) NODE *load = 0; VALUE ret = 0; - if ((load = autoload_node(klass, id)) != 0) { - if ((ret = rb_require_safe(load->nd_lit, load->nd_nth)) != Qfalse) { - (void) autoload_delete(klass, id); - } + if ((load = autoload_node(klass, id)) == 0) { + return 0; + } + else if ((ret = rb_require_safe(load->nd_lit, load->nd_nth)) == Qfalse) { + return 0; + } + else { + (void) autoload_delete(klass, id); + return ret; } - return ret; } static VALUE @@ -1440,7 +1457,14 @@ rb_const_get_0(klass, id, exclude, recurse) while (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) { if (value == Qundef) { rb_autoload_load(tmp, id); - continue; + st_lookup(RCLASS(tmp)->iv_tbl, id, &value); + if (value == Qundef) { + /* the autoload above did not assign a constant */ + break; + } + else { + continue; + } } if (exclude && tmp == rb_cObject && klass != rb_cObject) { rb_warn("toplevel constant %s referenced by %s::%s", |