[#30408] Ruby 1.8.6 preview2 has been released — "Akinori MUSHA" <knu@...>

 Ruby 1.8.6 preview2 をリリースしました。

20 messages 2007/02/24
[#30414] fail to autoload at $SAFE==4 (Re: Ruby 1.8.6 preview2 has been released) — Hidetoshi NAGAI <nagai@...> 2007/02/25

永井@知能.九工大です.

[#30418] Re: fail to autoload at $SAFE==4 (Re: Ruby 1.8.6 preview2 has been released) — Nobuyoshi Nakada <nobu@...> 2007/02/25

なかだです。

[ruby-dev:30366] Re: schedule for Ruby 1.8.6

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-02-17 01:52:14 UTC
List: ruby-dev #30366
なかだです。

At Thu, 1 Feb 2007 22:29:55 +0900,
Hiroyuki Iwatsuki wrote in [ruby-dev:30239]:
> 昨年末の話ですが、
> [ruby-dev:30023] autoloading static linked extension
> での修正はRuby 1.8.6に反映されますでしょうか?
> なかださんがRuby 1.8用差分を出したところで話が止まっている
> ように思いますが、できればこの件の修正が入ってくれると
> 嬉しいです。

うっかりしてる間にcode freezeしてしまいましたが、これはどうしま
しょうか。まぁ、回避できないのはdynamic loadingのない環境で特定
の拡張ライブラリを使いたいときくらいだけなので、もう〆切ならしょ
うがないかなという気もしますが。

ちなみに、以前のパッチではちゃんとLoadErrorが上がっていなかった
ので修正版。


Index: eval.c
===================================================================
--- eval.c	(revision 11758)
+++ eval.c	(working copy)
@@ -6929,5 +6929,14 @@ static st_table *loading_tbl;
 #endif
 
-static char *
+
+static const char *const loadable_ext[] = {
+    ".rb", DLEXT,
+#ifdef DLEXT2
+    DLEXT2,
+#endif
+    0
+};
+
+static int
 rb_feature_p(feature, ext, rb)
     const char *feature, *ext;
@@ -6935,5 +6944,5 @@ rb_feature_p(feature, ext, rb)
 {
     VALUE v;
-    char *f, *e;
+    const char *f, *e;
     long i, len, elen;
 
@@ -6946,18 +6955,38 @@ rb_feature_p(feature, ext, rb)
 	elen = 0;
     }
-    for (i = 0; i < RARRAY(rb_features)->len; ++i) {
-	v = RARRAY(rb_features)->ptr[i];
+    for (i = 0; i < RARRAY_LEN(rb_features); ++i) {
+	v = RARRAY_PTR(rb_features)[i];
 	f = StringValuePtr(v);
-	if (strncmp(f, feature, len) != 0) continue;
+	if (RSTRING_LEN(v) < len || strncmp(f, feature, len) != 0)
+	    continue;
 	if (!*(e = f + len)) {
 	    if (ext) continue;
-	    return e;
+	    return 'u';
 	}
 	if (*e != '.') continue;
 	if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {
-	    return e;
+	    return 's';
 	}
 	if ((rb || !ext) && (strcmp(e, ".rb") == 0)) {
-	    return e;
+	    return 'r';
+	}
+    }
+    if (loading_tbl) {
+	if (st_lookup(loading_tbl, (st_data_t)feature, 0)) {
+	    if (ext) return 'u';
+	    return strcmp(ext, ".rb") ? 's' : 'r';
+	}
+	else {
+	    char *buf;
+
+	    if (ext) return 0;
+	    buf = ALLOCA_N(char, len + DLEXT_MAXLEN + 1);
+	    strcpy(buf, feature);
+	    for (i = 0; (e = loadable_ext[i]) != 0; i++) {
+		strncpy(buf + len, e, DLEXT_MAXLEN + 1);
+		if (st_lookup(loading_tbl, (st_data_t)buf, 0)) {
+		    return i ? 's' : 'r';
+		}
+	    }
 	}
     }
@@ -6965,11 +6994,5 @@ rb_feature_p(feature, ext, rb)
 }
 
-static const char *const loadable_ext[] = {
-    ".rb", DLEXT,
-#ifdef DLEXT2
-    DLEXT2,
-#endif
-    0
-};
+static int search_required(VALUE, VALUE *, VALUE *);
 
 int
@@ -6977,17 +7000,12 @@ rb_provided(feature)
     const char *feature;
 {
-    int i;
-    char *buf;
+    VALUE fname, path;
 
     if (rb_feature_p(feature, 0, Qfalse))
 	return Qtrue;
-    if (!loading_tbl) return Qfalse;
-    if (st_lookup(loading_tbl, (st_data_t)feature, 0)) return Qtrue;
-    buf = ALLOCA_N(char, strlen(feature)+8);
-    strcpy(buf, feature);
-    for (i=0; ; i++) {
-	if (!loadable_ext[i]) break;
-	strcpy(buf+strlen(feature), loadable_ext[i]);
-	if (st_lookup(loading_tbl, (st_data_t)buf, 0)) return Qtrue;
+    if (search_required(rb_str_new2(feature), &fname, &path) != 0) {
+	feature = RSTRING_PTR(fname);
+	if (rb_feature_p(feature, strrchr(feature, '.'), Qfalse))
+	    return Qtrue;
     }
     return Qfalse;
@@ -7008,17 +7026,39 @@ rb_provide(feature)
 }
 
-static int
-load_wait(ftptr)
-    char *ftptr;
+static char *
+load_lock(ftptr)
+    const char *ftptr;
 {
     st_data_t th;
 
-    if (!loading_tbl) return Qfalse;
-    if (!st_lookup(loading_tbl, (st_data_t)ftptr, &th)) return Qfalse;
+    if (!loading_tbl ||
+	!st_lookup(loading_tbl, (st_data_t)ftptr, &th))
+    {
+	/* loading ruby library should be serialized. */
+	if (!loading_tbl) {
+	    loading_tbl = st_init_strtable();
+	}
+	/* partial state */
+	ftptr = ruby_strdup(ftptr);
+	st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)curr_thread);
+	return (char *)ftptr;
+    }
     do {
-	if ((rb_thread_t)th == curr_thread) return Qtrue;
+	if ((rb_thread_t)th == curr_thread) return 0;
 	CHECK_INTS;
     } while (st_lookup(loading_tbl, (st_data_t)ftptr, &th));
-    return Qtrue;
+    return 0;
+}
+
+static void
+load_unlock(const char *ftptr)
+{
+    if (ftptr) {
+	st_data_t key = (st_data_t)ftptr;
+	
+	if (st_delete(loading_tbl, &key, 0)) {
+	    free((char *)key);
+	}
+    }
 }
 
@@ -7062,14 +7102,14 @@ search_required(fname, featurep, path)
     *featurep = fname;
     *path = 0;
-    ext = strrchr(ftptr = RSTRING(fname)->ptr, '.');
+    ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
     if (ext && !strchr(ext, '/')) {
 	if (strcmp(".rb", ext) == 0) {
 	    if (rb_feature_p(ftptr, ext, Qtrue)) return 'r';
-	    if (*path = rb_find_file(fname)) return 'r';
+	    if ((*path = rb_find_file(fname)) != 0) return 'r';
 	    return 0;
 	}
 	else if (IS_SOEXT(ext)) {
 	    if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
-	    tmp = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
+	    tmp = rb_str_new(RSTRING_PTR(fname), ext-RSTRING_PTR(fname));
 	    *featurep = tmp;
 #ifdef DLEXT2
@@ -7090,18 +7130,16 @@ search_required(fname, featurep, path)
 	else if (IS_DLEXT(ext)) {
 	    if (rb_feature_p(ftptr, ext, Qfalse)) return 's';
-	    if (*path = rb_find_file(fname)) return 's';
+	    if ((*path = rb_find_file(fname)) != 0) return 's';
 	}
     }
     tmp = fname;
-    switch (type = rb_find_file_ext(&tmp, loadable_ext)) {
+    type = rb_find_file_ext(&tmp, loadable_ext);
+    *featurep = tmp;
+    switch (type) {
       case 0:
-	if ((ext = rb_feature_p(ftptr, 0, Qfalse))) {
-	    type = strcmp(".rb", ext);
-	    break;
-	}
-	return 0;
+	ftptr = RSTRING_PTR(tmp);
+	return rb_feature_p(ftptr, 0, Qfalse);
 
       default:
-	*featurep = tmp;
 	ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');
 	if (rb_feature_p(ftptr, ext, !--type)) break;
@@ -7151,16 +7189,9 @@ rb_require_safe(fname, safe)
 	found = search_required(fname, &feature, &path);
 	if (found) {
-	    if (!path || load_wait(RSTRING(feature)->ptr)) {
+	    if (!path || !(ftptr = load_lock(RSTRING_PTR(feature)))) {
 		result = Qfalse;
 	    }
 	    else {
 		ruby_safe_level = 0;
-		/* loading ruby library should be serialized. */
-		if (!loading_tbl) {
-		    loading_tbl = st_init_strtable();
-		}
-		/* partial state */
-		ftptr = ruby_strdup(RSTRING_PTR(feature));
-		st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)curr_thread);
 		switch (found) {
 		  case 'r':
@@ -7189,9 +7220,5 @@ rb_require_safe(fname, safe)
     SCOPE_SET(saved.vmode);
     ruby_safe_level = saved.safe;
-    if (ftptr) {
-	if (st_delete(loading_tbl, (st_data_t *)&ftptr, 0)) { /* loading done */
-	    free(ftptr);
-	}
-    }
+    load_unlock(ftptr);
     if (state) JUMP_TAG(state);
     if (NIL_P(result)) {
@@ -7212,4 +7239,22 @@ rb_require(fname)
 }
 
+void
+ruby_init_ext(name, init)
+    const char *name;
+    void (*init) _((void));
+{
+    ruby_current_node = 0;
+    ruby_sourcefile = rb_source_filename(name);
+    ruby_sourceline = 0;
+    ruby_frame->last_func = 0;
+    ruby_frame->orig_func = 0;
+    SCOPE_SET(SCOPE_PUBLIC);
+    if (load_lock(name)) {
+	(*init)();
+	rb_provide(name);
+	load_unlock(name);
+    }
+}
+
 static void
 secure_visibility(self)


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread