Changes: Christian Ullrich
- $Id: stack.h 5303 2006-09-05 10:39:58Z edwin $
+ $Id: stack.h 5404 2006-09-07 13:29:05Z christian $
*/
* against maximum stack depth only at block boundaries?
*/
-/* XXX we should find a way to remove the opc/op1 check */
-#if defined(ENABLE_VERIFIER)
-#define NEW_CHECKOVERFLOW \
- do { \
- if (stackdepth > m->maxstack) \
- if ((iptr->opc != ICMD_ACONST) || !(iptr->flags.bits & INS_FLAG_NOCHECK)) \
- goto throw_stack_overflow; \
- } while(0)
-#else /* !ENABLE_VERIFIER */
-#define NEW_CHECKOVERFLOW
-#endif /* ENABLE_VERIFIER */
-
/* XXX we should find a way to remove the opc/op1 check */
#if defined(ENABLE_VERIFIER)
#define CHECKOVERFLOW \
do { \
if (stackdepth > m->maxstack) \
- if ((iptr[0].opc != ICMD_ACONST) || (iptr[0].op1 == 0)) \
+ if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr)) \
goto throw_stack_overflow; \
} while(0)
#else /* !ENABLE_VERIFIER */
/* ALLOCATING STACK SLOTS */
/*--------------------------------------------------*/
-#define NEWSTACK(s,v,n) \
+#define NEWSTACK(s,v,n) \
do { \
new->prev = curstack; \
new->type = (s); \
new->varkind = (v); \
new->varnum = (n); \
curstack = new; \
+ jd->var[(n)].type = (s); \
+ jd->var[(n)].flags = 0; \
new++; \
} while (0)
/* allocate the input stack for an exception handler */
#define NEWXSTACK {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
-
/*--------------------------------------------------*/
/* STACK MANIPULATION */
/*--------------------------------------------------*/
} while (0)
-/*--------------------------------------------------*/
-/* STACK OPERATIONS MODELING */
-/*--------------------------------------------------*/
-
-/* The following macros are used to model the stack manipulations of
- * different kinds of instructions.
- *
- * These macros check the input stackdepth and they set the output
- * stackdepth and the output stack of the instruction (iptr->dst).
- *
- * These macros do *not* check for stack overflows!
- */
-
-#define PUSHCONST(s){NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
-#define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
-#define STORE(s) {REQUIRE_1;POP(s);SETDST;stackdepth--;}
-
-#define OP1_0(s) \
- do { \
- REQUIRE_1; \
- POP(s); \
- SETDST; \
- stackdepth--; \
- } while (0)
-
-#define OP1_0ANY \
- do { \
- REQUIRE_1; \
- POPANY; \
- SETDST; \
- stackdepth--; \
- } while (0)
-
-#define OP0_1(s) \
- do { \
- NEWSTACKn(s, stackdepth); \
- SETDST; \
- stackdepth++; \
- } while (0)
-
-#define OP1_1(s,d) \
- do { \
- REQUIRE_1; \
- POP(s); \
- NEWSTACKn(d, stackdepth - 1);\
- SETDST; \
- } while (0)
-
-#define OP2_0(s) \
- do { \
- REQUIRE_2; \
- POP(s); \
- POP(s); \
- SETDST; \
- stackdepth -= 2; \
- } while (0)
-
-#define OPTT2_0(t,b) \
- do { \
- REQUIRE_2; \
- POP(t); \
- POP(b); \
- SETDST; \
- stackdepth -= 2; \
- } while (0)
-
-#define OP2_1(s) \
- do { \
- REQUIRE_2; \
- POP(s); \
- POP(s); \
- NEWSTACKn(s, stackdepth - 2); \
- SETDST; \
- stackdepth--; \
- } while (0)
-
-#define OP2IAT_1(s) \
- do { \
- REQUIRE_2; \
- POP(TYPE_INT); \
- POP(TYPE_ADR); \
- NEWSTACKn(s, stackdepth - 2); \
- SETDST; \
- stackdepth--; \
- } while (0)
-
-#define OP2IT_1(s) \
- do { \
- REQUIRE_2; \
- POP(TYPE_INT); \
- POP(s); \
- NEWSTACKn(s, stackdepth - 2); \
- SETDST; \
- stackdepth--; \
- } while (0)
-
-#define OPTT2_1(s,d) \
- do { \
- REQUIRE_2; \
- POP(s); \
- POP(s); \
- NEWSTACKn(d, stackdepth - 2); \
- SETDST; \
- stackdepth--; \
- } while (0)
-
-#define OP2_2(s) \
- do { \
- REQUIRE_2; \
- POP(s); \
- POP(s); \
- NEWSTACKn(s, stackdepth - 2); \
- NEWSTACKn(s, stackdepth - 1); \
- SETDST; \
- } while (0)
-
-#define OP3TIA_0(s) \
- do { \
- REQUIRE_3; \
- POP(s); \
- POP(TYPE_INT); \
- POP(TYPE_ADR); \
- SETDST; \
- stackdepth -= 3; \
- } while (0)
-
-#define OP3_0(s) \
- do { \
- REQUIRE_3; \
- POP(s); \
- POP(s); \
- POP(s); \
- SETDST; \
- stackdepth -= 3; \
- } while (0)
-
-#define POPMANY(i) \
- do { \
- REQUIRE((i)); \
- stackdepth -= (i); \
- while(--(i) >= 0) { \
- POPANY; \
- } \
- SETDST; \
- } while (0)
-
-/* Do not copy Interface Stackslots over DUP! */
-#define DUP {REQUIRE_1; \
- if (CURKIND != STACKVAR) { \
- NEWSTACK(CURTYPE,CURKIND,curstack->varnum); \
- } else { \
- NEWSTACK(CURTYPE, TEMPVAR, stackdepth); \
- } \
- SETDST; stackdepth++;}
-#define SWAP {REQUIRE_2;COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
- new[0].prev=curstack;new[1].prev=new;\
- curstack=new+1;new+=2;SETDST;}
-#define DUP_X1 {REQUIRE_2;COPY(curstack,new);COPY(curstack,new+2);POPANY;\
- COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
- new[1].prev=new;new[2].prev=new+1;\
- curstack=new+2;new+=3;SETDST;stackdepth++;}
-#define DUP2_X1 {REQUIRE_3;COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
- COPY(curstack,new);COPY(curstack,new+3);POPANY;\
- COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
- new[1].prev=new;new[2].prev=new+1;\
- new[3].prev=new+2;new[4].prev=new+3;\
- curstack=new+4;new+=5;SETDST;stackdepth+=2;}
-#define DUP_X2 {REQUIRE_3;COPY(curstack,new);COPY(curstack,new+3);POPANY;\
- COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
- new[0].prev=curstack;new[1].prev=new;\
- new[2].prev=new+1;new[3].prev=new+2;\
- curstack=new+3;new+=4;SETDST;stackdepth++;}
-#define DUP2_X2 {REQUIRE_4;COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
- COPY(curstack,new);COPY(curstack,new+4);POPANY;\
- COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
- new[0].prev=curstack;new[1].prev=new;\
- new[2].prev=new+1;new[3].prev=new+2;\
- new[4].prev=new+3;new[5].prev=new+4;\
- curstack=new+5;new+=6;SETDST;stackdepth+=2;}
-
-
/*--------------------------------------------------*/
/* MACROS FOR HANDLING BASIC BLOCKS */
/*--------------------------------------------------*/
* block to another. The destination block receives the copy as its
* input stack.
*/
-#define COPYCURSTACK(copy) {\
+#if defined(NEW_VAR)
+# define COPYCURSTACK(copy) {\
+ stackptr s;\
+ if(curstack){\
+ s=curstack;\
+ new+=stackdepth;\
+ copy=new;\
+ while(s){\
+ copy--; \
+ copy->prev=copy-1;\
+ copy->type=s->type;\
+ copy->flags=0;\
+ copy->varkind=STACKVAR;\
+ copy->varnum=s->varnum;\
+ SET_OUTVAR(s); \
+ s=s->prev;\
+ }\
+ copy->prev=NULL;\
+ copy=new-1;\
+ }\
+ else\
+ copy=NULL;\
+}
+#else
+# define COPYCURSTACK(copy) {\
int d;\
stackptr s;\
if(curstack){\
else\
copy=NULL;\
}
+#endif
/* MARKREACHED marks the destination block <b> as reached. If this
* block has been reached before we check if stack depth and types
* c...current stack
*/
+/* XXX this macro is much too big! */
+
#define MARKREACHED(b,c) \
do { \
if ((b) <= (bptr)) \
(b)->bitflags |= BBFLAG_REPLACEMENT; \
if ((b)->flags < BBREACHED) { \
+ int locali; \
COPYCURSTACK((c)); \
(b)->flags = BBREACHED; \
(b)->instack = (c); \
(b)->indepth = stackdepth; \
+ (b)->invars = DMNEW(s4, stackdepth); \
+ for (locali = stackdepth; locali--; (c) = (c)->prev) { \
+ (b)->invars[locali] = (c)->varnum; \
+ SET_OUTVAR((c)); \
+ } \
} else { \
stackptr s = curstack; \
stackptr t = (b)->instack; \
} while (0)
+/* external macros ************************************************************/
+
+#define BLOCK_OF(index) \
+ (jd->new_basicblocks + jd->new_basicblockindex[index])
+
+
/* function prototypes ********************************************************/
bool stack_init(void);