/* * jit-interp.h - Bytecode interpreter for platforms without native support. * * Copyright (C) 2004 Southern Storm Software, Pty Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _JIT_INTERP_H #define _JIT_INTERP_H #include "jit-internal.h" #include "jit-apply-rules.h" #ifdef __cplusplus extern "C" { #endif /* * Structure of a stack item. */ typedef union { jit_int int_value; jit_uint uint_value; jit_long long_value; jit_ulong ulong_value; jit_float32 float32_value; jit_float64 float64_value; jit_nfloat nfloat_value; void *ptr_value; #if JIT_APPLY_MAX_STRUCT_IN_REG != 0 char struct_value[JIT_APPLY_MAX_STRUCT_IN_REG]; #endif } jit_item; /* * Number of items that make up a struct or union value on the stack. */ #define JIT_NUM_ITEMS_IN_STRUCT(size) \ (((size) + (sizeof(jit_item) - 1)) / sizeof(jit_item)) /* * Information that is prefixed to a function that describes * its interpretation context. The code starts just after this. */ typedef struct jit_function_interp *jit_function_interp_t; struct jit_function_interp { /* The function that this structure is associated with */ jit_function_t func; /* Size of the argument area to allocate, in bytes */ unsigned int args_size; /* Size of the local stack frame to allocate, in bytes */ unsigned int frame_size; /* Size of the working stack area of the frame, in items */ unsigned int working_area; }; /* * Get the size of the "jit_function_interp" structure, rounded * up to a multiple of "void *". */ #define jit_function_interp_size \ ((sizeof(struct jit_function_interp) + sizeof(void *) - 1) & \ ~(sizeof(void *) - 1)) /* * Get the entry point for a function, from its "jit_function_interp_t" block. */ #define jit_function_interp_entry_pc(info) \ ((void **)(((unsigned char *)(info)) + jit_function_interp_size)) /* * Argument variable access opcodes. */ #define JIT_OP_LDARG_SBYTE (JIT_OP_NUM_OPCODES + 0x0000) #define JIT_OP_LDARG_UBYTE (JIT_OP_NUM_OPCODES + 0x0001) #define JIT_OP_LDARG_SHORT (JIT_OP_NUM_OPCODES + 0x0002) #define JIT_OP_LDARG_USHORT (JIT_OP_NUM_OPCODES + 0x0003) #define JIT_OP_LDARG_INT (JIT_OP_NUM_OPCODES + 0x0004) #define JIT_OP_LDARG_LONG (JIT_OP_NUM_OPCODES + 0x0005) #define JIT_OP_LDARG_FLOAT32 (JIT_OP_NUM_OPCODES + 0x0006) #define JIT_OP_LDARG_FLOAT64 (JIT_OP_NUM_OPCODES + 0x0007) #define JIT_OP_LDARG_NFLOAT (JIT_OP_NUM_OPCODES + 0x0008) #define JIT_OP_LDARG_STRUCT (JIT_OP_NUM_OPCODES + 0x0009) #define JIT_OP_LDARGA (JIT_OP_NUM_OPCODES + 0x000A) #define JIT_OP_STARG_BYTE (JIT_OP_NUM_OPCODES + 0x000B) #define JIT_OP_STARG_SHORT (JIT_OP_NUM_OPCODES + 0x000C) #define JIT_OP_STARG_INT (JIT_OP_NUM_OPCODES + 0x000D) #define JIT_OP_STARG_LONG (JIT_OP_NUM_OPCODES + 0x000E) #define JIT_OP_STARG_FLOAT32 (JIT_OP_NUM_OPCODES + 0x000F) #define JIT_OP_STARG_FLOAT64 (JIT_OP_NUM_OPCODES + 0x0010) #define JIT_OP_STARG_NFLOAT (JIT_OP_NUM_OPCODES + 0x0011) #define JIT_OP_STARG_STRUCT (JIT_OP_NUM_OPCODES + 0x0012) /* * Local variable frame access opcodes. */ #define JIT_OP_LDLOC_SBYTE (JIT_OP_NUM_OPCODES + 0x0013) #define JIT_OP_LDLOC_UBYTE (JIT_OP_NUM_OPCODES + 0x0014) #define JIT_OP_LDLOC_SHORT (JIT_OP_NUM_OPCODES + 0x0015) #define JIT_OP_LDLOC_USHORT (JIT_OP_NUM_OPCODES + 0x0016) #define JIT_OP_LDLOC_INT (JIT_OP_NUM_OPCODES + 0x0017) #define JIT_OP_LDLOC_LONG (JIT_OP_NUM_OPCODES + 0x0018) #define JIT_OP_LDLOC_FLOAT32 (JIT_OP_NUM_OPCODES + 0x0019) #define JIT_OP_LDLOC_FLOAT64 (JIT_OP_NUM_OPCODES + 0x001A) #define JIT_OP_LDLOC_NFLOAT (JIT_OP_NUM_OPCODES + 0x001B) #define JIT_OP_LDLOC_STRUCT (JIT_OP_NUM_OPCODES + 0x001C) #define JIT_OP_LDLOCA (JIT_OP_NUM_OPCODES + 0x001D) #define JIT_OP_STLOC_BYTE (JIT_OP_NUM_OPCODES + 0x001E) #define JIT_OP_STLOC_SHORT (JIT_OP_NUM_OPCODES + 0x001F) #define JIT_OP_STLOC_INT (JIT_OP_NUM_OPCODES + 0x0020) #define JIT_OP_STLOC_LONG (JIT_OP_NUM_OPCODES + 0x0021) #define JIT_OP_STLOC_FLOAT32 (JIT_OP_NUM_OPCODES + 0x0022) #define JIT_OP_STLOC_FLOAT64 (JIT_OP_NUM_OPCODES + 0x0023) #define JIT_OP_STLOC_NFLOAT (JIT_OP_NUM_OPCODES + 0x0024) #define JIT_OP_STLOC_STRUCT (JIT_OP_NUM_OPCODES + 0x0025) /* * Pointer check opcodes (interpreter only). */ #define JIT_OP_CHECK_NULL_N (JIT_OP_NUM_OPCODES + 0x0026) /* * Stack management. */ #define JIT_OP_POP (JIT_OP_NUM_OPCODES + 0x0027) #define JIT_OP_POP_2 (JIT_OP_NUM_OPCODES + 0x0028) #define JIT_OP_POP_3 (JIT_OP_NUM_OPCODES + 0x0029) #define JIT_OP_PUSH_RETURN_INT (JIT_OP_NUM_OPCODES + 0x002A) #define JIT_OP_PUSH_RETURN_LONG (JIT_OP_NUM_OPCODES + 0x002B) #define JIT_OP_PUSH_RETURN_FLOAT32 (JIT_OP_NUM_OPCODES + 0x002C) #define JIT_OP_PUSH_RETURN_FLOAT64 (JIT_OP_NUM_OPCODES + 0x002D) #define JIT_OP_PUSH_RETURN_NFLOAT (JIT_OP_NUM_OPCODES + 0x002E) #define JIT_OP_PUSH_RETURN_SMALL_STRUCT (JIT_OP_NUM_OPCODES + 0x002F) /* * Nested function call handling. */ #define JIT_OP_IMPORT_LOCAL (JIT_OP_NUM_OPCODES + 0x0030) #define JIT_OP_IMPORT_ARG (JIT_OP_NUM_OPCODES + 0x0031) /* * Push constant values onto the stack. */ #define JIT_OP_PUSH_CONST_INT (JIT_OP_NUM_OPCODES + 0x0032) #define JIT_OP_PUSH_CONST_LONG (JIT_OP_NUM_OPCODES + 0x0033) #define JIT_OP_PUSH_CONST_FLOAT32 (JIT_OP_NUM_OPCODES + 0x0034) #define JIT_OP_PUSH_CONST_FLOAT64 (JIT_OP_NUM_OPCODES + 0x0035) #define JIT_OP_PUSH_CONST_NFLOAT (JIT_OP_NUM_OPCODES + 0x0036) /* * Marker opcode for the end of the interpreter-specific opcodes. */ #define JIT_OP_END_MARKER (JIT_OP_NUM_OPCODES + 0x0037) /* * Number of interpreter-specific opcodes. */ #define JIT_OP_NUM_INTERP_OPCODES \ (JIT_OP_END_MARKER + 1 - JIT_OP_NUM_OPCODES) /* * Opcode version. Should be increased whenever new opcodes * are added to this list or the public list in "jit-opcode.h". * This value is written to ELF binaries, to ensure that code * for one version of libjit is not inadvertantly used in another. */ #define JIT_OPCODE_VERSION 0 /* * Additional opcode definition flags. */ #define JIT_OPCODE_INTERP_ARGS_MASK 0x7E000000 #define JIT_OPCODE_NINT_ARG 0x02000000 #define JIT_OPCODE_NINT_ARG_TWO 0x04000000 #define JIT_OPCODE_CONST_LONG 0x06000000 #define JIT_OPCODE_CONST_FLOAT32 0x08000000 #define JIT_OPCODE_CONST_FLOAT64 0x0A000000 #define JIT_OPCODE_CONST_NFLOAT 0x0C000000 #define JIT_OPCODE_CALL_INDIRECT_ARGS 0x0E000000 #ifdef __cplusplus }; #endif #endif /* _JIT_INTERP_H */