[#30060] merge YARV — SASADA Koichi <ko1@...>

Hi,

20 messages 2006/12/31
[#30061] Re: merge YARV — SASADA Koichi <ko1@...> 2006/12/31

 ささだです。

[ruby-dev:30023] autoloading static linked extension

From: Nobuyoshi Nakada <nobu@...>
Date: 2006-12-18 14:46:23 UTC
List: ruby-dev #30023
なかだです。

http://moonrock.jp/~don/d/200612.html#d08_t2 の件ですが、
Init_ext()ではloading_tblに入らないのが原因です。

とりあえず[ruby-dev:29523]の際に作ったパッチです。ext/extmk.rb
は1.8も共通。


Index: eval.c
===================================================================
RCS file: /pub/cvs/ruby/eval.c,v
retrieving revision 1.616.2.194
diff -U 2 -p -r1.616.2.194 eval.c
--- eval.c	10 Sep 2006 00:18:39 -0000	1.616.2.194
+++ eval.c	13 Sep 2006 02:05:31 -0000
@@ -6927,5 +6927,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;
@@ -6933,5 +6942,5 @@ rb_feature_p(feature, ext, rb)
 {
     VALUE v;
-    char *f, *e;
+    const char *f, *e;
     long i, len, elen;
 
@@ -6947,5 +6956,6 @@ rb_feature_p(feature, ext, rb)
 	v = RARRAY(rb_features)->ptr[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;
@@ -6960,32 +6970,32 @@ rb_feature_p(feature, ext, rb)
 	}
     }
+    if (loading_tbl) {
+	e = ext;
+	if (!st_lookup(loading_tbl, (st_data_t)feature, 0)) {
+	    char *buf;
+
+	    if (ext) return 0;
+	    buf = ALLOCA_N(char, len+8);
+	    strcpy(buf, feature);
+	    for (i = 0; (e = loadable_ext[i]) != 0; i++) {
+		strcpy(buf + len, loadable_ext[i]);
+		if (st_lookup(loading_tbl, (st_data_t)buf, 0)) {
+		    break;
+		}
+	    }
+	}
+	return !e ? 'u' : strcmp(e, ".rb") ? 's' : 'r';
+    }
     return 0;
 }
 
-static const char *const loadable_ext[] = {
-    ".rb", DLEXT,
-#ifdef DLEXT2
-    DLEXT2,
-#endif
-    0
-};
-
 int
 rb_provided(feature)
     const char *feature;
 {
-    int i;
-    char *buf;
+    int c;
 
     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;
     }
     return Qfalse;
@@ -7006,17 +7016,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);
+	}
+    }
 }
 
@@ -7149,16 +7181,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':
@@ -7187,9 +7212,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)) {
@@ -7210,4 +7231,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->callee = 0;
+    ruby_frame->this_func = 0;
+    VIS_SET(VIS_PUBLIC);
+    if (load_lock(name)) {
+	(*init)();
+	rb_provide(name);
+	load_unlock(name);
+    }
+}
+
 static void
 secure_visibility(self)

Index: eval.c
===================================================================
RCS file: /pub/cvs/ruby/eval.c,v
retrieving revision 1.946
diff -U 2 -p -r1.946 eval.c
--- eval.c	18 Sep 2006 01:58:59 -0000	1.946
+++ eval.c	19 Sep 2006 04:55:21 -0000
@@ -6821,9 +6821,18 @@ static st_table *loading_tbl;
 #endif
 
