63 using namespace cacao;
68 #if defined(ENABLE_VERIFIER)
73 #define INDEX_ONEWORD(num) \
75 if (((num) < 0) || ((num) >= m->maxlocals)) \
76 goto throw_illegal_local_variable_number; \
79 #define INDEX_TWOWORD(num) \
81 if (((num) < 0) || (((num) + 1) >= m->maxlocals)) \
82 goto throw_illegal_local_variable_number; \
88 #define CHECK_BYTECODE_INDEX(i) \
90 if (((i) < 0) || ((i) >= m->jcodelength)) \
91 goto throw_invalid_bytecode_index; \
96 #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) \
98 if ((i) < 0 || (i) > m->jcodelength) \
99 goto throw_invalid_bytecode_index; \
104 #define INDEX_ONEWORD(num)
105 #define INDEX_TWOWORD(num)
106 #define CHECK_BYTECODE_INDEX(i)
107 #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i)
114 #define MARK_BASICBLOCK(pd, i) \
116 (pd)->basicblockstart[(i)] = 1; \
119 #define INSTRUCTIONS_CHECK(i) \
120 if ((ircount + (i)) > pd.instructionslength) \
121 iptr = parse_realloc_instructions(&pd, ircount, (i))
143 #define OP_PREPARE_FLAGS(o, f) \
144 iptr->opc = (ICMD) (o); \
145 iptr->line = currentline; \
146 iptr->flags.bits |= (f) | (ircount << INS_FLAG_ID_SHIFT);
148 #define OP_PREPARE_ZEROFLAGS(o) \
149 OP_PREPARE_FLAGS(o, 0)
151 #define OP_PREPARE(o) \
152 OP_PREPARE_ZEROFLAGS(o)
155 OP_PREPARE_ZEROFLAGS(o); \
158 #define OP_CHECK_EXCEPTION(o) \
159 OP_PREPARE_FLAGS(o, INS_FLAG_CHECK); \
162 #define OP_LOADCONST_I(v) \
163 OP_PREPARE_ZEROFLAGS(ICMD_ICONST); \
164 iptr->sx.val.i = (v); \
167 #define OP_LOADCONST_L(v) \
168 OP_PREPARE_ZEROFLAGS(ICMD_LCONST); \
169 iptr->sx.val.l = (v); \
172 #define OP_LOADCONST_F(v) \
173 OP_PREPARE_ZEROFLAGS(ICMD_FCONST); \
174 iptr->sx.val.f = (v); \
177 #define OP_LOADCONST_D(v) \
178 OP_PREPARE_ZEROFLAGS(ICMD_DCONST); \
179 iptr->sx.val.d = (v); \
182 #define OP_LOADCONST_NULL() \
183 OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \
184 iptr->sx.val.anyptr = NULL; \
187 #define OP_LOADCONST_STRING(v) \
188 OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \
189 iptr->sx.val.stringconst = (v); \
192 #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS(cl, cr, extraflags) \
193 OP_PREPARE(ICMD_ACONST); \
195 iptr->sx.val.c.cls = (cl); \
196 iptr->flags.bits |= INS_FLAG_CLASS | (extraflags); \
199 iptr->sx.val.c.ref = (cr); \
200 iptr->flags.bits |= INS_FLAG_CLASS | INS_FLAG_UNRESOLVED \
205 #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr) \
206 OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), INS_FLAG_CHECK)
208 #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr) \
209 OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), 0)
211 #define OP_S3_CLASSINFO_OR_CLASSREF(o, c, cr, extraflags) \
214 iptr->sx.s23.s3.c.cls= (c); \
215 iptr->flags.bits |= (extraflags); \
218 iptr->sx.s23.s3.c.ref= (cr); \
219 iptr->flags.bits |= INS_FLAG_UNRESOLVED | (extraflags); \
223 #define OP_INSINDEX(o, iindex) \
224 OP_PREPARE_ZEROFLAGS(o); \
225 iptr->dst.insindex = (iindex); \
228 # define OP_LOCALINDEX(o,index) \
229 OP_PREPARE_ZEROFLAGS(o); \
230 iptr->s1.varindex = (index); \
233 # define OP_LOCALINDEX_I(o,index,v) \
234 OP_PREPARE_ZEROFLAGS(o); \
235 iptr->s1.varindex = (index); \
236 iptr->sx.val.i = (v); \
239 # define LOCALTYPE_USED(index,type) \
241 local_map[(index) * 5 + (type)] = 1; \
244 #define OP_LOAD_ONEWORD(o,index,type) \
246 INDEX_ONEWORD(index); \
247 OP_LOCALINDEX(o,index); \
248 LOCALTYPE_USED(index,type); \
251 #define OP_LOAD_TWOWORD(o,index,type) \
253 INDEX_TWOWORD(index); \
254 OP_LOCALINDEX(o,index); \
255 LOCALTYPE_USED(index,type); \
258 # define OP_STORE_ONEWORD(o,index,type) \
260 INDEX_ONEWORD(index); \
261 OP_PREPARE_ZEROFLAGS(o); \
262 iptr->dst.varindex = (index); \
263 LOCALTYPE_USED(index,type); \
267 # define OP_STORE_TWOWORD(o,index,type) \
269 INDEX_TWOWORD(index); \
270 OP_PREPARE_ZEROFLAGS(o); \
271 iptr->dst.varindex = (index); \
272 LOCALTYPE_USED(index,type); \
276 #define OP_BUILTIN_CHECK_EXCEPTION(BTE) \
277 code_unflag_leafmethod(code); \
278 OP_PREPARE_FLAGS(ICMD_BUILTIN, INS_FLAG_CHECK); \
279 iptr->sx.s23.s3.bte = (BTE); \
282 #define OP_BUILTIN_NO_EXCEPTION(BTE) \
283 code_unflag_leafmethod(code); \
284 OP_PREPARE_ZEROFLAGS(ICMD_BUILTIN); \
285 iptr->sx.s23.s3.bte = (BTE); \
288 #define OP_BUILTIN_ARITHMETIC(opcode, BTE) \
289 code_unflag_leafmethod(code); \
290 OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK); \
291 iptr->sx.s23.s3.bte = (BTE); \
295 #define OP_FMIREF_PREPARE(o, FMIREF) \
297 iptr->sx.s23.s3.fmiref = (FMIREF);
300 #define INSTRUCTIONS_INCREMENT 5
306 #define BYTECODEINDEX_TO_BASICBLOCK(dst) \
309 parse_bytecodeindex_to_basicblock(jd, &pd, (dst).insindex); \
454 for (
s4 i = 0;
i < len; ++
i, ++rex) {
462 bcindex = rex->
endpc;
467 #if defined(ENABLE_VERIFIER)
468 if (bcindex <= rex->startpc) {
478 if (bcindex < m->jcodelength)
494 #if defined(ENABLE_VERIFIER)
495 throw_invalid_bytecode_index:
497 "Illegal bytecode index in exception table");
544 for (
s4 i = 0;
i < len; ++
i, ++rex, ++ex) {
553 if (rex->catchtype.any != NULL) {
563 rex->catchtype.cls = exclass;
594 #if defined(ENABLE_VERIFIER)
595 #define CHECK_END_OF_BYTECODE(neededlength) \
597 if ((neededlength) > m->jcodelength) \
598 goto throw_unexpected_end_of_bytecode; \
601 #define CHECK_END_OF_BYTECODE(neededlength)
647 local_map[i * 5 + 0] = 0;
648 local_map[i * 5 + 1] = 0;
649 local_map[i * 5 + 2] = 0;
650 local_map[i * 5 + 3] = 0;
651 local_map[i * 5 + 4] = 0;
689 for (bcindex = 0; bcindex < m->
jcodelength; bcindex = nextbc) {
699 if (linepcchange == bcindex) {
704 if (lineindex < m->linenumbercount) {
706 if (linepcchange == bcindex)
707 goto next_linenumber;
724 if (blockend && (opcode !=
BC_nop)) {
793 goto pushconstantitem;
802 #if defined(ENABLE_VERIFIER)
805 "Attempt to access constant outside range");
840 #if defined(ENABLE_VERIFIER)
947 if (iswide ==
false) {
952 nextbc = bcindex + 3;
963 if (iswide ==
false) {
968 nextbc = bcindex + 3;
1016 if (iswide ==
false) {
1021 nextbc = bcindex + 3;
1030 if (iswide ==
false) {
1035 nextbc = bcindex + 3;
1080 if (iswide ==
false) {
1086 nextbc = bcindex + 5;
1131 #if defined(ENABLE_VERIFIER)
1227 iptr->
sx.
s23.s3.jsrtarget.insindex =
i;
1238 iptr->
sx.
s23.s3.jsrtarget.insindex =
i;
1246 if (iswide ==
false) {
1250 nextbc = bcindex + 3;
1280 #if defined(ENABLE_VERIFIER)
1295 iptr->
sx.
s23.s3.lookupdefault.insindex = j;
1301 iptr->
sx.
s23.s2.lookupcount = num;
1313 for (
u4 i = 0; i < num; i++) {
1317 lookup->
value = value;
1321 #if defined(ENABLE_VERIFIER)
1324 if (i && (value <= prevvalue)) {
1362 iptr->
sx.
s23.s2.tablelow = lo;
1368 iptr->
sx.
s23.s3.tablehigh = hi;
1373 s8 num = ((
s8) hi) - ((
s8) lo) + 1;
1375 #if defined(ENABLE_VERIFIER)
1386 (table++)->insindex = deftarget;
1392 for (
s4 i = 0; i < num; i++) {
1396 (table++)->insindex = j;
1423 iptr->
sx.
s23.s3.fmiref = fmi;
1427 #if defined(ENABLE_VERIFIER)
1443 iptr->
sx.
s23.s3.uf = uf;
1446 #if defined(ENABLE_VERIFIER)
1478 goto invoke_nonstatic_method;
1487 goto invoke_nonstatic_method;
1498 invoke_nonstatic_method:
1509 iptr->
sx.
s23.s3.fmiref = fmi;
1513 #if defined(ENABLE_VERIFIER)
1527 assert(iptr->
sx.
s23.s3.fmiref->is_resolved());
1543 iptr->
sx.
s23.s3.um = um;
1546 #if defined(ENABLE_VERIFIER)
1587 if (cr->
name[0] ==
'[') {
1611 if (cr->
name[0] ==
'[') {
1651 #if !SUPPORT_DIVISION
1655 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1665 #if !SUPPORT_DIVISION
1669 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1679 #if !(SUPPORT_DIVISION && SUPPORT_LONG_DIV)
1683 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1693 #if !(SUPPORT_DIVISION && SUPPORT_LONG_DIV)
1697 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1707 #if defined(__I386__)
1717 #if defined(__I386__)
1727 #if defined(__ALPHA__)
1737 #if defined(__ALPHA__)
1747 #if defined(__ALPHA__)
1757 #if defined(__ALPHA__)
1770 #if defined(ENABLE_VERIFIER)
1862 #if defined(ENABLE_VERIFIER)
1888 #if defined(ENABLE_VERIFIER)
1891 "Command-sequence crosses code-boundary");
1921 for (bcindex = 0; bcindex < m->
jcodelength; bcindex++) {
1926 #if defined(ENABLE_VERIFIER)
1932 "Branch into middle of instruction");
1958 for (
s4 i = 0; i < ircount; i++, iptr++) {
1985 for (
s4 i = 0; i < ircount; i++, iptr++) {
2001 bptr->
nr = bbcount++;
2003 bptr[-1].
next = bptr;
2008 switch (iptr->
opc) {
2039 s4 j = iptr->
sx.
s23.s3.tablehigh - iptr->
sx.
s23.s2.tablelow + 1;
2053 s4 j = iptr->
sx.
s23.s2.lookupcount;
2101 for (
s4 i = 0; i < (m->
maxlocals * 5); i++, mapptr++) {
2103 *mapptr = nlocals++;
2129 #if defined(ENABLE_VERIFIER)
2144 for (
s4 t=0; t<5; t++) {
2145 varindex = local_map[5*i + t];
2147 VAR(varindex)->type = (
Type) t;
2148 reversemap[varindex] =
i;
2172 #if defined(ENABLE_VERIFIER)
2174 throw_unexpected_end_of_bytecode:
2178 throw_invalid_bytecode_index:
2182 throw_illegal_local_variable_number:
void exceptions_throw_verifyerror(methodinfo *m, const char *message,...)
static void parse_setup(jitdata *jd, parsedata_t *pd)
official tags from JVM spec
static bool parse_mark_exception_boundaries(jitdata *jd, parsedata_t *pd)
void * class_getconstant(classinfo *c, u4 pos, ConstantPoolTag ctype)
#define BASICBLOCK_INIT(bptr, m)
#define JITDATA_HAS_FLAG_REORDER(jd)
#define MSET(ptr, byte, type, num)
unresolved_field * resolve_create_unresolved_field(classinfo *referer, methodinfo *refmethod, instruction *iptr)
exception_entry * exceptiontable
#define OP_S3_CLASSINFO_OR_CLASSREF(o, c, cr, extraflags)
#define BUILTIN_newarray_float
s4 rawexceptiontablelength
#define OP_LOADCONST_I(v)
#define INSTRUCTION_STARTS_BASICBLOCK(iptr)
#define OP_LOAD_TWOWORD(o, index, type)
#define OP_INSINDEX(o, iindex)
unresolved_method * resolve_create_unresolved_method(classinfo *referer, methodinfo *refmethod, constant_FMIref *methodref, bool invokestatic, bool invokespecial)
resolve_result_t resolve_field_lazy(methodinfo *refmethod, constant_FMIref *fieldref)
bool resolve_classref(methodinfo *refmethod, constant_classref *ref, resolve_mode_t mode, bool checkaccess, bool link, classinfo **result)
#define OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr)
#define OP_CHECK_EXCEPTION(o)
#define OP_PREPARE_ZEROFLAGS(o)
#define BUILTIN_newarray_long
#define OP_BUILTIN_ARITHMETIC(opcode, BTE)
static void code_unflag_leafmethod(codeinfo *code)
Breakpoint * get_breakpoint(int32_t location)
#define BUILTIN_newarray_char
static instruction * parse_realloc_instructions(parsedata_t *pd, s4 icount, s4 n)
#define OP_LOADCONST_NULL()
#define MZERO(ptr, type, num)
#define BUILTIN_newarray_byte
#define OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr)
#define OP_LOADCONST_F(v)
#define CHECK_BYTECODE_INDEX_EXCLUSIVE(i)
raw_exception_entry * rawexceptiontable
#define OP_BUILTIN_NO_EXCEPTION(BTE)
static basicblock * parse_bytecodeindex_to_basicblock(jitdata *jd, parsedata_t *pd, s4 bcindex)
#define OP_PREPARE_FLAGS(o, f)
builtintable_entry * builtintable_get_internal(functionptr fp)
resolve_result_t resolve_method_lazy(methodinfo *refmethod, constant_FMIref *methodref, bool invokespecial)
#define CHECK_BYTECODE_INDEX(i)
#define LOCALTYPE_USED(index, type)
#define OP_LOAD_ONEWORD(o, index, type)
#define LOCK_monitor_enter
static uint8_t read_u1_be(const uint8_t *src)
read uint8_t from pointer big endian
This file contains the statistics framework.
#define INSTRUCTIONS_CHECK(i)
#define OP_LOCALINDEX_I(o, index, v)
#define BUILTIN_newarray_boolean
static void * reallocate(void *src, size_t len1, size_t len2)
Stupid realloc implementation for dump memory.
#define JITDATA_HAS_FLAG_VERIFY(jd)
Type
Types used internally by JITTED code.
#define OP_LOADCONST_L(v)
#define OP_BUILTIN_CHECK_EXCEPTION(BTE)
static int16_t read_s2_be(const uint8_t *src)
read int16_t from pointer big endian
classref_or_classinfo catchtype
bool contains(int32_t location)
#define VERIFIER_EXTRA_LOCALS
Fieldref, Methodref and InterfaceMethodref.
static uint16_t read_u2_be(const uint8_t *src)
read uint16_t from pointer big endian
#define OP_STORE_ONEWORD(o, index, type)
union instruction::@12 sx
#define BUILTIN_arrayinstanceof
#define BUILTIN_newarray_int
#define OP_LOADCONST_D(v)
void params_from_paramtypes(s4 mflags)
#define LOCK_monitor_exit
#define INSTRUCTIONS_INCREMENT
static bool parse_resolve_exception_table(jitdata *jd, parsedata_t *pd)
instruction * instructions
#define BUILTIN_newarray_double
#define MARK_BASICBLOCK(pd, i)
#define OP_LOADCONST_STRING(v)
#define BUILTIN_newarray_short
static void * allocate(size_t size)
#define MEMORY_ALIGN(pos, size)
bool resolve_classref_or_classinfo(methodinfo *refmethod, classref_or_classinfo cls, resolve_mode_t mode, bool checkaccess, bool link, classinfo **result)
struct instruction::@12::@13 s23
const parseddesc_t parseddesc
BreakpointTable * breakpoints
#define BYTECODEINDEX_TO_BASICBLOCK(dst)
#define INDEX_ONEWORD(num)
#define OP_STORE_TWOWORD(o, index, type)
static int32_t read_s4_be(const uint8_t *src)
read int32_t from pointer big endian
static JavaString literal(Utf8String)
instruction * instructions
#define CHECK_END_OF_BYTECODE(neededlength)
constant_classref * class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
static uint32_t read_u4_be(const uint8_t *src)
read uint32_t from pointer big endian
#define VERIFIER_EXTRA_VARS
static int8_t read_s1_be(const uint8_t *src)
read int8_t from pointer big endian