[前][次][番号順一覧][スレッド一覧]

ruby-changes:9017

From: yugui <ko1@a...>
Date: Fri, 5 Dec 2008 22:35:37 +0900 (JST)
Subject: [ruby-changes:9017] Ruby:r20551 (ruby_1_9_1): merges r20531 from trunk into ruby_1_9_1.

yugui	2008-12-05 22:33:59 +0900 (Fri, 05 Dec 2008)

  New Revision: 20551

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20551

  Log:
    merges r20531 from trunk into ruby_1_9_1.
    * load.c (rb_get_load_path): returns the load path without
      touching.
    * load.c (rb_feature_provided): new function to return the loading
      path in addition to rb_provided().
    
    * load.c (search_required): sets path if loading.
    
    * variable.c (autoload_provided): load paths are expanded to check
      if loading.
    
    * variable.c (autoload_node): keeps autoload mark while loading.
      [ruby-core:20235]
    
    * variable.c (rb_const_get_0): loops while autoload mark is set.

  Modified files:
    branches/ruby_1_9_1/ChangeLog
    branches/ruby_1_9_1/bootstraptest/test_autoload.rb
    branches/ruby_1_9_1/include/ruby/intern.h
    branches/ruby_1_9_1/load.c
    branches/ruby_1_9_1/variable.c

Index: ruby_1_9_1/include/ruby/intern.h
===================================================================
--- ruby_1_9_1/include/ruby/intern.h	(revision 20550)
+++ ruby_1_9_1/include/ruby/intern.h	(revision 20551)
@@ -267,6 +267,7 @@
 void rb_load_protect(VALUE, int, int*);
 NORETURN(void rb_jump_tag(int));
 int rb_provided(const char*);
+int rb_feature_provided(const char *, const char **);
 void rb_provide(const char*);
 VALUE rb_f_require(VALUE, VALUE);
 VALUE rb_require_safe(VALUE, int);
Index: ruby_1_9_1/ChangeLog
===================================================================
--- ruby_1_9_1/ChangeLog	(revision 20550)
+++ ruby_1_9_1/ChangeLog	(revision 20551)
@@ -1,3 +1,21 @@
+Fri Dec  5 03:29:17 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* load.c (rb_get_load_path): returns the load path without
+	  touching.
+
+	* load.c (rb_feature_provided): new function to return the loading
+	  path in addition to rb_provided().
+
+	* load.c (search_required): sets path if loading.
+
+	* variable.c (autoload_provided): load paths are expanded to check
+	  if loading.
+
+	* variable.c (autoload_node): keeps autoload mark while loading.
+	  [ruby-core:20235]
+
+	* variable.c (rb_const_get_0): loops while autoload mark is set.
+
 Fri Dec  5 01:19:21 2008  Yukihiro Matsumoto  <matz@r...>
 
 	* pack.c (pack_pack): propagate taint status from format string to
Index: ruby_1_9_1/variable.c
===================================================================
--- ruby_1_9_1/variable.c	(revision 20550)
+++ ruby_1_9_1/variable.c	(revision 20551)
@@ -1387,57 +1387,76 @@
     return (NODE *)load;
 }
 
-VALUE
-rb_autoload_load(VALUE klass, ID id)
+static VALUE
+autoload_provided(VALUE arg)
 {
-    VALUE file;
-    NODE *load = autoload_delete(klass, id);
-
-    if (!load || !(file = load->nd_lit)) {
-	return Qfalse;
-    }
-    return rb_require_safe(file, load->nd_nth);
+    const char **p = (const char **)arg;
+    return rb_feature_provided(*p, p);
 }
 
 static VALUE
