Here is an example of registry based dynamic loading.
First, the plugin:

////////////////////////////////////
// test plugin thing
println "Hello Plugin tp init";
gen setup(x:string) : int = 
{
   println$ "Module tp setup with " + x;
   return 0;
}

proc entry() {
  println$ "Module tplug entry";
}

export fun setup of (string) as "tplug_setup";
export fun entry of (unit) as "tplug_entry";
////////////////////////////////

Now, to test the registry, I'm going to do an *ordinary* plugin load,
then I'm going to STEAL the antry points from it and add them to
the registry. Then I will load this artificially created module.
This is NOT static linking! But it shows what has to be done.

//////////////////////////////////
// First we do a dynamic load of the plugin.
// Note this is using lower level routines.


//////////////////////////  STANDARD DYNAMIC LOAD
var linst = Dynlink::init_lib("tplug");
println$ "tplug instance created";

var sresult = Dynlink::func1[int,string] (linst, "tplug_setup") ("tplug setup 
string");
C_hack::ignore (sresult);
var entry = Dynlink::proc0 (linst, "tplug_entry");
entry;
println$ "Plugin run";

////////////////// POPULATE REGISTRY

// Now, grab the entry points and make a module
// in the registry using them.

var lib = Dynlink::get_library linst;
var tfc = Dynlink::get_thread_frame_creator_as_address lib;
var star = Dynlink::get_start_as_address lib;
Dynlink::add_symbol ("silly","silly_create_thread_frame",tfc);
Dynlink::add_symbol ("silly","silly_flx_start",star);

var setup=Dynlink::raw_dlsym(lib,"tplug_setup");
var entrypoint =Dynlink::raw_dlsym(lib,"tplug_entry");
Dynlink::add_symbol("silly","silly_setup",setup);
Dynlink::add_symbol("silly","silly_entry",entrypoint);


///////////////////// RUN FROM REGISTRY
// And now try to run it.
var linst2 = Dynlink::init_lib("silly");
println$ "Silly instance created?";

var sresult2 = Dynlink::func1[int,string] (linst2, "silly_setup") ("silly setup 
string");
C_hack::ignore (sresult2);
var entry2 = Dynlink::proc0 (linst2, "silly_entry");
entry2;
println$ "Silly Plugin run";

//////////////////////////////
Hello Plugin tp init
tplug instance created
Module tp setup with tplug setup string
Module tplug entry
Plugin run
Hello Plugin tp init
Silly instance created?
Module tp setup with silly setup string
Module tplug entry
Silly Plugin run
////////////////////////////////////////

the important thing to note is that the code to run from DLL loaded from
the file system is *identical* to the code used to run code from the registry.

In otherwords, the use of the registry is **transparent** to the program.

The registry is stored in the garbage collector. There is only one (per
garbage collector!). (The current access is NOT thread safe! That will be 
fixed).

This has important consequences, in particular it allows HIJACKING.

For example consider an actual DLL like fdoc2html loaded by the
webserver. It loads flx2html, which loads cpp2html. If the webserver
"preloads" cpp2html, then flx2html will use the preloaded version
in the registry rather than loading an actual DLL. This will work
even if flx2html is dynamically loaded.


Now, for static linking what we need to do is conditionally include the Felix
code calling "add_symbol". It will get the machine addresses of statically
linked symbols from C using something like this:

        header fred = 'extern "C" void fred()';
        const fred:address = "(void*)fred";
        Dynlink::add_symbol ("somelib","fred",fred);

We can actually put this stuff in our programs inside a function,
and if we don't call that function it will just evaporate.
So all we need to arrange is to call that function if, and only if,
we're static linking. And of course we have to actually make the
plugin static link library available to "flx".

AFAIK there's no way to tell if one is static linking in Felix.
In C we know, because FLX_STATIC_LINK macro is set.

--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
Own the Future-Intel® Level Up Game Demo Contest 2013
Rise to greatness in Intel's independent game demo contest.
Compete for recognition, cash, and the chance to get your game 
on Steam. $5K grand prize plus 10 genre and skill prizes. 
Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to