diff options
-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", |