Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/jit/jit-function.c  view on Meta::CPAN

	}
	else
	{
		return 0;
	}
}

/*
 * Information that is stored for an exception region in the cache.
 */
typedef struct jit_cache_eh *jit_cache_eh_t;
struct jit_cache_eh
{
	jit_label_t		handler_label;
	unsigned char  *handler;
	jit_cache_eh_t	previous;
};

/*@
 * @deftypefun int jit_function_is_compiled (jit_function_t @var{func})
 * Determine if a function has already been compiled.
 * @end deftypefun
@*/
int jit_function_is_compiled(jit_function_t func)
{
	if(func)
	{
		return func->is_compiled;
	}
	else
	{
		return 0;
	}
}

/*@
 * @deftypefun int jit_function_set_recompilable (jit_function_t @var{func})
 * Mark this function as a candidate for recompilation.  That is,
 * it is possible that we may call @code{jit_function_compile}
 * more than once, to re-optimize an existing function.
 *
 * It is very important that this be called before the first time that
 * you call @code{jit_function_compile}.  Functions that are recompilable
 * are invoked in a slightly different way to non-recompilable functions.
 * If you don't set this flag, then existing invocations of the function
 * may continue to be sent to the original compiled version, not the new
 * version.
 * @end deftypefun
@*/
void jit_function_set_recompilable(jit_function_t func)
{
	if(func)
	{
		func->is_recompilable = 1;
	}
}

/*@
 * @deftypefun void jit_function_clear_recompilable (jit_function_t @var{func})
 * Clear the recompilable flag on this function.  Normally you would use
 * this once you have decided that the function has been optimized enough,
 * and that you no longer intend to call @code{jit_function_compile} again.
 *
 * Future uses of the function with @code{jit_insn_call} will output a
 * direct call to the function, which is more efficient than calling
 * its recompilable version.  Pre-existing calls to the function may still
 * use redirection stubs, and will remain so until the pre-existing
 * functions are themselves recompiled.
 * @end deftypefun
@*/
void jit_function_clear_recompilable(jit_function_t func)
{
	if(func)
	{
		func->is_recompilable = 0;
	}
}

/*@
 * @deftypefun int jit_function_is_recompilable (jit_function_t @var{func})
 * Determine if this function is recompilable.
 * @end deftypefun
@*/
int jit_function_is_recompilable(jit_function_t func)
{
	if(func)
	{
		return func->is_recompilable;
	}
	else
	{
		return 0;
	}
}

#ifdef JIT_BACKEND_INTERP

/*
 * Closure handling function for "jit_function_to_closure".
 */
static void function_closure(jit_type_t signature, void *result,
							 void **args, void *user_data)
{
	if(!jit_function_apply((jit_function_t)user_data, args, result))
	{
		/* We cannot report the exception through the closure,
		   so we have no choice but to rethrow it up the stack */
		jit_exception_throw(jit_exception_get_last());
	}
}

#endif /* JIT_BACKEND_INTERP */

/*@
 * @deftypefun {void *} jit_function_to_closure (jit_function_t @var{func})
 * Convert a compiled function into a closure that can called directly
 * from C.  Returns NULL if out of memory, or if closures are not
 * supported on this platform.
 *
 * If the function has not been compiled yet, then this will return
 * a pointer to a redirector that will arrange for the function to be

libjit/jit/jit-function.c  view on Meta::CPAN

 * the instructions in the function's body.  It should return one of the
 * result codes @code{JIT_RESULT_OK}, @code{JIT_RESULT_COMPILE_ERROR},
 * or @code{JIT_RESULT_OUT_OF_MEMORY}.
 *
 * @item
 * If the user's on-demand function hasn't already done so, @code{libjit}
 * will call @code{jit_function_compile} to compile the function.
 *
 * @item
 * The context is unlocked by calling @code{jit_context_build_end} and
 * @code{libjit} jumps to the newly-compiled entry point.  If an error
 * occurs, a built-in exception of type @code{JIT_RESULT_COMPILE_ERROR}
 * or @code{JIT_RESULT_OUT_OF_MEMORY} will be thrown.
 * @end enumerate
 *
 * Normally you will need some kind of context information to tell you
 * which higher-level construct is being compiled.  You can use the
 * metadata facility to add this context information to the function
 * just after you create it with @code{jit_function_create}.
 * @end deftypefun
@*/
void
jit_function_set_on_demand_compiler(jit_function_t func, jit_on_demand_func on_demand)
{
	if(func)
	{
		func->on_demand = on_demand;
	}
}

/*@
 * @deftypefun jit_on_demand_func jit_function_get_on_demand_compiler (jit_function_t @var{func})
 * Returns function's on-demand compiler.
 * @end deftypefun
@*/
jit_on_demand_func
jit_function_get_on_demand_compiler(jit_function_t func)
{
	if(func)
	{
		return func->on_demand;
	}
	return 0;
}

/*@
 * @deftypefun int jit_function_apply (jit_function_t @var{func}, void **@var{args}, void *@var{return_area})
 * Call the function @var{func} with the supplied arguments.  Each element
 * in @var{args} is a pointer to one of the arguments, and @var{return_area}
 * points to a buffer to receive the return value.  Returns zero if an
 * exception occurred.
 *
 * This is the primary means for executing a function from ordinary
 * C code without creating a closure first with @code{jit_function_to_closure}.
 * Closures may not be supported on all platforms, but function application
 * is guaranteed to be supported everywhere.
 *
 * Function applications acts as an exception blocker.  If any exceptions
 * occur during the execution of @var{func}, they won't travel up the
 * stack any further than this point.  This prevents ordinary C code
 * from being accidentally presented with a situation that it cannot handle.
 * This blocking protection is not present when a function is invoked
 * via its closure.
 * @end deftypefun
 *
 * @deftypefun int jit_function_apply_vararg (jit_function_t @var{func}, jit_type_t @var{signature}, void **@var{args}, void *@var{return_area})
 * Call the function @var{func} with the supplied arguments.  There may
 * be more arguments than are specified in the function's original signature,
 * in which case the additional values are passed as variable arguments.
 * This function is otherwise identical to @code{jit_function_apply}.
 * @end deftypefun
@*/
#if !defined(JIT_BACKEND_INTERP)
/* The interpreter version is in "jit-interp.cpp" */

int jit_function_apply(jit_function_t func, void **args, void *return_area)
{
	if(func)
	{
		return jit_function_apply_vararg
			(func, func->signature, args, return_area);
	}
	else
	{
		return jit_function_apply_vararg(func, 0, args, return_area);
	}
}

int jit_function_apply_vararg
	(jit_function_t func, jit_type_t signature, void **args, void *return_area)
{
	struct jit_backtrace call_trace;
	void *entry;
	jit_jmp_buf jbuf;

	/* Establish a "setjmp" point here so that we can unwind the
	   stack to this point when an exception occurs and then prevent
	   the exception from propagating further up the stack */
	_jit_unwind_push_setjmp(&jbuf);
	if(setjmp(jbuf.buf))
	{
		_jit_unwind_pop_setjmp();
		return 0;
	}

	/* Create a backtrace entry that blocks exceptions from
	   flowing further than this up the stack */
	_jit_backtrace_push(&call_trace, 0);

	/* Get the function's entry point */
	if(!func)
	{
		jit_exception_builtin(JIT_RESULT_NULL_FUNCTION);
		return 0;
	}
	if(func->nested_parent)
	{
		jit_exception_builtin(JIT_RESULT_CALLED_NESTED);
		return 0;
	}
	if(func->is_compiled)



( run in 0.991 second using v1.01-cache-2.11-cpan-524268b4103 )