/* src/vm/jit/parse.h - parser header Copyright (C) 1996-2005, 2006, 2008 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _PARSE_H #define _PARSE_H #include "config.h" #include "vm/types.h" #include "vm/global.h" #include "vm/jit/codegen-common.hpp" /* macros for verifier checks during parsing **********************************/ #if defined(ENABLE_VERIFIER) /* We have to check local variables indices here because they are */ /* used in stack.c to index the locals array. */ #define INDEX_ONEWORD(num) \ do { \ if (((num) < 0) || ((num) >= m->maxlocals)) \ goto throw_illegal_local_variable_number; \ } while (0) #define INDEX_TWOWORD(num) \ do { \ if (((num) < 0) || (((num) + 1) >= m->maxlocals)) \ goto throw_illegal_local_variable_number; \ } while (0) /* CHECK_BYTECODE_INDEX(i) checks whether i is a valid bytecode index. */ /* The end of the bytecode (i == m->jcodelength) is considered valid. */ #define CHECK_BYTECODE_INDEX(i) \ do { \ if (((i) < 0) || ((i) >= m->jcodelength)) \ goto throw_invalid_bytecode_index; \ } while (0) /* CHECK_BYTECODE_INDEX_EXCLUSIVE is used for the exclusive ends */ /* of exception handler ranges. */ #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) \ do { \ if ((i) < 0 || (i) > m->jcodelength) \ goto throw_invalid_bytecode_index; \ } while (0) #else /* !defined(ENABLE_VERIFIER) */ #define INDEX_ONEWORD(num) #define INDEX_TWOWORD(num) #define CHECK_BYTECODE_INDEX(i) #define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) #endif /* defined(ENABLE_VERIFIER) */ /* basic block generating macro ***********************************************/ #define MARK_BASICBLOCK(pd, i) \ do { \ (pd)->basicblockstart[(i)] = 1; \ } while (0) #define INSTRUCTIONS_CHECK(i) \ if ((ircount + (i)) > pd.instructionslength) \ iptr = parse_realloc_instructions(&pd, ircount, (i)) /* intermediate code generating macros ****************************************/ /* These macros ALWAYS set the following fields of *iptr to valid values: */ /* iptr->opc */ /* iptr->flags */ /* iptr->line */ /* These macros do NOT touch the following fields of *iptr, unless a value is */ /* given for them: */ /* iptr->s1 */ /* iptr->sx */ /* iptr->dst */ /* The _PREPARE macros omit the PINC, so you can set additional fields */ /* afterwards. */ #define PINC \ iptr++; ircount++ #define OP_PREPARE_FLAGS(o, f) \ iptr->opc = (o); \ iptr->line = currentline; \ iptr->flags.bits |= (f) | (ircount << INS_FLAG_ID_SHIFT); #define OP_PREPARE_ZEROFLAGS(o) \ OP_PREPARE_FLAGS(o, 0) #define OP_PREPARE(o) \ OP_PREPARE_ZEROFLAGS(o) #define OP(o) \ OP_PREPARE_ZEROFLAGS(o); \ PINC #define OP_CHECK_EXCEPTION(o) \ OP_PREPARE_FLAGS(o, INS_FLAG_CHECK); \ PINC #define OP_LOADCONST_I(v) \ OP_PREPARE_ZEROFLAGS(ICMD_ICONST); \ iptr->sx.val.i = (v); \ PINC #define OP_LOADCONST_L(v) \ OP_PREPARE_ZEROFLAGS(ICMD_LCONST); \ iptr->sx.val.l = (v); \ PINC #define OP_LOADCONST_F(v) \ OP_PREPARE_ZEROFLAGS(ICMD_FCONST); \ iptr->sx.val.f = (v); \ PINC #define OP_LOADCONST_D(v) \ OP_PREPARE_ZEROFLAGS(ICMD_DCONST); \ iptr->sx.val.d = (v); \ PINC #define OP_LOADCONST_NULL() \ OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ iptr->sx.val.anyptr = NULL; \ PINC #define OP_LOADCONST_STRING(v) \ OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ iptr->sx.val.stringconst = (v); \ PINC #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS(cl, cr, extraflags) \ OP_PREPARE(ICMD_ACONST); \ if (cl) { \ iptr->sx.val.c.cls = (cl); \ iptr->flags.bits |= INS_FLAG_CLASS | (extraflags); \ } \ else { \ iptr->sx.val.c.ref = (cr); \ iptr->flags.bits |= INS_FLAG_CLASS | INS_FLAG_UNRESOLVED \ | (extraflags); \ } \ PINC #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr) \ OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), INS_FLAG_CHECK) #define OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr) \ OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), 0) #define OP_S3_CLASSINFO_OR_CLASSREF(o, c, cr, extraflags) \ OP_PREPARE(o); \ if (c) { \ iptr->sx.s23.s3.c.cls= (c); \ iptr->flags.bits |= (extraflags); \ } \ else { \ iptr->sx.s23.s3.c.ref= (cr); \ iptr->flags.bits |= INS_FLAG_UNRESOLVED | (extraflags); \ } \ PINC #define OP_INSINDEX(o, iindex) \ OP_PREPARE_ZEROFLAGS(o); \ iptr->dst.insindex = (iindex); \ PINC # define OP_LOCALINDEX(o,index) \ OP_PREPARE_ZEROFLAGS(o); \ iptr->s1.varindex = (index); \ PINC # define OP_LOCALINDEX_I(o,index,v) \ OP_PREPARE_ZEROFLAGS(o); \ iptr->s1.varindex = (index); \ iptr->sx.val.i = (v); \ PINC # define LOCALTYPE_USED(index,type) \ do { \ local_map[(index) * 5 + (type)] = 1; \ } while (0) #define OP_LOAD_ONEWORD(o,index,type) \ do { \ INDEX_ONEWORD(index); \ OP_LOCALINDEX(o,index); \ LOCALTYPE_USED(index,type); \ } while (0) #define OP_LOAD_TWOWORD(o,index,type) \ do { \ INDEX_TWOWORD(index); \ OP_LOCALINDEX(o,index); \ LOCALTYPE_USED(index,type); \ } while (0) # define OP_STORE_ONEWORD(o,index,type) \ do { \ INDEX_ONEWORD(index); \ OP_PREPARE_ZEROFLAGS(o); \ iptr->dst.varindex = (index); \ LOCALTYPE_USED(index,type); \ PINC; \ } while (0) # define OP_STORE_TWOWORD(o,index,type) \ do { \ INDEX_TWOWORD(index); \ OP_PREPARE_ZEROFLAGS(o); \ iptr->dst.varindex = (index); \ LOCALTYPE_USED(index,type); \ PINC; \ } while (0) #define OP_BUILTIN_CHECK_EXCEPTION(bte) \ code_unflag_leafmethod(code); \ OP_PREPARE_FLAGS(ICMD_BUILTIN, INS_FLAG_CHECK); \ iptr->sx.s23.s3.bte = (bte); \ PINC #define OP_BUILTIN_NO_EXCEPTION(bte) \ code_unflag_leafmethod(code); \ OP_PREPARE_ZEROFLAGS(ICMD_BUILTIN); \ iptr->sx.s23.s3.bte = (bte); \ PINC #define OP_BUILTIN_ARITHMETIC(opcode, bte) \ code_unflag_leafmethod(code); \ OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK); \ iptr->sx.s23.s3.bte = (bte); \ PINC /* CAUTION: You must set iptr->flags yourself when using this! */ #define OP_FMIREF_PREPARE(o, fmiref) \ OP_PREPARE(o); \ iptr->sx.s23.s3.fmiref = (fmiref); /* function prototypes ********************************************************/ #ifdef __cplusplus extern "C" { #endif bool parse(jitdata *jd); #ifdef __cplusplus } #endif #endif /* _PARSE_H */ /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: * mode: c * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 * End: * vim:noexpandtab:sw=4:ts=4: */