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 )