#ifndef _JIT_INTERNAL_H
#define _JIT_INTERNAL_H
#include <jit/jit.h>
#include "jit-config.h"
#if defined(HAVE_STRING_H)
# include <string.h>
#elif defined(HAVE_STRINGS_H)
# include <strings.h>
#endif
#if defined(HAVE_MEMORY_H)
# include <memory.h>
#endif
#if defined(HAVE_MEMSET)
# define jit_memset(s, c, len) (memset((s), (c), (len)))
# define jit_memzero(s, len) (memset((s), 0, (len)))
#elif defined(HAVE_BZERO)
# define jit_memzero(s, len) (bzero((char *)(s), (len)))
#else
# define jit_memzero(s, len) (jit_memset((char *)(s), 0, (len)))
#endif
#if defined(HAVE_MEMCPY)
# define jit_memcpy(s1, s2, len) (memcpy((s1), (s2), (len)))
#endif
#if defined(HAVE_MEMMOVE)
# define jit_memmove(s1, s2, len) (memmove((s1), (s2), (len)))
#endif
#if defined(HAVE_MEMCMP)
# define jit_memcmp(s1, s2, len) (memcmp((s1), (s2), (len)))
#elif defined(HAVE_BCMP)
# define jit_memcmp(s1, s2, len) (bcmp((char *)(s1), (char *)(s2), (len)))
#endif
#if defined(HAVE_MEMCHR)
# define jit_memchr(s, c, len) (memchr((s), (c), (len)))
#endif
#include "jit-apply-func.h"
#include "jit-thread.h"
#include "jit-varint.h"
#ifdef __cplusplus
extern
"C"
{
#endif
#define _JIT_ALIGN_CHECK_TYPE(type,name) \
struct
_JIT_align_##name { \
jit_sbyte pad; \
type field; \
}
#define _JIT_ALIGN_FOR_TYPE(name) \
((jit_nuint)(&(((
struct
_JIT_align_##name *)0)->field)))
#define _JIT_ALIGN_MAX(a,b) \
((a) > (b) ? (a) : (b))
#define _JIT_ALIGN_MAX3(a,b,c) \
(_JIT_ALIGN_MAX((a), _JIT_ALIGN_MAX((b), (c))))
_JIT_ALIGN_CHECK_TYPE(jit_sbyte, sbyte);
_JIT_ALIGN_CHECK_TYPE(jit_short,
short
);
_JIT_ALIGN_CHECK_TYPE(jit_int,
int
);
_JIT_ALIGN_CHECK_TYPE(jit_long,
long
);
_JIT_ALIGN_CHECK_TYPE(jit_ptr, ptr);
_JIT_ALIGN_CHECK_TYPE(jit_float32,
float
);
_JIT_ALIGN_CHECK_TYPE(jit_float64,
double
);
_JIT_ALIGN_CHECK_TYPE(jit_nfloat, nfloat);
#if defined(JIT_X86)
#define JIT_BEST_ALIGNMENT 4
#else
#define JIT_BEST_ALIGNMENT \
_JIT_ALIGN_MAX(_JIT_ALIGN_MAX3(_JIT_ALIGN_FOR_TYPE(
int
), \
_JIT_ALIGN_FOR_TYPE(
long
), \
_JIT_ALIGN_FOR_TYPE(ptr)), \
_JIT_ALIGN_MAX3(_JIT_ALIGN_FOR_TYPE(
float
), \
_JIT_ALIGN_FOR_TYPE(
double
), \
_JIT_ALIGN_FOR_TYPE(nfloat)))
#endif
#define JIT_ALIGN_SBYTE _JIT_ALIGN_FOR_TYPE(sbyte)
#define JIT_ALIGN_UBYTE _JIT_ALIGN_FOR_TYPE(sbyte)
#define JIT_ALIGN_SHORT _JIT_ALIGN_FOR_TYPE(short)
#define JIT_ALIGN_USHORT _JIT_ALIGN_FOR_TYPE(short)
#define JIT_ALIGN_CHAR _JIT_ALIGN_FOR_TYPE(char)
#define JIT_ALIGN_INT _JIT_ALIGN_FOR_TYPE(int)
#define JIT_ALIGN_UINT _JIT_ALIGN_FOR_TYPE(int)
#define JIT_ALIGN_NINT _JIT_ALIGN_FOR_TYPE(ptr)
#define JIT_ALIGN_NUINT _JIT_ALIGN_FOR_TYPE(ptr)
#define JIT_ALIGN_LONG _JIT_ALIGN_FOR_TYPE(long)
#define JIT_ALIGN_ULONG _JIT_ALIGN_FOR_TYPE(long)
#define JIT_ALIGN_FLOAT32 _JIT_ALIGN_FOR_TYPE(float)
#define JIT_ALIGN_FLOAT64 _JIT_ALIGN_FOR_TYPE(double)
#define JIT_ALIGN_NFLOAT _JIT_ALIGN_FOR_TYPE(nfloat)
#define JIT_ALIGN_PTR _JIT_ALIGN_FOR_TYPE(ptr)
typedef
struct
jit_pool_block *jit_pool_block_t;
struct
jit_pool_block
{
jit_pool_block_t next;
char
data[1];
};
typedef
struct
{
unsigned
int
elem_size;
unsigned
int
elems_per_block;
unsigned
int
elems_in_last;
jit_pool_block_t blocks;
void
*free_list;
} jit_memory_pool;
void
_jit_memory_pool_init(jit_memory_pool *pool, unsigned
int
elem_size);
#define jit_memory_pool_init(pool,type) \
_jit_memory_pool_init((pool),
sizeof
(type))
void
_jit_memory_pool_free(jit_memory_pool *pool, jit_meta_free_func func);
#define jit_memory_pool_free(pool,func) _jit_memory_pool_free((pool), (func))
void
*_jit_memory_pool_alloc(jit_memory_pool *pool);
#define jit_memory_pool_alloc(pool,type) \
((type *)_jit_memory_pool_alloc((pool)))
void
_jit_memory_pool_dealloc(jit_memory_pool *pool,
void
*item);
#define jit_memory_pool_dealloc(pool,item) \
(_jit_memory_pool_dealloc((pool), (item)))
struct
_jit_meta
{
int
type;
void
*data;
jit_meta_free_func free_data;
jit_meta_t next;
jit_function_t pool_owner;
};
typedef
struct
_jit_edge *_jit_edge_t;
struct
_jit_edge
{
jit_block_t src;
jit_block_t dst;
int
flags;
};
#define _JIT_EDGE_FALLTHRU 0
#define _JIT_EDGE_BRANCH 1
#define _JIT_EDGE_RETURN 2
#define _JIT_EDGE_EXCEPT 3
struct
_jit_block
{
jit_function_t func;
jit_label_t label;
jit_insn_t insns;
int
num_insns;
int
max_insns;
jit_block_t next;
jit_block_t prev;
_jit_edge_t *succs;
int
num_succs;
_jit_edge_t *preds;
int
num_preds;
unsigned visited : 1;
unsigned ends_in_dead : 1;
unsigned address_of : 1;
jit_meta_t meta;
void
*address;
void
*fixup_list;
void
*fixup_absolute_list;
};
struct
_jit_value
{
jit_block_t block;
jit_type_t type;
unsigned is_temporary : 1;
unsigned is_local : 1;
unsigned is_volatile : 1;
unsigned is_addressable : 1;
unsigned is_constant : 1;
unsigned is_nint_constant : 1;
unsigned is_parameter : 1;
unsigned is_reg_parameter : 1;
unsigned has_address : 1;
unsigned free_address : 1;
unsigned in_register : 1;
unsigned in_frame : 1;
unsigned in_global_register : 1;
unsigned live : 1;
unsigned next_use : 1;
unsigned has_frame_offset : 1;
unsigned global_candidate : 1;
unsigned has_global_register : 1;
short
reg;
short
global_reg;
jit_nint address;
jit_nint frame_offset;
jit_nuint usage_count;
int
index;
};
#define JIT_INVALID_FRAME_OFFSET ((jit_nint)0x7FFFFFFF)
void
_jit_value_free(
void
*value);
void
_jit_value_ref_params(jit_function_t func);
struct
_jit_insn
{
short
opcode;
short
flags;
jit_value_t dest;
jit_value_t value1;
jit_value_t value2;
};
#define JIT_INSN_DEST_LIVE 0x0001
#define JIT_INSN_DEST_NEXT_USE 0x0002
#define JIT_INSN_VALUE1_LIVE 0x0004
#define JIT_INSN_VALUE1_NEXT_USE 0x0008
#define JIT_INSN_VALUE2_LIVE 0x0010
#define JIT_INSN_VALUE2_NEXT_USE 0x0020
#define JIT_INSN_LIVENESS_FLAGS 0x003F
#define JIT_INSN_DEST_IS_LABEL 0x0040
#define JIT_INSN_DEST_IS_FUNCTION 0x0080
#define JIT_INSN_DEST_IS_NATIVE 0x0100
#define JIT_INSN_DEST_OTHER_FLAGS 0x01C0
#define JIT_INSN_VALUE1_IS_NAME 0x0200
#define JIT_INSN_VALUE1_IS_LABEL 0x0400
#define JIT_INSN_VALUE1_OTHER_FLAGS 0x0600
#define JIT_INSN_VALUE2_IS_SIGNATURE 0x0800
#define JIT_INSN_VALUE2_OTHER_FLAGS 0x0800
#define JIT_INSN_DEST_IS_VALUE 0x1000
typedef
struct
_jit_label_info _jit_label_info_t;
struct
_jit_label_info
{
jit_block_t block;
jit_label_t alias;
int
flags;
};
#define JIT_LABEL_ADDRESS_OF 0x0001
typedef
struct
_jit_builder *jit_builder_t;
struct
_jit_builder
{
jit_block_t entry_block;
jit_block_t exit_block;
jit_block_t init_block;
jit_block_t current_block;
jit_block_t deleted_blocks;
jit_block_t *block_order;
int
num_block_order;
jit_label_t next_label;
_jit_label_info_t *label_info;
jit_label_t max_label_info;
jit_value_t setjmp_value;
jit_value_t thrown_exception;
jit_value_t thrown_pc;
jit_label_t catcher_label;
jit_value_t eh_frame_info;
unsigned non_leaf : 1;
unsigned may_throw : 1;
unsigned ordinary_return : 1;
unsigned has_tail_call : 1;
unsigned position_independent : 1;
jit_memory_pool value_pool;
jit_memory_pool edge_pool;
jit_memory_pool meta_pool;
jit_value_t null_constant;
jit_value_t zero_constant;
jit_value_t *param_values;
jit_value_t struct_return;
jit_value_t parent_frame;
jit_meta_t meta;
jit_nint frame_size;
jit_nint deferred_items;
jit_nint param_area_size;
#ifdef _JIT_COMPILE_DEBUG
int
block_count;
int
insn_count;
#endif
};
struct
_jit_function
{
jit_context_t context;
jit_function_t next;
jit_function_t prev;
jit_function_t nested_parent;
jit_meta_t meta;
jit_type_t signature;
jit_builder_t builder;
jit_varint_data_t bytecode_offset;
void
*cookie;
unsigned is_recompilable : 1;
unsigned is_optimized : 1;
unsigned no_throw : 1;
unsigned no_return : 1;
unsigned has_try : 1;
unsigned optimization_level : 8;
int
volatile
is_compiled;
void
*
volatile
entry_point;
jit_on_demand_func on_demand;
#ifndef JIT_BACKEND_INTERP
# ifdef jit_redirector_size
unsigned
char
*redirector;
# endif
unsigned
char
*indirector;
#endif
};
int
_jit_function_ensure_builder(jit_function_t func);
void
_jit_function_free_builder(jit_function_t func);
void
_jit_function_destroy(jit_function_t func);
void
_jit_function_compute_liveness(jit_function_t func);
void
*_jit_function_compile_on_demand(jit_function_t func);
unsigned
long
_jit_function_get_bytecode(jit_function_t func,
void
*func_info,
void
*pc,
int
exact);
typedef
struct
jit_regsym *jit_regsym_t;
struct
jit_regsym
{
void
*value;
int
after;
char
name[1];
};
struct
_jit_context
{
jit_memory_manager_t memory_manager;
jit_memory_context_t memory_context;
jit_mutex_t memory_lock;
jit_mutex_t builder_lock;
jit_function_t functions;
jit_function_t last_function;
jit_meta_t meta;
jit_readelf_t elf_binaries;
jit_regsym_t *registered_symbols;
int
num_registered_symbols;
jit_debugger_hook_func debug_hook;
jit_debugger_t debugger;
jit_on_demand_driver_func on_demand_driver;
};
void
*_jit_malloc_exec(unsigned
int
size);
void
_jit_free_exec(
void
*ptr, unsigned
int
size);
void
_jit_flush_exec(
void
*ptr, unsigned
int
size);
void
_jit_memory_lock(jit_context_t context);
void
_jit_memory_unlock(jit_context_t context);
int
_jit_memory_ensure(jit_context_t context);
void
_jit_memory_destroy(jit_context_t context);
jit_function_info_t _jit_memory_find_function_info(jit_context_t context,
void
*pc);
jit_function_t _jit_memory_get_function(jit_context_t context, jit_function_info_t info);
void
*_jit_memory_get_function_start(jit_context_t context, jit_function_info_t info);
void
*_jit_memory_get_function_end(jit_context_t context, jit_function_info_t info);
jit_function_t _jit_memory_alloc_function(jit_context_t context);
void
_jit_memory_free_function(jit_context_t context, jit_function_t func);
int
_jit_memory_start_function(jit_context_t context, jit_function_t func);
int
_jit_memory_end_function(jit_context_t context,
int
result);
int
_jit_memory_extend_limit(jit_context_t context,
int
count);
void
*_jit_memory_get_limit(jit_context_t context);
void
*_jit_memory_get_break(jit_context_t context);
void
_jit_memory_set_break(jit_context_t context,
void
*brk);
void
*_jit_memory_alloc_trampoline(jit_context_t context);
void
_jit_memory_free_trampoline(jit_context_t context,
void
*ptr);
void
*_jit_memory_alloc_closure(jit_context_t context);
void
_jit_memory_free_closure(jit_context_t context,
void
*ptr);
void
*_jit_memory_alloc_data(jit_context_t context, jit_size_t size, jit_size_t align);
typedef
struct
jit_backtrace *jit_backtrace_t;
struct
jit_backtrace
{
jit_backtrace_t parent;
void
*pc;
void
*security_object;
jit_meta_free_func free_security_object;
};
void
_jit_backtrace_push(jit_backtrace_t trace,
void
*pc);
void
_jit_backtrace_pop(
void
);
void
_jit_backtrace_set(jit_backtrace_t trace);
struct
jit_thread_control
{
void
*last_exception;
jit_exception_func exception_handler;
jit_backtrace_t backtrace_head;
struct
jit_jmp_buf *setjmp_head;
};
int
_jit_block_init(jit_function_t func);
void
_jit_block_free(jit_function_t func);
void
_jit_block_build_cfg(jit_function_t func);
void
_jit_block_clean_cfg(jit_function_t func);
int
_jit_block_compute_postorder(jit_function_t func);
jit_block_t _jit_block_create(jit_function_t func);
void
_jit_block_destroy(jit_block_t block);
void
_jit_block_detach(jit_block_t first, jit_block_t last);
void
_jit_block_attach_after(jit_block_t block, jit_block_t first, jit_block_t last);
void
_jit_block_attach_before(jit_block_t block, jit_block_t first, jit_block_t last);
int
_jit_block_record_label(jit_block_t block, jit_label_t label);
int
_jit_block_record_label_flags(jit_function_t func, jit_label_t label,
int
flags);
jit_insn_t _jit_block_add_insn(jit_block_t block);
jit_insn_t _jit_block_get_last(jit_block_t block);
int
_jit_block_is_final(jit_block_t block);
void
_jit_meta_free_one(
void
*meta);
int
_jit_insn_check_is_redundant(
const
jit_insn_iter_t *iter);
int
_jit_load_opcode(
int
base_opcode, jit_type_t type,
jit_value_t value,
int
no_temps);
int
_jit_store_opcode(
int
base_opcode,
int
small_base, jit_type_t type);
void
_jit_debugger_hook(jit_function_t func, jit_nint data1, jit_nint data2);
struct
jit_component
{
jit_type_t type;
jit_nuint offset;
char
*name;
};
struct
_jit_type
{
unsigned
int
ref_count;
int
kind : 19;
int
abi : 8;
int
is_fixed : 1;
int
layout_flags : 4;
jit_nuint size;
jit_nuint alignment;
jit_type_t sub_type;
unsigned
int
num_components;
struct
jit_component components[1];
};
struct
jit_tagged_type
{
struct
_jit_type type;
void
*data;
jit_meta_free_func free_func;
};
extern
struct
_jit_type
const
_jit_type_void_def;
extern
struct
_jit_type
const
_jit_type_sbyte_def;
extern
struct
_jit_type
const
_jit_type_ubyte_def;
extern
struct
_jit_type
const
_jit_type_short_def;
extern
struct
_jit_type
const
_jit_type_ushort_def;
extern
struct
_jit_type
const
_jit_type_int_def;
extern
struct
_jit_type
const
_jit_type_uint_def;
extern
struct
_jit_type
const
_jit_type_nint_def;
extern
struct
_jit_type
const
_jit_type_nuint_def;
extern
struct
_jit_type
const
_jit_type_long_def;
extern
struct
_jit_type
const
_jit_type_ulong_def;
extern
struct
_jit_type
const
_jit_type_float32_def;
extern
struct
_jit_type
const
_jit_type_float64_def;
extern
struct
_jit_type
const
_jit_type_nfloat_def;
extern
struct
_jit_type
const
_jit_type_void_ptr_def;
typedef
enum
{
JIT_SIG_NONE = 0,
JIT_SIG_i_i = 1,
JIT_SIG_i_ii = 2,
JIT_SIG_i_piii = 3,
JIT_SIG_i_iI = 4,
JIT_SIG_i_II = 5,
JIT_SIG_I_I = 6,
JIT_SIG_I_II = 7,
JIT_SIG_i_pIII = 8,
JIT_SIG_l_l = 9,
JIT_SIG_l_ll = 10,
JIT_SIG_i_plll = 11,
JIT_SIG_i_l = 12,
JIT_SIG_i_ll = 13,
JIT_SIG_l_lI = 14,
JIT_SIG_L_L = 15,
JIT_SIG_L_LL = 16,
JIT_SIG_i_pLLL = 17,
JIT_SIG_i_LL = 18,
JIT_SIG_L_LI = 19,
JIT_SIG_f_f = 20,
JIT_SIG_f_ff = 21,
JIT_SIG_i_f = 22,
JIT_SIG_i_ff = 23,
JIT_SIG_d_d = 24,
JIT_SIG_d_dd = 25,
JIT_SIG_i_d = 26,
JIT_SIG_i_dd = 27,
JIT_SIG_D_D = 28,
JIT_SIG_D_DD = 29,
JIT_SIG_i_D = 30,
JIT_SIG_i_DD = 31,
JIT_SIG_conv = 32,
JIT_SIG_conv_ovf= 33
} _jit_intrinsic_signature;
#define _JIT_INTRINSIC_FLAG_NONE 0x0000
#define _JIT_INTRINSIC_FLAG_BRANCH 0x8000
#define _JIT_INTRINSIC_FLAG_BRANCH_UNARY 0xC000
#define _JIT_INTRINSIC_FLAG_NOT 0x4000
#define _JIT_INTRINSIC_FLAG_MASK 0xC000
#define _JIT_INTRINSIC_FLAG_IFALSE 0x0000
#define _JIT_INTRINSIC_FLAG_ITRUE 0x0001
#define _JIT_INTRINSIC_FLAG_LFALSE 0x0002
#define _JIT_INTRINSIC_FLAG_LTRUE 0x0003
typedef
struct
_jit_intrinsic_info _jit_intrinsic_info_t;
struct
_jit_intrinsic_info
{
jit_short flags;
jit_short signature;
void
*intrinsic;
};
extern
_jit_intrinsic_info_t
const
_jit_intrinsics[JIT_OP_NUM_OPCODES];
jit_value_t
_jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_type_t dest_type,
jit_value_t value1, jit_value_t value2);
#define JIT_CALL_NATIVE (1 << 14)
#ifdef JIT_USE_SIGNALS
void
_jit_signal_init(
void
);
#endif
#ifdef __cplusplus
};
#endif
#endif /* _JIT_INTERNAL_H */