Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-insn.c view on Meta::CPAN
return 0;
}
func->builder->current_block->ends_in_dead = 1;
return jit_insn_new_block(func);
}
/*@
* @deftypefun jit_value_t jit_insn_get_call_stack (jit_function_t @var{func})
* Get an object that represents the current position in the code,
* and all of the functions that are currently on the call stack.
* This is equivalent to calling @code{jit_exception_get_stack_trace},
* and is normally used just prior to @code{jit_insn_throw} to record
* the location of the exception that is being thrown.
* @end deftypefun
@*/
jit_value_t jit_insn_get_call_stack(jit_function_t func)
{
jit_type_t type;
jit_value_t value;
/* Create a signature prototype for "void *()" */
type = jit_type_create_signature
(jit_abi_cdecl, jit_type_void_ptr, 0, 0, 1);
if(!type)
{
return 0;
}
/* Call "jit_exception_get_stack_trace" to obtain the stack trace */
value = jit_insn_call_native
(func, "jit_exception_get_stack_trace",
(void *)jit_exception_get_stack_trace, type, 0, 0, 0);
/* Clean up and exit */
jit_type_free(type);
return value;
}
/*@
* @deftypefun jit_value_t jit_insn_thrown_exception (jit_function_t @var{func})
* Get the value that holds the most recent thrown exception. This is
* typically used in @code{catch} clauses.
* @end deftypefun
@*/
jit_value_t jit_insn_thrown_exception(jit_function_t func)
{
if(!_jit_function_ensure_builder(func))
{
return 0;
}
if(!(func->builder->thrown_exception))
{
func->builder->thrown_exception =
jit_value_create(func, jit_type_void_ptr);
}
return func->builder->thrown_exception;
}
/*
* Initialize the "setjmp" setup block that is needed to catch exceptions
* thrown back to this level of execution. The block looks like this:
*
* jit_jmp_buf jbuf;
* void *catcher;
*
* _jit_unwind_push_setjmp(&jbuf);
* if(setjmp(&jbuf.buf))
* {
* catch_pc = jbuf.catch_pc;
* if(catch_pc)
* {
* jbuf.catch_pc = 0;
* goto *catcher;
* }
* else
* {
* _jit_unwind_pop_and_rethrow();
* }
* }
*
* The field "jbuf.catch_pc" will be set to the address of the relevant
* "catch" block just before a subroutine call that may involve exceptions.
* It will be reset to NULL after such subroutine calls.
*
* Native back ends are responsible for outputting a call to the function
* "_jit_unwind_pop_setjmp()" just before "return" instructions if the
* "has_try" flag is set on the function.
*/
static int initialize_setjmp_block(jit_function_t func)
{
#if !defined(JIT_BACKEND_INTERP)
jit_label_t start_label = jit_label_undefined;
jit_label_t end_label = jit_label_undefined;
jit_label_t code_label = jit_label_undefined;
jit_label_t rethrow_label = jit_label_undefined;
jit_type_t type;
jit_value_t args[2];
jit_value_t value;
/* Bail out if we have already done this before */
if(func->builder->setjmp_value)
{
return 1;
}
func->builder->catcher_label = jit_label_undefined;
/* Force the start of a new block to mark the start of the init code */
if(!jit_insn_label(func, &start_label))
{
return 0;
}
/* Create a value to hold an item of type "jit_jmp_buf" */
type = jit_type_create_struct(0, 0, 1);
if(!type)
{
return 0;
}
jit_type_set_size_and_alignment
(type, sizeof(jit_jmp_buf), JIT_BEST_ALIGNMENT);
if((func->builder->setjmp_value = jit_value_create(func, type)) == 0)
( run in 0.764 second using v1.01-cache-2.11-cpan-524268b4103 )