+
+static const char *const loadable_ext[] = {
+    ".rb", DLEXT,
+#ifdef DLEXT2
+    DLEXT2,
+#endif
+    0
+};
+
 static int
 rb_feature_p(const char *feature, const char *ext, int rb)
 {
     VALUE v;
-    char *f, *e;
+    const char *f, *e;
     long i, len, elen;
 
@@ -6839,5 +6848,6 @@ rb_feature_p(const char *feature, const 
 	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;
@@ -6852,15 +6862,24 @@ rb_feature_p(const char *feature, const 
 	}
     }
+    if (loading_tbl) {
+	e = ext;
+	if (!st_lookup(loading_tbl, (st_data_t)feature, 0)) {
+	    char *buf;
+
+	    if (ext) return 0;
+	    buf = ALLOCA_N(char, len+8);
+	    strcpy(buf, feature);
+	    for (i = 0; (e = loadable_ext[i]) != 0; i++) {
+		strcpy(buf + len, loadable_ext[i]);
+		if (st_lookup(loading_tbl, (st_data_t)buf, 0)) {
+		    break;
+		}
+	    }
+	}
+	return !e ? 'u' : strcmp(e, ".rb") ? 's' : 'r';
+    }
     return 0;
 }
 
-static const char *const loadable_ext[] = {
-    ".rb", DLEXT,
-#ifdef DLEXT2
-    DLEXT2,
-#endif
-    0
-};
-
 static int search_required(VALUE, VALUE *);
 
@@ -6868,24 +6887,12 @@ int
 rb_provided(const char *feature)
 {
-    int i;
-    char *buf;
+    int c;
     VALUE fname;
 
     if (rb_feature_p(feature, 0, Qfalse))
 	return Qtrue;
-    if (loading_tbl) {
-	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; loadable_ext[i]; i++) {
-	    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)) {
+    if ((c = search_required(rb_str_new2(feature), &fname)) != 0) {
 	feature = RSTRING_PTR(fname);
-	if (rb_feature_p(feature, 0, Qfalse))
-	    return Qtrue;
-	if (loading_tbl && st_lookup(loading_tbl, (st_data_t)feature, 0))
+	if (rb_feature_p(feature, c ? strrchr(feature, '.') : 0, Qfalse))
 	    return Qtrue;
     }
@@ -6905,16 +6912,38 @@ rb_provide(const char *feature)
 }
 
-static int
-load_wait(char *ftptr)
+static char *
+load_lock(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);
+	}
+    }
 }
 
@@ -7063,5 +7092,5 @@ rb_require_safe(VALUE fname, int safe)
 	found = search_required(fname, &path);
 	if (found) {
-	    if (!path || load_wait(RSTRING_PTR(path))) {
+	    if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
 		result = Qfalse;
 	    }
@@ -7105,9 +7134,5 @@ rb_require_safe(VALUE fname, int safe)
     POP_CREF();
     POP_SCOPE();
-    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)) {
@@ -7127,4 +7152,20 @@ rb_require(const char *fname)
 }
 
+void
+ruby_init_ext(const char *name, void (*init)(void))
+{
+    ruby_current_node = 0;
+    ruby_sourcefile = rb_source_filename(name);
+    ruby_sourceline = 0;
+    ruby_frame->callee = 0;
+    ruby_frame->this_func = 0;
+    VIS_SET(VIS_PUBLIC);
+    if (load_lock(name)) {
+	(*init)();
+	rb_provide(name);
+	load_unlock(name);
+    }
+}
+
 static void
 secure_visibility(VALUE self)

Index: ext/extmk.rb
===================================================================
RCS file: /pub/cvs/ruby/ext/extmk.rb,v
retrieving revision 1.101
diff -U 2 -p -r1.101 extmk.rb
--- ext/extmk.rb	16 Sep 2006 07:06:36 -0000	1.101
+++ ext/extmk.rb	19 Sep 2006 04:55:28 -0000
@@ -452,12 +452,9 @@ unless $extlist.empty?
 #include "ruby.h"
 
-#define init(func, name) {				\
-    void func _((void));				\
-    ruby_sourcefile = src = rb_source_filename(name);	\
-    func();						\
-    rb_provide(src);					\
-}
+#define init(func, name) {void func _((void)); ruby_init_ext(name, func);}
+
+void ruby_init_ext _((const char *name, void (*init)(void)));
 
-void Init_ext _((void))\n{\n    char *src;#$extinit}
+void Init_ext _((void))\n{\n#$extinit}
 }
   if !modified?(extinit.c, MTIMES) || IO.read(extinit.c) != src


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

In This Thread

Prev Next