Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jitdynamic/jit-cpp-mangle.c view on Meta::CPAN
@cindex Name mangling
Sometimes you want to retrieve a C++ method from a dynamic library
using @code{jit_dynlib_get_symbol}. Unfortunately, C++ name mangling
rules differ from one system to another, making this process very
error-prone.
The functions that follow try to help. They aren't necessarily fool-proof,
but they should work in the most common cases. The only alternative is
to wrap your C++ library with C functions, so that the names are predictable.
The basic idea is that you supply a description of the C++ method that
you wish to access, and these functions return a number of candidate forms
that you can try with @code{jit_dynlib_get_symbol}. If one form fails,
you move on and try the next form, until either symbol lookup succeeds
or until all forms have been exhausted.
@noindent
The following code demonstrates how to resolve a global function:
@example
jit_dynlib_handle_t handle;
jit_type_t signature;
int form = 0;
void *address = 0;
char *mangled;
while((mangled = jit_mangle_global_function
("foo", signature, form)) != 0)
@{
address = jit_dynlib_get_symbol(handle, mangled);
if(address != 0)
@{
break;
@}
jit_free(mangled);
++form;
@}
if(address)
@{
printf("%s = 0x%lx\n", mangled, (long)address);
@}
else
@{
printf("could not resolve foo\n");
@}
@end example
This mechanism typically cannot be used to obtain the entry points for
@code{inline} methods. You will need to make other arrangements to
simulate the behaviour of inline methods, or recompile your dynamic C++
library in a mode that explicitly exports inlines.
C++ method names are very picky about types. On 32-bit systems,
@code{int} and @code{long} are the same size, but they are mangled
to different characters. To ensure that the correct function is
picked, you should use @code{jit_type_sys_int}, @code{jit_type_sys_long}, etc
instead of the platform independent types. If you do use a platform
independent type like @code{jit_type_int}, this library will try to
guess which system type you mean, but the guess will most likely be wrong.
@*/
/*
* Useful encoding characters.
*/
static char const hexchars[16] = "0123456789ABCDEF";
static char const b36chars[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/*
* Name mangling output context.
*/
typedef struct jit_mangler *jit_mangler_t;
struct jit_mangler
{
char *buf;
unsigned int buf_len;
unsigned int buf_max;
int out_of_memory;
char **names;
unsigned int num_names;
unsigned int max_names;
};
/*
* Initialize a mangling context.
*/
static void init_mangler(jit_mangler_t mangler)
{
mangler->buf = 0;
mangler->buf_len = 0;
mangler->buf_max = 0;
mangler->out_of_memory = 0;
mangler->names = 0;
mangler->num_names = 0;
mangler->max_names = 0;
}
/*
* End a mangling operation, and return the final string.
*/
static char *end_mangler(jit_mangler_t mangler)
{
unsigned int index;
for(index = 0; index < mangler->num_names; ++index)
{
jit_free(mangler->names[index]);
}
jit_free(mangler->names);
if(!(mangler->buf) || mangler->out_of_memory)
{
jit_free(mangler->buf);
return 0;
}
return mangler->buf;
}
/*
* Add a character to a mangling buffer.
*/
( run in 0.772 second using v1.01-cache-2.11-cpan-39bf76dae61 )