Autoloading static linked extension

e$B$J$+$@$G$9!#e(B

http://moonrock.jp/~don/d/200612.html#d08_t2 e$B$N7o$G$9$,!"e(B
Init_ext()e$B$G$Oe(Bloading_tble$B$KF~$i$J$$$N$,860x$G$9!#e(B

e$B$H$j$"$($:e(B[ruby-dev:29523]e$B$N:]$K:n$C$?%Q%C%A$G$9!#e(Bext/extmk.rb
e$B$Oe(B1.8e$B$b6&DL!#e(B

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

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:30023] autoloading static linked extension”
on Mon, 18 Dec 2006 23:46:23 +0900, Nobuyoshi N.
[email protected] writes:

|http://moonrock.jp/~don/d/200612.html#d08_t2 e$B$N7o$G$9$,!“e(B
|Init_ext()e$B$G$Oe(Bloading_tble$B$KF~$i$J$$$N$,860x$G$9!#e(B
|
|e$B$H$j$”$($:e(B[ruby-dev:29523]e$B$N:]$K:n$C$?%Q%C%A$G$9!#e(Bext/extmk.rb
|e$B$Oe(B1.8e$B$b6&DL!#e(B

e$B@5D>!“;W$C$?$h$jBg$-$/$FCf?H$rA4ItM}2r$7$?$H$OCG8@$G$-$J$$$Ne(B
e$B$G$9$,!”$H$j$"$($:?.$8$^$9!#%3%_%C%H$7$F$b$i$($^$;$s$+!#e(BHEAD
e$B$K!#e(Bknue$B$5$s$,!V$&$s!W$H8@$($Pe(B1_8e$B$K$b!#e(B

At Tue, 19 Dec 2006 00:14:15 +0900,
matz wrote:

e$B@5D>!“;W$C$?$h$jBg$-$/$FCf?H$rA4ItM}2r$7$?$H$OCG8@$G$-$J$$$Ne(B
e$B$G$9$,!”$H$j$"$($:?.$8$^$9!#%3%_%C%H$7$F$b$i$($^$;$s$+!#e(BHEAD
e$B$K!#e(Bknue$B$5$s$,!V$&$s!W$H8@$($Pe(B1_8e$B$K$b!#e(B

e$B!!e(Brb_provided() e$B$Ne(B if e$B%V%m%C%/$O3g8L$,H4$1$F$$$^$9$+!)e(B

e$B!!e(B1.8
e$B$K$D$$$F$O<j85$G%F%9%H$7$?$$$N$GJLES%C%A$r$*4j$$$7$^$9!#e(B


/
/__ __ Akinori.org / MUSHA.org
/ ) ) ) ) / FreeBSD.org / Ruby-lang.org
Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp

“Different eyes see different things,
Different hearts beat on different strings –
But there are times for you and me when all such things agree”

e$B$J$+$@$G$9!#e(B

At Tue, 19 Dec 2006 07:43:02 +0900,
Akinori MUSHA wrote in [ruby-dev:30027]:

e$B!!e(Brb_provided() e$B$Ne(B if e$B%V%m%C%/$O3g8L$,H4$1$F$$$^$9$+!)e(B

e$B$9$$$^$;$s!"H4$1$F$k$H$$$&$+!"D>$7$+$1$@$C$?$h$&$G$9!#e(B

e$B!!e(B1.8 e$B$K$D$$$F$O<j85$G%F%9%H$7$?$$$N$GJLES%C%A$r$*4j$$$7$^$9!#e(B

e$B$3$l$G$I$&$G$7$g$&$+!#e(B

Index: eval.c

RCS file: /pub/cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.616.2.200
diff -U 2 -p -r1.616.2.200 eval.c
— eval.c 9 Dec 2006 12:40:17 -0000 1.616.2.200
+++ eval.c 19 Dec 2006 15:51:06 -0000
@@ -6930,5 +6930,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;
@@ -6936,5 +6945,5 @@ rb_feature_p(feature, ext, rb)
{
VALUE v;

  • char *f, *e;
  • const char *f, *e;
    long i, len, elen;

@@ -6947,30 +6956,42 @@ 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) {
  • 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 *, VALUE *);

int
@@ -6978,17 +6999,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;
    @@ -7009,17 +7025,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);
    
  • }
  • }
    }

@@ -7063,14 +7101,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
@@ -7091,18 +7129,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;
    @@ -7152,16 +7188,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':
    

@@ -7190,9 +7219,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)) {
    @@ -7213,4 +7238,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)
Index: ext/extmk.rb

RCS file: /pub/cvs/ruby/src/ruby/ext/extmk.rb,v
retrieving revision 1.44.2.37
diff -U 2 -p -r1.44.2.37 extmk.rb
— ext/extmk.rb 19 Oct 2006 16:03:45 -0000 1.44.2.37
+++ ext/extmk.rb 19 Dec 2006 15:54: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