Yukihiro Matsumoto wrote: > Interesting. That's my cue! *hacks away some more* > Probably. If you will come up with the solution, I will consider it > to be merged. I'm too busy these days to provide the solution by > myself. Sorry. Not a finished solution yet, but I have something that does seem to work. It hasn't been tested much, but here are the diffs I have so far, just in case someone else want this. (These are diffs towards the 1.6.5 release) -------8<----------- [ cut here ] -------8<----------- *** ../../ruby-1.6.5/eval.c Mon Sep 17 23:47:02 2001 --- eval.c Fri Dec 7 19:55:14 2001 *************** *** 5266,5271 **** --- 5266,5330 ---- static VALUE rb_features; static st_table *loading_tbl; + /* deferred static extension initialization hack */ + static VALUE rb_static_ext_hash; + static VALUE rb_mStaticExt, rb_cStaticExt; + typedef struct { + char * filename; + int required; + void (*initfunc)(void); + } rb_static_ext_entry; + + void rb_static_ext_register( fname, initfunc ) + char * fname ; + void (*initfunc)(void) ; + { + rb_static_ext_entry *p; + VALUE key, entry; + + /* register a static extension in our map */ + p = ALLOC( rb_static_ext_entry ); + p->filename = fname; + p->initfunc = initfunc; + p->required = 0; + key = rb_str_new2( fname ); + entry = Data_Wrap_Struct( rb_cStaticExt, 0,free, p ); + rb_hash_aset( rb_static_ext_hash, key, entry ); + } + + + int rb_static_ext_require( VALUE string ) + { + VALUE ext; + rb_static_ext_entry *p; + + ext = rb_hash_aref( rb_static_ext_hash, string ); + if( NIL_P(ext) ) + return -1; + + p = NULL; + Data_Get_Struct( ext, rb_static_ext_entry, p ); + if( p ){ + if( ! p->required ){ + /* we found the given string, and it isn't already required */ + p->required = 1; + (*(p->initfunc))(); + rb_provide( p->filename ); + return 1; + } + else + { + /* already required */ + return 0; + }; + }; + /* not found in our static_ext hash, please don't mind us */ + return -1; + } + + + + static int rb_feature_p(feature, wait) const char *feature; *************** *** 5356,5361 **** --- 5415,5421 ---- volatile VALUE load; int state; volatile int safe = ruby_safe_level; + int resultcode; Check_SafeStr(fname); ext = strrchr(RSTRING(fname)->ptr, '.'); *************** *** 5369,5374 **** --- 5429,5439 ---- } } else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) { + resultcode = rb_static_ext_require( fname ); + if( resultcode >= 0 ){ + return ( resultcode ? Qtrue : Qfalse ); + } + fname = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr); #ifdef DLEXT2 tmp = fname; *************** *** 6008,6013 **** --- 6073,6084 ---- rb_features = rb_ary_new(); rb_define_readonly_variable("$\"", &rb_features); + + // deferred static extension initialization stuff + rb_static_ext_hash = rb_hash_new(); + rb_mStaticExt = rb_define_module("StaticExt"); + rb_cStaticExt = rb_define_class_under( rb_mStaticExt, "Extention", + rb_cObject ); rb_define_global_function("load", rb_f_load, -1); rb_define_global_function("require", rb_f_require, 1); -------8<----------- [ cut here ] -------8<----------- *** ../../ruby-1.6.5/ext/extmk.rb.in Fri Jul 27 04:52:19 2001 --- ext/extmk.rb.in Fri Dec 7 19:10:02 2001 *************** *** 720,725 **** --- 720,726 ---- exit end $extinit = "" unless $extinit + $extdefinitions = "" unless $extdefinitions ruby = "@RUBY_INSTALL_NAME@@EXEEXT@" miniruby = "miniruby@EXEEXT@" *************** *** 729,738 **** for s,t in $extlist f = format("%s/%s.%s", s, t, $LIBEXT) if File.exist?(f) ! $extinit += format("\ ! \tInit_%s();\n\ ! \trb_provide(\"%s.so\");\n\ ! ", t, s) $extobjs += "ext/" $extobjs += f $extobjs += " " --- 730,743 ---- for s,t in $extlist f = format("%s/%s.%s", s, t, $LIBEXT) if File.exist?(f) ! #$extinit += format("\ ! #\tInit_%s();\n\ ! #\trb_provide(\"%s.so\");\n\ ! #", t, s) ! ! $extinit +=format("\trb_static_ext_register( \"%s.so\", &Init_%s );\n",s,t) ! ! $extdefinitions += format("void Init_%s(void);\n", t) $extobjs += "ext/" $extobjs += f $extobjs += " " *************** *** 743,748 **** --- 748,754 ---- if older("extinit.c", "#{$top_srcdir}/ext/@setup@") f = open("extinit.c", "w") + f.printf $extdefinitions f.printf "void Init_ext() {\n" f.printf $extinit f.printf "}\n" -------8<----------- [ cut here ] -------8<----------- I had some changes in intern.h too, but it compiled without that, so I left it out. -- <[ Kent Dahl ]>================<[ http://www.stud.ntnu.no/~kentda/ ]> )____(stud.techn.;ind.шл.data)||(softwareDeveloper.at(Trustix))_( /"Opinions expressed are mine and not those of my Employer, "\ ( "the University, my girlfriend, stray cats, banana fruitflies, " ) \"nor the frontal lobe of my left cerebral hemisphere. "/