github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/jit-internal.h (about)

     1  /*
     2   * jit-internal.h - Internal definitions for the JIT.
     3   *
     4   * Copyright (C) 2004  Southern Storm Software, Pty Ltd.
     5   *
     6   * This file is part of the libjit library.
     7   *
     8   * The libjit library is free software: you can redistribute it and/or
     9   * modify it under the terms of the GNU Lesser General Public License
    10   * as published by the Free Software Foundation, either version 2.1 of
    11   * the License, or (at your option) any later version.
    12   *
    13   * The libjit library is distributed in the hope that it will be useful,
    14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    16   * Lesser General Public License for more details.
    17   *
    18   * You should have received a copy of the GNU Lesser General Public
    19   * License along with the libjit library.  If not, see
    20   * <http://www.gnu.org/licenses/>.
    21   */
    22  
    23  #ifndef	_JIT_INTERNAL_H
    24  #define	_JIT_INTERNAL_H
    25  
    26  #include <jit/jit.h>
    27  #include "jit-config.h"
    28  
    29  #if defined(HAVE_STRING_H)
    30  # include <string.h>
    31  #elif defined(HAVE_STRINGS_H)
    32  # include <strings.h>
    33  #endif
    34  #if defined(HAVE_MEMORY_H)
    35  # include <memory.h>
    36  #endif
    37  
    38  /*
    39   * Macros that replace the routines in <jit/jit-util.h>
    40   * with direct calls on the underlying library functions.
    41   */
    42  #if defined(HAVE_MEMSET)
    43  # define jit_memset(s, c, len)		(memset((s), (c), (len)))
    44  # define jit_memzero(s, len)		(memset((s), 0, (len)))
    45  #elif defined(HAVE_BZERO)
    46  # define jit_memzero(s, len)		(bzero((char *)(s), (len)))
    47  #else
    48  # define jit_memzero(s, len)		(jit_memset((char *)(s), 0, (len)))
    49  #endif
    50  #if defined(HAVE_MEMCPY)
    51  # define jit_memcpy(s1, s2, len)	(memcpy((s1), (s2), (len)))
    52  #endif
    53  #if defined(HAVE_MEMMOVE)
    54  # define jit_memmove(s1, s2, len)	(memmove((s1), (s2), (len)))
    55  #endif
    56  #if defined(HAVE_MEMCMP)
    57  # define jit_memcmp(s1, s2, len)	(memcmp((s1), (s2), (len)))
    58  #elif defined(HAVE_BCMP)
    59  # define jit_memcmp(s1, s2, len)	(bcmp((char *)(s1), (char *)(s2), (len)))
    60  #endif
    61  #if defined(HAVE_MEMCHR)
    62  # define jit_memchr(s, c, len)		(memchr((s), (c), (len)))
    63  #endif
    64  
    65  /*
    66   * We need the apply rules for "jit_redirector_size".
    67   */
    68  #include "jit-apply-func.h"
    69  
    70  /*
    71   * Include the thread routines.
    72   */
    73  #include "jit-thread.h"
    74  
    75  /*
    76   * Include varint encoding for bytecode offset data.
    77   */
    78  #include "jit-varint.h"
    79  
    80  #ifdef	__cplusplus
    81  extern	"C" {
    82  #endif
    83  
    84  /*
    85   * The following is some macro magic that attempts to detect
    86   * the best alignment to use on the target platform.  The final
    87   * value, "JIT_BEST_ALIGNMENT", will be a compile-time constant.
    88   */
    89  
    90  #define	_JIT_ALIGN_CHECK_TYPE(type,name)	\
    91  	struct _JIT_align_##name {		\
    92  		jit_sbyte pad;			\
    93  		type field;			\
    94  	}
    95  
    96  #define	_JIT_ALIGN_FOR_TYPE(name)	\
    97  	((jit_nuint)(&(((struct _JIT_align_##name *)0)->field)))
    98  
    99  #define	_JIT_ALIGN_MAX(a,b)	\
   100  	((a) > (b) ? (a) : (b))
   101  
   102  #define	_JIT_ALIGN_MAX3(a,b,c) \
   103  	(_JIT_ALIGN_MAX((a), _JIT_ALIGN_MAX((b), (c))))
   104  
   105  _JIT_ALIGN_CHECK_TYPE(jit_sbyte, sbyte);
   106  _JIT_ALIGN_CHECK_TYPE(jit_short, short);
   107  _JIT_ALIGN_CHECK_TYPE(jit_int, int);
   108  _JIT_ALIGN_CHECK_TYPE(jit_long, long);
   109  _JIT_ALIGN_CHECK_TYPE(jit_ptr, ptr);
   110  _JIT_ALIGN_CHECK_TYPE(jit_float32, float);
   111  _JIT_ALIGN_CHECK_TYPE(jit_float64, double);
   112  _JIT_ALIGN_CHECK_TYPE(jit_nfloat, nfloat);
   113  
   114  #if defined(JIT_X86)
   115  /* Sometimes the code below guesses wrong on Win32 platforms */
   116  #define	JIT_BEST_ALIGNMENT	4
   117  #else
   118  #define	JIT_BEST_ALIGNMENT						\
   119  	_JIT_ALIGN_MAX(_JIT_ALIGN_MAX3(_JIT_ALIGN_FOR_TYPE(int),	\
   120  				       _JIT_ALIGN_FOR_TYPE(long),	\
   121  				       _JIT_ALIGN_FOR_TYPE(ptr)),	\
   122  		       _JIT_ALIGN_MAX3(_JIT_ALIGN_FOR_TYPE(float),	\
   123  				       _JIT_ALIGN_FOR_TYPE(double),	\
   124  				       _JIT_ALIGN_FOR_TYPE(nfloat)))
   125  #endif
   126  
   127  /*
   128   * Get the alignment values for various system types.
   129   * These will also be compile-time constants.
   130   */
   131  #define	JIT_ALIGN_SBYTE			_JIT_ALIGN_FOR_TYPE(sbyte)
   132  #define	JIT_ALIGN_UBYTE			_JIT_ALIGN_FOR_TYPE(sbyte)
   133  #define	JIT_ALIGN_SHORT			_JIT_ALIGN_FOR_TYPE(short)
   134  #define	JIT_ALIGN_USHORT		_JIT_ALIGN_FOR_TYPE(short)
   135  #define	JIT_ALIGN_CHAR			_JIT_ALIGN_FOR_TYPE(char)
   136  #define	JIT_ALIGN_INT			_JIT_ALIGN_FOR_TYPE(int)
   137  #define	JIT_ALIGN_UINT			_JIT_ALIGN_FOR_TYPE(int)
   138  #define	JIT_ALIGN_NINT			_JIT_ALIGN_FOR_TYPE(ptr)
   139  #define	JIT_ALIGN_NUINT			_JIT_ALIGN_FOR_TYPE(ptr)
   140  #define	JIT_ALIGN_LONG			_JIT_ALIGN_FOR_TYPE(long)
   141  #define	JIT_ALIGN_ULONG			_JIT_ALIGN_FOR_TYPE(long)
   142  #define	JIT_ALIGN_FLOAT32		_JIT_ALIGN_FOR_TYPE(float)
   143  #define	JIT_ALIGN_FLOAT64		_JIT_ALIGN_FOR_TYPE(double)
   144  #define	JIT_ALIGN_NFLOAT		_JIT_ALIGN_FOR_TYPE(nfloat)
   145  #define	JIT_ALIGN_PTR			_JIT_ALIGN_FOR_TYPE(ptr)
   146  
   147  /*
   148   * Structure of a memory pool.
   149   */
   150  typedef struct jit_pool_block *jit_pool_block_t;
   151  struct jit_pool_block
   152  {
   153  	jit_pool_block_t	next;
   154  	char			data[1];
   155  };
   156  typedef struct
   157  {
   158  	unsigned int		elem_size;
   159  	unsigned int		elems_per_block;
   160  	unsigned int		elems_in_last;
   161  	jit_pool_block_t	blocks;
   162  	void			*free_list;
   163  
   164  } jit_memory_pool;
   165  
   166  /*
   167   * Initialize a memory pool.
   168   */
   169  void _jit_memory_pool_init(jit_memory_pool *pool, unsigned int elem_size);
   170  #define	jit_memory_pool_init(pool,type)	\
   171  			_jit_memory_pool_init((pool), sizeof(type))
   172  
   173  /*
   174   * Free the contents of a memory pool.
   175   */
   176  void _jit_memory_pool_free(jit_memory_pool *pool, jit_meta_free_func func);
   177  #define	jit_memory_pool_free(pool,func)	_jit_memory_pool_free((pool), (func))
   178  
   179  /*
   180   * Allocate an item from a memory pool.
   181   */
   182  void *_jit_memory_pool_alloc(jit_memory_pool *pool);
   183  #define	jit_memory_pool_alloc(pool,type)	\
   184  			((type *)_jit_memory_pool_alloc((pool)))
   185  
   186  /*
   187   * Deallocate an item back to a memory pool.
   188   */
   189  void _jit_memory_pool_dealloc(jit_memory_pool *pool, void *item);
   190  #define	jit_memory_pool_dealloc(pool,item)	\
   191  			(_jit_memory_pool_dealloc((pool), (item)))
   192  
   193  /*
   194   * Storage for metadata.
   195   */
   196  struct _jit_meta
   197  {
   198  	int			type;
   199  	void			*data;
   200  	jit_meta_free_func	free_data;
   201  	jit_meta_t		next;
   202  	jit_function_t		pool_owner;
   203  };
   204  
   205  /*
   206   * Control flow graph edge.
   207   */
   208  typedef struct _jit_edge *_jit_edge_t;
   209  struct _jit_edge
   210  {
   211  	/* Source node of the edge */
   212  	jit_block_t		src;
   213  
   214  	/* Destination node of the edge */
   215  	jit_block_t		dst;
   216  
   217  	/* Edge flags */
   218  	int			flags;
   219  };
   220  
   221  #define _JIT_EDGE_FALLTHRU	0
   222  #define _JIT_EDGE_BRANCH	1
   223  #define _JIT_EDGE_RETURN	2
   224  #define _JIT_EDGE_EXCEPT	3
   225  
   226  /*
   227   * Internal structure of a basic block.
   228   */
   229  struct _jit_block
   230  {
   231  	jit_function_t		func;
   232  	jit_label_t		label;
   233  
   234  	/* List of all instructions in this block */
   235  	jit_insn_t		insns;
   236  	int			num_insns;
   237  	int			max_insns;
   238  
   239  	/* Next and previous blocks in the function's linear block list */
   240  	jit_block_t 		next;
   241  	jit_block_t 		prev;
   242  
   243  	/* Edges to successor blocks in control flow graph */
   244  	_jit_edge_t		*succs;
   245  	int			num_succs;
   246  
   247  	/* Edges to predecessor blocks in control flow graph */
   248  	_jit_edge_t		*preds;
   249  	int			num_preds;
   250  
   251  	/* Control flow flags */
   252  	unsigned		visited : 1;
   253  	unsigned		ends_in_dead : 1;
   254  	unsigned		address_of : 1;
   255  
   256  	/* Metadata */
   257  	jit_meta_t		meta;
   258  
   259  	/* Code generation data */
   260  	void			*address;
   261  	void			*fixup_list;
   262  	void			*fixup_absolute_list;
   263  };
   264  
   265  /*
   266   * Internal structure of a value.
   267   */
   268  struct _jit_value
   269  {
   270  	jit_block_t		block;
   271  	jit_type_t		type;
   272  	unsigned		is_temporary : 1;
   273  	unsigned		is_local : 1;
   274  	unsigned		is_volatile : 1;
   275  	unsigned		is_addressable : 1;
   276  	unsigned		is_constant : 1;
   277  	unsigned		is_nint_constant : 1;
   278  	unsigned		is_parameter : 1;
   279  	unsigned		is_reg_parameter : 1;
   280  	unsigned		has_address : 1;
   281  	unsigned		free_address : 1;
   282  	unsigned		in_register : 1;
   283  	unsigned		in_frame : 1;
   284  	unsigned		in_global_register : 1;
   285  	unsigned		live : 1;
   286  	unsigned		next_use : 1;
   287  	unsigned		has_frame_offset : 1;
   288  	unsigned		global_candidate : 1;
   289  	unsigned		has_global_register : 1;
   290  	short			reg;
   291  	short			global_reg;
   292  	jit_nint		address;
   293  	jit_nint		frame_offset;
   294  	jit_nuint		usage_count;
   295  	int			index;
   296  };
   297  #define	JIT_INVALID_FRAME_OFFSET	((jit_nint)0x7FFFFFFF)
   298  
   299  /*
   300   * Free the structures that are associated with a value.
   301   */
   302  void _jit_value_free(void *value);
   303  
   304  /*
   305   * Add references to all of the parameter values in a function.
   306   * This is used when the initialization block is split during a
   307   * "jit_insn_move_blocks_to_start" instruction.
   308   */
   309  void _jit_value_ref_params(jit_function_t func);
   310  
   311  /*
   312   * Internal structure of an instruction.
   313   */
   314  struct _jit_insn
   315  {
   316  	short			opcode;
   317  	short			flags;
   318  	jit_value_t		dest;
   319  	jit_value_t		value1;
   320  	jit_value_t		value2;
   321  };
   322  
   323  /*
   324   * Instruction flags.
   325   */
   326  #define	JIT_INSN_DEST_LIVE		0x0001
   327  #define	JIT_INSN_DEST_NEXT_USE		0x0002
   328  #define	JIT_INSN_VALUE1_LIVE		0x0004
   329  #define	JIT_INSN_VALUE1_NEXT_USE	0x0008
   330  #define	JIT_INSN_VALUE2_LIVE		0x0010
   331  #define	JIT_INSN_VALUE2_NEXT_USE	0x0020
   332  #define	JIT_INSN_LIVENESS_FLAGS		0x003F
   333  #define	JIT_INSN_DEST_IS_LABEL		0x0040
   334  #define	JIT_INSN_DEST_IS_FUNCTION	0x0080
   335  #define	JIT_INSN_DEST_IS_NATIVE		0x0100
   336  #define	JIT_INSN_DEST_OTHER_FLAGS	0x01C0
   337  #define	JIT_INSN_VALUE1_IS_NAME		0x0200
   338  #define	JIT_INSN_VALUE1_IS_LABEL	0x0400
   339  #define	JIT_INSN_VALUE1_OTHER_FLAGS	0x0600
   340  #define	JIT_INSN_VALUE2_IS_SIGNATURE	0x0800
   341  #define	JIT_INSN_VALUE2_OTHER_FLAGS	0x0800
   342  #define	JIT_INSN_DEST_IS_VALUE		0x1000
   343  
   344  /*
   345   * Information about each label associated with a function.
   346   *
   347   * Multiple labels may belong to the same basic block. Such labels are
   348   * linked into list.
   349   */
   350  typedef struct _jit_label_info _jit_label_info_t;
   351  struct _jit_label_info
   352  {
   353  	/* Block the label assigned to */
   354  	jit_block_t		block;
   355  
   356  	/* Next label that might belong to the same block */
   357  	jit_label_t		alias;
   358  
   359  	/* Label flags */
   360  	int			flags;
   361  };
   362  
   363  #define JIT_LABEL_ADDRESS_OF		0x0001
   364  
   365  
   366  /*
   367   * Information that is associated with a function for building
   368   * the instructions and values.  This structure can be discarded
   369   * once the function has been fully compiled.
   370   */
   371  typedef struct _jit_builder *jit_builder_t;
   372  struct _jit_builder
   373  {
   374  	/* Entry point for the function (and the head of the block list) */
   375  	jit_block_t		entry_block;
   376  
   377  	/* Exit point for the function (and the tail of the block list) */
   378  	jit_block_t		exit_block;
   379  
   380  	/* The position to insert initialization blocks */
   381  	jit_block_t		init_block;
   382  
   383  	/* The current block that is being constructed */
   384  	jit_block_t		current_block;
   385  
   386  	/* The list of deleted blocks */
   387  	jit_block_t		deleted_blocks;
   388  
   389  	/* Blocks sorted in order required by an optimization pass */
   390  	jit_block_t		*block_order;
   391  	int			num_block_order;
   392  
   393  	/* The next block label to be allocated */
   394  	jit_label_t		next_label;
   395  
   396  	/* Mapping from label numbers to blocks */
   397  	_jit_label_info_t	*label_info;
   398  	jit_label_t		max_label_info;
   399  
   400  	/* Exception handling definitions for the function */
   401  	jit_value_t		setjmp_value;
   402  	jit_value_t		thrown_exception;
   403  	jit_value_t		thrown_pc;
   404  	jit_label_t		catcher_label;
   405  	jit_value_t		eh_frame_info;
   406  
   407  	/* Flag that is set to indicate that this function is not a leaf */
   408  	unsigned		non_leaf : 1;
   409  
   410  	/* Flag that indicates if we've seen code that may throw an exception */
   411  	unsigned		may_throw : 1;
   412  
   413  	/* Flag that indicates if the function has an ordinary return */
   414  	unsigned		ordinary_return : 1;
   415  
   416  	/* Flag that indicates that the current function contains a tail call */
   417  	unsigned		has_tail_call : 1;
   418  
   419  	/* Generate position-independent code */
   420  	unsigned		position_independent : 1;
   421  
   422  	/* Memory pools that contain values, instructions, and metadata blocks */
   423  	jit_memory_pool		value_pool;
   424  	jit_memory_pool		edge_pool;
   425  	jit_memory_pool		meta_pool;
   426  
   427  	/* Common constants that have been cached */
   428  	jit_value_t		null_constant;
   429  	jit_value_t		zero_constant;
   430  
   431  	/* The values for the parameters, structure return, and parent frame */
   432  	jit_value_t		*param_values;
   433  	jit_value_t		struct_return;
   434  	jit_value_t		parent_frame;
   435  
   436  	/* Metadata that is stored only while the function is being built */
   437  	jit_meta_t		meta;
   438  
   439  	/* Current size of the local variable frame (used by the back end) */
   440  	jit_nint		frame_size;
   441  
   442  	/* Number of stack items that are queued for a deferred pop */
   443  	jit_nint		deferred_items;
   444  
   445  	/* Size of the outgoing parameter area in the frame */
   446  	jit_nint		param_area_size;
   447  
   448  #ifdef _JIT_COMPILE_DEBUG
   449  	int			block_count;
   450  	int			insn_count;
   451  #endif
   452  };
   453  
   454  /*
   455   * Internal structure of a function.
   456   */
   457  struct _jit_function
   458  {
   459  	/* The context that the function is associated with */
   460  	jit_context_t		context;
   461  	jit_function_t		next;
   462  	jit_function_t		prev;
   463  
   464  	/* Containing function in a nested context */
   465  	jit_function_t		nested_parent;
   466  	jit_value_t		parent_frame;
   467  #ifdef JIT_BACKEND_INTERP
   468  	jit_value_t		arguments_pointer;
   469  	jit_nint		arguments_pointer_offset;
   470  #endif
   471  	jit_function_t		cached_parent;
   472  	jit_value_t		cached_parent_frame;
   473  
   474  	/* Metadata that survives once the builder is discarded */
   475  	jit_meta_t		meta;
   476  
   477  	/* The signature for this function */
   478  	jit_type_t		signature;
   479  
   480  	/* The builder information for this function */
   481  	jit_builder_t		builder;
   482  
   483  	/* Debug information for this function */
   484  	jit_varint_data_t	bytecode_offset;
   485  
   486  	/* Cookie value for this function */
   487  	void			*cookie;
   488  
   489  	/* Flag bits for this function */
   490  	unsigned		is_recompilable : 1;
   491  	unsigned		is_optimized : 1;
   492  	unsigned		no_throw : 1;
   493  	unsigned		no_return : 1;
   494  	unsigned		has_try : 1;
   495  	unsigned		optimization_level : 8;
   496  
   497  	/* Flag set once the function is compiled */
   498  	int volatile		is_compiled;
   499  
   500  	/* The entry point for the function's compiled code */
   501  	void * volatile		entry_point;
   502  
   503  	/* The function to call to perform on-demand compilation */
   504  	jit_on_demand_func	on_demand;
   505  
   506  #ifndef JIT_BACKEND_INTERP
   507  # ifdef jit_redirector_size
   508  	/* Buffer that contains the redirector for this function.
   509  	   Redirectors are used to support on-demand compilation */
   510  	unsigned char		*redirector;
   511  # endif
   512  
   513  	/* Buffer that contains the indirector for this function.
   514  	   The indirector jumps to the address that is currently
   515  	   stored in the entry_point field. Indirectors are used
   516  	   to support recompilation and on-demand compilation. */
   517  	unsigned char		*indirector;
   518  #endif
   519  };
   520  
   521  /*
   522   * Ensure that there is a builder associated with a function.
   523   */
   524  int _jit_function_ensure_builder(jit_function_t func);
   525  
   526  /*
   527   * Free the builder associated with a function.
   528   */
   529  void _jit_function_free_builder(jit_function_t func);
   530  
   531  /*
   532   * Destroy all memory associated with a function.
   533   */
   534  void _jit_function_destroy(jit_function_t func);
   535  
   536  /*
   537   * Compute value liveness and "next use" information for a function.
   538   */
   539  void _jit_function_compute_liveness(jit_function_t func);
   540  
   541  /*
   542   * Compile a function on-demand.  Returns the entry point.
   543   */
   544  void *_jit_function_compile_on_demand(jit_function_t func);
   545  
   546  /*
   547   * Get the bytecode offset that is associated with a native
   548   * offset within a method.  Returns JIT_CACHE_NO_OFFSET
   549   * if the bytecode offset could not be determined.
   550   */
   551  unsigned long _jit_function_get_bytecode(jit_function_t func, void *func_info, void *pc, int exact);
   552  
   553  /*
   554   * Information about a registered external symbol.
   555   */
   556  typedef struct jit_regsym *jit_regsym_t;
   557  struct jit_regsym
   558  {
   559  	void   *value;
   560  	int		after;
   561  	char	name[1];
   562  };
   563  
   564  /*
   565   * Internal structure of a context.
   566   */
   567  struct _jit_context
   568  {
   569  	/* The context's memory control */
   570  	jit_memory_manager_t	memory_manager;
   571  	jit_memory_context_t	memory_context;
   572  	jit_mutex_t		memory_lock;
   573  
   574  	/* Lock that controls access to the building process */
   575  	jit_mutex_t		builder_lock;
   576  
   577  	/* List of functions that are currently registered with the context */
   578  	jit_function_t		functions;
   579  	jit_function_t		last_function;
   580  
   581  	/* Metadata that is associated with the context */
   582  	jit_meta_t		meta;
   583  
   584  	/* ELF binaries that have been loaded into this context */
   585  	jit_readelf_t		elf_binaries;
   586  
   587  	/* Table of symbols that have been registered with this context */
   588  	jit_regsym_t		*registered_symbols;
   589  	int			num_registered_symbols;
   590  
   591  	/* Debugger support */
   592  	jit_debugger_hook_func	debug_hook;
   593  	jit_debugger_t		debugger;
   594  
   595  	/* On-demand compilation driver */
   596  	jit_on_demand_driver_func	on_demand_driver;
   597  };
   598  
   599  void *_jit_malloc_exec(unsigned int size);
   600  void _jit_free_exec(void *ptr, unsigned int size);
   601  void _jit_flush_exec(void *ptr, unsigned int size);
   602  
   603  void _jit_memory_lock(jit_context_t context);
   604  void _jit_memory_unlock(jit_context_t context);
   605  
   606  int _jit_memory_ensure(jit_context_t context);
   607  void _jit_memory_destroy(jit_context_t context);
   608  
   609  jit_function_info_t _jit_memory_find_function_info(jit_context_t context, void *pc);
   610  jit_function_t _jit_memory_get_function(jit_context_t context, jit_function_info_t info);
   611  void *_jit_memory_get_function_start(jit_context_t context, jit_function_info_t info);
   612  void *_jit_memory_get_function_end(jit_context_t context, jit_function_info_t info);
   613  
   614  jit_function_t _jit_memory_alloc_function(jit_context_t context);
   615  void _jit_memory_free_function(jit_context_t context, jit_function_t func);
   616  int _jit_memory_start_function(jit_context_t context, jit_function_t func);
   617  int _jit_memory_end_function(jit_context_t context, int result);
   618  int _jit_memory_extend_limit(jit_context_t context, int count);
   619  void *_jit_memory_get_limit(jit_context_t context);
   620  void *_jit_memory_get_break(jit_context_t context);
   621  void _jit_memory_set_break(jit_context_t context, void *brk);
   622  void *_jit_memory_alloc_trampoline(jit_context_t context);
   623  void _jit_memory_free_trampoline(jit_context_t context, void *ptr);
   624  void *_jit_memory_alloc_closure(jit_context_t context);
   625  void _jit_memory_free_closure(jit_context_t context, void *ptr);
   626  void *_jit_memory_alloc_data(jit_context_t context, jit_size_t size, jit_size_t align);
   627  
   628  /*
   629   * Backtrace control structure, for managing stack traces.
   630   * These structures must be allocated on the stack.
   631   */
   632  typedef struct jit_backtrace *jit_backtrace_t;
   633  struct jit_backtrace
   634  {
   635  	jit_backtrace_t		parent;
   636  	void			*pc;
   637  	void			*security_object;
   638  	jit_meta_free_func	free_security_object;
   639  };
   640  
   641  /*
   642   * Push a new backtrace onto the stack.  The fields in "trace" are filled in.
   643   */
   644  void _jit_backtrace_push(jit_backtrace_t trace, void *pc);
   645  
   646  /*
   647   * Pop the top-most backtrace item.
   648   */
   649  void _jit_backtrace_pop(void);
   650  
   651  /*
   652   * Reset the backtrace stack to "trace".  Used in exception catch
   653   * blocks to fix up the backtrace information.
   654   */
   655  void _jit_backtrace_set(jit_backtrace_t trace);
   656  
   657  /*
   658   * Control information that is associated with a thread.
   659   */
   660  struct jit_thread_control
   661  {
   662  	void			*last_exception;
   663  	jit_exception_func	exception_handler;
   664  	jit_backtrace_t		backtrace_head;
   665  	struct jit_jmp_buf	*setjmp_head;
   666  };
   667  
   668  /*
   669   * Initialize the block list for a function.
   670   */
   671  int _jit_block_init(jit_function_t func);
   672  
   673  /*
   674   * Free all blocks that are associated with a function.
   675   */
   676  void _jit_block_free(jit_function_t func);
   677  
   678  /*
   679   * Build control flow graph edges for all blocks associated with a
   680   * function.
   681   */
   682  void _jit_block_build_cfg(jit_function_t func);
   683  
   684  /*
   685   * Eliminate useless control flow between blocks in a function.
   686   */
   687  void _jit_block_clean_cfg(jit_function_t func);
   688  
   689  /*
   690   * Compute block postorder for control flow graph depth first traversal.
   691   */
   692  int _jit_block_compute_postorder(jit_function_t func);
   693  
   694  /*
   695   * Create a new block and associate it with a function.
   696   */
   697  jit_block_t _jit_block_create(jit_function_t func);
   698  
   699  /*
   700   * Destroy a block.
   701   */
   702  void _jit_block_destroy(jit_block_t block);
   703  
   704  /*
   705   * Detach blocks from their current position in a function.
   706   */
   707  void _jit_block_detach(jit_block_t first, jit_block_t last);
   708  
   709  /*
   710   * Attach blocks to a function after a specific position.
   711   */
   712  void _jit_block_attach_after(jit_block_t block, jit_block_t first, jit_block_t last);
   713  
   714  /*
   715   * Attach blocks to a function before a specific position.
   716   */
   717  void _jit_block_attach_before(jit_block_t block, jit_block_t first, jit_block_t last);
   718  
   719  /*
   720   * Record the label mapping for a block.
   721   */
   722  int _jit_block_record_label(jit_block_t block, jit_label_t label);
   723  
   724  /*
   725   * Record the label flags.
   726   */
   727  int _jit_block_record_label_flags(jit_function_t func, jit_label_t label, int flags);
   728  
   729  /*
   730   * Add an instruction to a block.
   731   */
   732  jit_insn_t _jit_block_add_insn(jit_block_t block);
   733  
   734  /*
   735   * Get the last instruction in a block.  NULL if the block is empty.
   736   */
   737  jit_insn_t _jit_block_get_last(jit_block_t block);
   738  
   739  /*
   740   * The block goes just before the function end possibly excluding
   741   * some empty blocks.
   742   */
   743  int _jit_block_is_final(jit_block_t block);
   744  
   745  /*
   746   * Free one element in a metadata list.
   747   */
   748  void _jit_meta_free_one(void *meta);
   749  
   750  /*
   751   * Determine if a NULL pointer check is redundant.  The specified
   752   * iterator is assumed to be positioned one place beyond the
   753   * "check_null" instruction that we are testing.
   754   */
   755  int _jit_insn_check_is_redundant(const jit_insn_iter_t *iter);
   756  
   757  /*
   758   * Get the correct opcode to use for a "load" instruction,
   759   * starting at a particular opcode base.  We assume that the
   760   * instructions are laid out as "sbyte", "ubyte", "short",
   761   * "ushort", "int", "long", "float32", "float64", "nfloat",
   762   * and "struct".
   763   */
   764  int _jit_load_opcode(int base_opcode, jit_type_t type);
   765  
   766  /*
   767   * Get the correct opcode to use for a "store" instruction.
   768   * We assume that the instructions are laid out as "byte",
   769   * "short", "int", "long", "float32", "float64", "nfloat",
   770   * and "struct".
   771   */
   772  int _jit_store_opcode(int base_opcode, int small_base, jit_type_t type);
   773  
   774  /*
   775   * Function that is called upon each breakpoint location.
   776   */
   777  void _jit_debugger_hook(jit_function_t func, jit_nint data1, jit_nint data2);
   778  
   779  /*
   780   * Internal structure of a type descriptor.
   781   */
   782  struct jit_component
   783  {
   784  	jit_type_t		type;
   785  	jit_nuint		offset;
   786  	char			*name;
   787  };
   788  struct _jit_type
   789  {
   790  	unsigned int		ref_count;
   791  	int			kind : 19;
   792  	int			abi : 8;
   793  	int			is_fixed : 1;
   794  	int			layout_flags : 4;
   795  	jit_nuint		size;
   796  	jit_nuint		alignment;
   797  	jit_type_t		sub_type;
   798  	unsigned int		num_components;
   799  	struct jit_component	components[1];
   800  };
   801  struct jit_tagged_type
   802  {
   803  	struct _jit_type	type;
   804  	void			*data;
   805  	jit_meta_free_func	free_func;
   806  
   807  };
   808  
   809  /*
   810   * Pre-defined type descriptors.
   811   */
   812  extern struct _jit_type const _jit_type_void_def;
   813  extern struct _jit_type const _jit_type_sbyte_def;
   814  extern struct _jit_type const _jit_type_ubyte_def;
   815  extern struct _jit_type const _jit_type_short_def;
   816  extern struct _jit_type const _jit_type_ushort_def;
   817  extern struct _jit_type const _jit_type_int_def;
   818  extern struct _jit_type const _jit_type_uint_def;
   819  extern struct _jit_type const _jit_type_nint_def;
   820  extern struct _jit_type const _jit_type_nuint_def;
   821  extern struct _jit_type const _jit_type_long_def;
   822  extern struct _jit_type const _jit_type_ulong_def;
   823  extern struct _jit_type const _jit_type_float32_def;
   824  extern struct _jit_type const _jit_type_float64_def;
   825  extern struct _jit_type const _jit_type_nfloat_def;
   826  extern struct _jit_type const _jit_type_void_ptr_def;
   827  
   828  /*
   829   * Intrinsic signatures.
   830   *
   831   * Naming convention is return type folowed by an underscore and the
   832   * argument types.
   833   *
   834   * jit_int	-> i  (lower case I)
   835   * jit_uint	-> I
   836   * jit_long	-> l  (lower case L)
   837   * jit_ulong	-> L
   838   * jit_float32	-> f
   839   * jit_float64	-> d
   840   * jit_nflloat	-> D
   841   *
   842   * pointer	-> p  followed by the type
   843   *
   844   * Special signatures are conv and conv_ovf for type conversions without
   845   * and with overflow checks.
   846   */
   847  typedef enum
   848  {
   849  	JIT_SIG_NONE	= 0,
   850  	JIT_SIG_i_i	= 1,
   851  	JIT_SIG_i_ii	= 2,
   852  	JIT_SIG_i_piii	= 3,
   853  	JIT_SIG_i_iI	= 4,
   854  	JIT_SIG_i_II	= 5,
   855  	JIT_SIG_I_I	= 6,
   856  	JIT_SIG_I_II	= 7,
   857  	JIT_SIG_i_pIII	= 8,
   858  	JIT_SIG_l_l	= 9,
   859  	JIT_SIG_l_ll	= 10,
   860  	JIT_SIG_i_plll	= 11,
   861  	JIT_SIG_i_l	= 12,
   862  	JIT_SIG_i_ll	= 13,
   863  	JIT_SIG_l_lI	= 14,
   864  	JIT_SIG_L_L	= 15,
   865  	JIT_SIG_L_LL	= 16,
   866  	JIT_SIG_i_pLLL	= 17,
   867  	JIT_SIG_i_LL	= 18,
   868  	JIT_SIG_L_LI	= 19,
   869  	JIT_SIG_f_f	= 20,
   870  	JIT_SIG_f_ff	= 21,
   871  	JIT_SIG_i_f	= 22,
   872  	JIT_SIG_i_ff	= 23,
   873  	JIT_SIG_d_d	= 24,
   874  	JIT_SIG_d_dd	= 25,
   875  	JIT_SIG_i_d	= 26,
   876  	JIT_SIG_i_dd	= 27,
   877  	JIT_SIG_D_D	= 28,
   878  	JIT_SIG_D_DD	= 29,
   879  	JIT_SIG_i_D	= 30,
   880  	JIT_SIG_i_DD	= 31,
   881  	JIT_SIG_conv	= 32,
   882  	JIT_SIG_conv_ovf= 33
   883  } _jit_intrinsic_signature;
   884  
   885  /*
   886   * Flags for the intrinsic info.
   887   */
   888  #define _JIT_INTRINSIC_FLAG_NONE		0x0000
   889  #define _JIT_INTRINSIC_FLAG_BRANCH		0x8000
   890  #define _JIT_INTRINSIC_FLAG_BRANCH_UNARY	0xC000
   891  #define _JIT_INTRINSIC_FLAG_NOT			0x4000
   892  #define _JIT_INTRINSIC_FLAG_MASK		0xC000
   893  
   894  /*
   895   * Additional intrinsic flags for the unary branches.
   896   */
   897  #define _JIT_INTRINSIC_FLAG_IFALSE		0x0000
   898  #define _JIT_INTRINSIC_FLAG_ITRUE		0x0001
   899  #define _JIT_INTRINSIC_FLAG_LFALSE		0x0002
   900  #define _JIT_INTRINSIC_FLAG_LTRUE		0x0003
   901  
   902  /*
   903   * Description for the implementation of an opcode by an intrinsic.
   904   */
   905  typedef struct _jit_intrinsic_info _jit_intrinsic_info_t;
   906  struct _jit_intrinsic_info
   907  {
   908  	int	flags;
   909  	jit_short	signature;
   910  	void 		*intrinsic;
   911  };
   912  
   913  extern _jit_intrinsic_info_t const _jit_intrinsics[JIT_OP_NUM_OPCODES];
   914  
   915  /*
   916   * Apply an opcode to one or two constant values.
   917   * Returns the constant result value on success and NULL otherwise.
   918   * NOTE: The type argument MUST be the correct destination type for the
   919   * opcode or a tagged type of the correct destination type.
   920   */
   921  jit_value_t
   922  _jit_opcode_apply_unary(jit_function_t func, jit_uint opcode, jit_value_t value,
   923  			jit_type_t type);
   924  jit_value_t
   925  _jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_value_t value1,
   926  		  jit_value_t value2, jit_type_t type);
   927  
   928  /*
   929   * Extra call flags for internal use.
   930   */
   931  #define	JIT_CALL_NATIVE		(1 << 14)
   932  
   933  #ifdef JIT_USE_SIGNALS
   934  
   935  /*
   936   * Initialize the signal handlers.
   937   */
   938  void _jit_signal_init(void);
   939  
   940  #endif
   941  
   942  #ifdef	__cplusplus
   943  };
   944  #endif
   945  
   946  #endif	/* _JIT_INTERNAL_H */