-autoload_file(VALUE mod, ID id)
+reset_safe(VALUE safe)
 {
+    rb_set_safe_level_force((int)safe);
+    return safe;
+}
+
+static NODE *
+autoload_node(VALUE mod, ID id, int noload)
+{
     VALUE file;
     struct st_table *tbl;
-    st_data_t val, load, n = id;
+    st_data_t val;
+    NODE *load;
+    const char *loading;
+    int safe;
 
     if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
-	!(tbl = check_autoload_table((VALUE)val)) || !st_lookup(tbl, n, &load)) {
-	return Qnil;
+	!(tbl = check_autoload_table((VALUE)val)) || !st_lookup(tbl, (st_data_t)id, &val)) {
+	return 0;
     }
-    file = ((NODE *)load)->nd_lit;
+    load = (NODE *)val;
+    file = load->nd_lit;
     Check_Type(file, T_STRING);
     if (!RSTRING_PTR(file) || !*RSTRING_PTR(file)) {
 	rb_raise(rb_eArgError, "empty file name");
     }
-    if (!rb_provided(RSTRING_PTR(file))) {
-	return file;
+    loading = RSTRING_PTR(file);
+    safe = rb_safe_level();
+    rb_set_safe_level_force(0);
+    if (!rb_ensure(autoload_provided, (VALUE)&loading, reset_safe, (VALUE)safe)) {
+	return load;
     }
-
-    /* already loaded but not defined */
-    st_delete(tbl, &n, 0);
-    if (!tbl->num_entries) {
-	n = autoload;
-	st_delete(RCLASS_IV_TBL(mod), &n, &val);
+    if (!noload && loading) {
+	return load;
     }
-    return Qnil;
+    return 0;
 }
 
 VALUE
+rb_autoload_load(VALUE klass, ID id)
+{
+    VALUE file;
+    NODE *load = autoload_node(klass, id, 0);
+
+    if (!load) return Qfalse;
+    file = load->nd_lit;
+    return rb_require_safe(file, load->nd_nth);
+}
+
+VALUE
 rb_autoload_p(VALUE mod, ID id)
 {
     struct st_table *tbl = RCLASS_IV_TBL(mod);
-    VALUE val;
+    st_data_t val;
+    NODE *load;
+    VALUE file;
 
     if (!tbl || !st_lookup(tbl, id, &val) || val != Qundef) {
 	return Qnil;
     }
-    return autoload_file(mod, id);
+    load = autoload_node(mod, id, 0);
+    return load && (file = load->nd_lit) ? file : Qnil;
 }
 
 static VALUE
@@ -1451,7 +1470,7 @@
     while (RTEST(tmp)) {
 	while (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp),id,&value)) {
 	    if (value == Qundef) {
-		if (!RTEST(rb_autoload_load(tmp, id))) break;
+		rb_autoload_load(tmp, id);
 		continue;
 	    }
 	    if (exclude && tmp == rb_cObject && klass != rb_cObject) {
@@ -1636,7 +1655,7 @@
   retry:
     while (tmp) {
 	if (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp), id, &value)) {
-	    if (value == Qundef && NIL_P(autoload_file(klass, id)))
+	    if (value == Qundef && !autoload_node(klass, id, 1))
 		return Qfalse;
 	    return Qtrue;
 	}
@@ -1675,7 +1694,7 @@
     const char *dest = isconst ? "constant" : "class variable";
 
     if (!OBJ_UNTRUSTED(klass) && rb_safe_level() >= 4)
-      rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest);
+	rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest);
     if (OBJ_FROZEN(klass)) {
 	if (BUILTIN_TYPE(klass) == T_MODULE) {
 	    rb_error_frozen("module");
@@ -1698,7 +1717,7 @@
 	}
     }
 
-    if(isconst){
+    if (isconst){
 	rb_vm_change_state();
     }
     st_insert(RCLASS_IV_TBL(klass), id, val);
Index: ruby_1_9_1/bootstraptest/test_autoload.rb
===================================================================
--- ruby_1_9_1/bootstraptest/test_autoload.rb	(revision 20550)
+++ ruby_1_9_1/bootstraptest/test_autoload.rb	(revision 20551)
@@ -50,3 +50,12 @@
   module M; end
   Thread.new{eval('$SAFE=4; ZZZ.new.hoge')}.value
 }
