#line 924 "lpsrc/flx_rtl.ipk"
#include "flx_dynlink.hpp"
#ifdef FLX_STATIC_LINK
extern "C" void *create_thread_frame;
extern "C" void *flx_start;
#endif
namespace flx { namespace rtl {
#ifdef MACOSX_NODLCOMPAT
void*
getmachosym(NSModule library, const char* symname)
{
NSSymbol sym = NSLookupSymbolInModule(library, symname);
if(sym)
return NSAddressOfSymbol(sym);
return 0;
}
#endif
flx_link_failure_t::flx_link_failure_t(string f, string o, string w) :
filename(f),
operation(o),
what(w)
{}
flx_link_failure_t::~flx_link_failure_t(){}
flx_dynlink_t::~flx_dynlink_t(){}
void flx_dynlink_t::link(char const *fname) throw(flx_link_failure_t)
{
filename=fname;
#ifndef FLX_STATIC_LINK
//#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32)
SetErrorMode(SEM_NOOPENFILEERRORBOX); // stop windows showing err dialogues
library = LoadLibrary(fname);
if(!library)
throw flx_link_failure_t(filename,"LoadLibrary","Cannot find dll");
#else
#ifdef MACOSX_NODLCOMPAT
NSObjectFileImage bndl_img;
NSObjectFileImageReturnCode res;
res = NSCreateObjectFileImageFromFile(fname, &bndl_img);
if(NSObjectFileImageSuccess != res)
throw flx_link_failure_t(filename, "NSCreateObjectFileImageFromFile",
"failure to open library");
// don't merge globals with loader's, load programmatically
// return on error allows us to continue without being terminated
unsigned long link_flags;
link_flags = NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR;
library = NSLinkModule(bndl_img, fname, link_flags);
// even if link failed, we do this
NSDestroyObjectFileImage(bndl_img);
// more info can be gleaned about link errors from NSLinkEditError
if(!library)
throw flx_link_failure_t(filename, "NSLinkModule", "failed to link");
#else
library = dlopen(fname,RTLD_NOW);
if(!library)
throw flx_link_failure_t(filename,"dlopen",dlerror());
#endif
#endif
#endif
//fprintf(stderr,"File %s dlopened at %p ok\n",fname,library);
thread_frame_creator = (thread_frame_creator_t)
DLSYM(library,create_thread_frame);
if(!thread_frame_creator)
throw flx_link_failure_t(filename,"dlsym","create_thread_frame");
//fprintf(stderr,"Thread frame creator found at %p\n",thread_frame_creator);
start_sym = (start_t)DLSYM(library,flx_start);
if(!start_sym)
throw flx_link_failure_t(filename,"dlsym","flx_start");
//fprintf(stderr,"Start symbol found at %p\n",start_sym);
refcnt = 1L;
//fprintf(stderr,"Set refcnt to 1\n");
try { usr_link(); }
catch (flx_link_failure_t &) { throw; }
catch (...) {
throw flx_link_failure_t
(
filename,
"usr_link()",
"Unknown user exception"
);
}
}
void flx_dynlink_t::unlink()
{
--refcnt;
if(refcnt == 0) {
//fprintf(stderr,"closing library\n");
#ifndef FLX_STATIC_LINK
//#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32)
FreeLibrary(library);
#else
#ifdef MACOSX_NODLCOMPAT
NSUnLinkModule(library, NSUNLINKMODULE_OPTION_NONE);
#else
dlclose(library);
#endif
#endif
#endif
}
}
void flx_dynlink_t::usr_link(){}
flx_libinit_t::~flx_libinit_t(){}
void flx_libinit_t::create
(
flx_dynlink_t *lib_a,
flx::gc::generic::collector_t *collector_a,
int argc,
char **argv,
FILE *stdin_,
FILE *stdout_,
FILE *stderr_
)
{
lib = lib_a;
collector = collector_a;
thread_frame = lib->thread_frame_creator(
collector
);
//fprintf(stderr,"Incrementing refcnt\n");
++lib->refcnt;
collector->add_root(thread_frame);
start_proc = lib->start_sym(thread_frame, argc, argv, stdin_,stdout_,stderr_);
usr_create();
}
void flx_libinit_t::usr_create(){}
void flx_libinit_t::destroy () {
usr_destroy();
collector->remove_root(thread_frame);
//fprintf(stderr,"Decrementing refcnt\n");
//fprintf(stderr,"Ref cnt=%ld\n",lib->refcnt);
--lib->refcnt;
//fprintf(stderr,"Ref cnt=%ld\n",lib->refcnt);
}
void flx_libinit_t::usr_destroy (){}
con_t *flx_libinit_t::bind_proc(void *fn, void *data) {
typedef con_t *(*binder_t)(void *,void*);
return ((binder_t)fn)(thread_frame,data);
}
}} // namespaces