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 )