+
+assert_equal 'okok', %q{
+  open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"}
+  autoload :ZZZ, "./zzz.rb"
+  t1 = Thread.new {ZZZ.ok}
+  t2 = Thread.new {ZZZ.ok}
+  [t1.value, t2.value].join
+}
+
Index: ruby_1_9_1/load.c
===================================================================
--- ruby_1_9_1/load.c	(revision 20550)
+++ ruby_1_9_1/load.c	(revision 20551)
@@ -30,13 +30,7 @@
 rb_get_load_path(void)
 {
     VALUE load_path = GET_VM()->load_path;
-    VALUE ary = rb_ary_new2(RARRAY_LEN(load_path));
-    long i;
-
-    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
-	rb_ary_push(ary, rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil));
-    }
-    return ary;
+    return load_path;
 }
 
 static VALUE
@@ -198,6 +192,12 @@
 int
 rb_provided(const char *feature)
 {
+    return rb_feature_provided(feature, 0);
+}
+
+int
+rb_feature_provided(const char *feature, const char **loading)
+{
     const char *ext = strrchr(feature, '.');
     volatile VALUE fullpath = 0;
 
@@ -208,15 +208,15 @@
     }
     if (ext && !strchr(ext, '/')) {
 	if (IS_RBEXT(ext)) {
-	    if (rb_feature_p(feature, ext, Qtrue, Qfalse, 0)) return Qtrue;
+	    if (rb_feature_p(feature, ext, Qtrue, Qfalse, loading)) return Qtrue;
 	    return Qfalse;
 	}
 	else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
-	    if (rb_feature_p(feature, ext, Qfalse, Qfalse, 0)) return Qtrue;
+	    if (rb_feature_p(feature, ext, Qfalse, Qfalse, loading)) return Qtrue;
 	    return Qfalse;
 	}
     }
-    if (rb_feature_p(feature, feature + strlen(feature), Qtrue, Qfalse, 0))
+    if (rb_feature_p(feature, feature + strlen(feature), Qtrue, Qfalse, loading))
 	return Qtrue;
     return Qfalse;
 }
@@ -430,9 +430,8 @@
 		return 'r';
 	    }
 	    if ((tmp = rb_find_file(fname)) != 0) {
-		tmp = rb_file_expand_path(tmp, Qnil);
 		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
-		if (!rb_feature_p(ftptr, ext, Qtrue, Qtrue, 0))
+		if (!rb_feature_p(ftptr, ext, Qtrue, Qtrue, &loading) || loading)
 		    *path = tmp;
 		return 'r';
 	    }
@@ -447,9 +446,8 @@
 #ifdef DLEXT2
 	    OBJ_FREEZE(tmp);
 	    if (rb_find_file_ext(&tmp, loadable_ext + 1)) {
-		tmp = rb_file_expand_path(tmp, Qnil);
 		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
-		if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, 0))
+		if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading)
 		    *path = tmp;
 		return 's';
 	    }
@@ -457,9 +455,8 @@
 	    rb_str_cat2(tmp, DLEXT);
 	    OBJ_FREEZE(tmp);
 	    if ((tmp = rb_find_file(tmp)) != 0) {
-		tmp = rb_file_expand_path(tmp, Qnil);
 		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
-		if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, 0))
+		if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading)
 		    *path = tmp;
 		return 's';
 	    }
@@ -471,9 +468,8 @@
 		return 's';
 	    }
 	    if ((tmp = rb_find_file(fname)) != 0) {
-		tmp = rb_file_expand_path(tmp, Qnil);
 		ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
-		if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, 0))
+		if (!rb_feature_p(ftptr, ext, Qfalse, Qtrue, &loading) || loading)
 		    *path = tmp;
 		return 's';
 	    }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]