summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-25 09:44:44 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-25 09:44:44 +0000
commit25be39306eb05ff940cc870161f13ad99fbd7e2f (patch)
treeed33f493d253fc4e5cce41e2248a6b98015e4bd6
parent4f6841496ab79e0b0759684ecb8ce2d69e450e97 (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--ChangeLog13
-rw-r--r--variable.c52
2 files changed, 51 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b28323c99..bb4e65ac1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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",