committed new stack modification method
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40122
This commit is contained in:
parent
2c65e42379
commit
ea6e82d79a
@ -1972,6 +1972,7 @@ static int declloc(int fstatic)
|
|||||||
} /* if */
|
} /* if */
|
||||||
markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
|
markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
|
||||||
modstk(-(int)size*sizeof(cell));
|
modstk(-(int)size*sizeof(cell));
|
||||||
|
markstack(MEMUSE_STATIC, size);
|
||||||
assert(curfunc!=NULL);
|
assert(curfunc!=NULL);
|
||||||
assert((curfunc->usage & uNATIVE)==0);
|
assert((curfunc->usage & uNATIVE)==0);
|
||||||
if (curfunc->x.stacksize<declared+1)
|
if (curfunc->x.stacksize<declared+1)
|
||||||
@ -3334,6 +3335,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
|
|||||||
sc_alignnext=FALSE;
|
sc_alignnext=FALSE;
|
||||||
} /* if */
|
} /* if */
|
||||||
declared=0; /* number of local cells */
|
declared=0; /* number of local cells */
|
||||||
|
resetstacklist();
|
||||||
rettype=(sym->usage & uRETVALUE); /* set "return type" variable */
|
rettype=(sym->usage & uRETVALUE); /* set "return type" variable */
|
||||||
curfunc=sym;
|
curfunc=sym;
|
||||||
define_args(); /* add the symbolic info for the function arguments */
|
define_args(); /* add the symbolic info for the function arguments */
|
||||||
@ -3361,7 +3363,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
|
|||||||
* has only a single statement in its body (no compound block) and that
|
* has only a single statement in its body (no compound block) and that
|
||||||
* statement declares a new variable
|
* statement declares a new variable
|
||||||
*/
|
*/
|
||||||
modstk((int)declared*sizeof(cell)); /* remove all local variables */
|
popstacklist();
|
||||||
declared=0;
|
declared=0;
|
||||||
} /* if */
|
} /* if */
|
||||||
if ((lastst!=tRETURN) && (lastst!=tGOTO)){
|
if ((lastst!=tRETURN) && (lastst!=tGOTO)){
|
||||||
@ -4770,6 +4772,7 @@ static void compound(int stmt_sameline,int starttok)
|
|||||||
int block_start=fline; /* save line where the compound block started */
|
int block_start=fline; /* save line where the compound block started */
|
||||||
int endtok;
|
int endtok;
|
||||||
|
|
||||||
|
pushstacklist();
|
||||||
/* if there is more text on this line, we should adjust the statement indent */
|
/* if there is more text on this line, we should adjust the statement indent */
|
||||||
if (stmt_sameline) {
|
if (stmt_sameline) {
|
||||||
int i;
|
int i;
|
||||||
@ -4808,8 +4811,9 @@ static void compound(int stmt_sameline,int starttok)
|
|||||||
} /* while */
|
} /* while */
|
||||||
if (lastst!=tRETURN)
|
if (lastst!=tRETURN)
|
||||||
destructsymbols(&loctab,nestlevel);
|
destructsymbols(&loctab,nestlevel);
|
||||||
if (lastst!=tRETURN && lastst!=tGOTO)
|
if (lastst!=tRETURN && lastst!=tGOTO) {
|
||||||
modstk((int)(declared-save_decl)*sizeof(cell)); /* delete local variable space */
|
popstacklist();
|
||||||
|
}
|
||||||
testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
|
testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
|
||||||
declared=save_decl;
|
declared=save_decl;
|
||||||
delete_symbols(&loctab,nestlevel,FALSE,TRUE); /* erase local symbols, but
|
delete_symbols(&loctab,nestlevel,FALSE,TRUE); /* erase local symbols, but
|
||||||
@ -5069,6 +5073,7 @@ static int dofor(void)
|
|||||||
save_decl=declared;
|
save_decl=declared;
|
||||||
save_nestlevel=nestlevel;
|
save_nestlevel=nestlevel;
|
||||||
save_endlessloop=endlessloop;
|
save_endlessloop=endlessloop;
|
||||||
|
pushstacklist();
|
||||||
|
|
||||||
addwhile(wq);
|
addwhile(wq);
|
||||||
skiplab=getlabel();
|
skiplab=getlabel();
|
||||||
@ -5094,8 +5099,11 @@ static int dofor(void)
|
|||||||
*/
|
*/
|
||||||
ptr=readwhile();
|
ptr=readwhile();
|
||||||
assert(ptr!=NULL);
|
assert(ptr!=NULL);
|
||||||
ptr[wqBRK]=(int)declared;
|
/*ptr[wqBRK]=(int)declared;
|
||||||
ptr[wqCONT]=(int)declared;
|
*ptr[wqCONT]=(int)declared;
|
||||||
|
*/
|
||||||
|
ptr[wqBRK] = stackusage->list_id;
|
||||||
|
ptr[wqCONT] = stackusage->list_id;
|
||||||
jumplabel(skiplab); /* skip expression 3 1st time */
|
jumplabel(skiplab); /* skip expression 3 1st time */
|
||||||
setlabel(wq[wqLOOP]); /* "continue" goes to this label: expr3 */
|
setlabel(wq[wqLOOP]); /* "continue" goes to this label: expr3 */
|
||||||
setline(TRUE);
|
setline(TRUE);
|
||||||
@ -5135,7 +5143,7 @@ static int dofor(void)
|
|||||||
* variable in "expr1".
|
* variable in "expr1".
|
||||||
*/
|
*/
|
||||||
destructsymbols(&loctab,nestlevel);
|
destructsymbols(&loctab,nestlevel);
|
||||||
modstk((int)(declared-save_decl)*sizeof(cell));
|
popstacklist();
|
||||||
testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
|
testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
|
||||||
declared=save_decl;
|
declared=save_decl;
|
||||||
delete_symbols(&loctab,nestlevel,FALSE,TRUE);
|
delete_symbols(&loctab,nestlevel,FALSE,TRUE);
|
||||||
@ -5152,7 +5160,7 @@ static int dofor(void)
|
|||||||
* 2. only one instruction may appear below each case, use a compound
|
* 2. only one instruction may appear below each case, use a compound
|
||||||
* instruction to execute multiple instructions
|
* instruction to execute multiple instructions
|
||||||
* 3. the "case" keyword accepts a comma separated list of values to
|
* 3. the "case" keyword accepts a comma separated list of values to
|
||||||
* match, it also accepts a range using the syntax "1 .. 4"
|
* match
|
||||||
*
|
*
|
||||||
* SWITCH param
|
* SWITCH param
|
||||||
* PRI = expression result
|
* PRI = expression result
|
||||||
@ -5349,6 +5357,8 @@ static void dolabel(void)
|
|||||||
/* since one can jump around variable declarations or out of compound
|
/* since one can jump around variable declarations or out of compound
|
||||||
* blocks, the stack must be manually adjusted
|
* blocks, the stack must be manually adjusted
|
||||||
*/
|
*/
|
||||||
|
//:TODO: This is actually generated, egads!
|
||||||
|
//We have to support this and LCTRL/SCTRL
|
||||||
setstk(-declared*sizeof(cell));
|
setstk(-declared*sizeof(cell));
|
||||||
sym->usage|=uDEFINE; /* label is now defined */
|
sym->usage|=uDEFINE; /* label is now defined */
|
||||||
}
|
}
|
||||||
@ -5496,8 +5506,7 @@ static void doreturn(void)
|
|||||||
rettype|=uRETNONE; /* function does not return anything */
|
rettype|=uRETNONE; /* function does not return anything */
|
||||||
} /* if */
|
} /* if */
|
||||||
destructsymbols(&loctab,0); /* call destructor for *all* locals */
|
destructsymbols(&loctab,0); /* call destructor for *all* locals */
|
||||||
modstk((int)declared*sizeof(cell)); /* end of function, remove *all*
|
genstackfree(-1); /* free everything on the stack */
|
||||||
* local variables */
|
|
||||||
ffret(strcmp(curfunc->name,uENTRYFUNC)!=0);
|
ffret(strcmp(curfunc->name,uENTRYFUNC)!=0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5511,7 +5520,7 @@ static void dobreak(void)
|
|||||||
if (ptr==NULL)
|
if (ptr==NULL)
|
||||||
return;
|
return;
|
||||||
destructsymbols(&loctab,nestlevel);
|
destructsymbols(&loctab,nestlevel);
|
||||||
modstk(((int)declared-ptr[wqBRK])*sizeof(cell));
|
genstackfree(ptr[wqBRK]);
|
||||||
jumplabel(ptr[wqEXIT]);
|
jumplabel(ptr[wqEXIT]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5524,7 +5533,7 @@ static void docont(void)
|
|||||||
if (ptr==NULL)
|
if (ptr==NULL)
|
||||||
return;
|
return;
|
||||||
destructsymbols(&loctab,nestlevel);
|
destructsymbols(&loctab,nestlevel);
|
||||||
modstk(((int)declared-ptr[wqCONT])*sizeof(cell));
|
genstackfree(ptr[wqCONT]);
|
||||||
jumplabel(ptr[wqLOOP]);
|
jumplabel(ptr[wqLOOP]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,14 @@ memuse_list_t *stackusage = NULL;
|
|||||||
void _push_memlist(memuse_list_t **head)
|
void _push_memlist(memuse_list_t **head)
|
||||||
{
|
{
|
||||||
memuse_list_t *newlist = (memuse_list_t *)malloc(sizeof(memuse_list_t));
|
memuse_list_t *newlist = (memuse_list_t *)malloc(sizeof(memuse_list_t));
|
||||||
(*head)->prev = *head;
|
if (*head != NULL)
|
||||||
(*head)->head = NULL;
|
{
|
||||||
|
newlist->list_id = (*head)->list_id + 1;
|
||||||
|
} else {
|
||||||
|
newlist->list_id = 0;
|
||||||
|
}
|
||||||
|
newlist->prev = *head;
|
||||||
|
newlist->head = NULL;
|
||||||
*head = newlist;
|
*head = newlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +58,26 @@ int _mark_memlist(memuse_list_t *head, int type, int size)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _reset_memlist(memuse_list_t **head)
|
||||||
|
{
|
||||||
|
memuse_list_t *curlist = *head;
|
||||||
|
memuse_list_t *tmplist;
|
||||||
|
while (curlist) {
|
||||||
|
memuse_t *curuse = curlist->head;
|
||||||
|
memuse_t *tmpuse;
|
||||||
|
while (curuse) {
|
||||||
|
tmpuse = curuse->prev;
|
||||||
|
free(curuse);
|
||||||
|
curuse = tmpuse;
|
||||||
|
}
|
||||||
|
tmplist = curlist->prev;
|
||||||
|
free(curlist);
|
||||||
|
curlist = tmplist;
|
||||||
|
}
|
||||||
|
*head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for pushing the heap list
|
* Wrapper for pushing the heap list
|
||||||
*/
|
*/
|
||||||
@ -99,8 +125,10 @@ void _heap_freeusage(memuse_list_t *heap)
|
|||||||
{
|
{
|
||||||
memuse_t *cur=heap->head;
|
memuse_t *cur=heap->head;
|
||||||
memuse_t *tmp;
|
memuse_t *tmp;
|
||||||
while (cur) {
|
while (cur)
|
||||||
if (cur->type == MEMUSE_STATIC) {
|
{
|
||||||
|
if (cur->type == MEMUSE_STATIC)
|
||||||
|
{
|
||||||
modheap((-1)*cur->size*sizeof(cell));
|
modheap((-1)*cur->size*sizeof(cell));
|
||||||
} else {
|
} else {
|
||||||
modheap_i();
|
modheap_i();
|
||||||
@ -112,6 +140,34 @@ void _heap_freeusage(memuse_list_t *heap)
|
|||||||
heap->head=NULL;
|
heap->head=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _stack_genusage(memuse_list_t *stack, int dofree)
|
||||||
|
{
|
||||||
|
memuse_t *cur = stack->head;
|
||||||
|
memuse_t *tmp;
|
||||||
|
while (cur)
|
||||||
|
{
|
||||||
|
if (cur->type == MEMUSE_DYNAMIC)
|
||||||
|
{
|
||||||
|
/* no idea yet */
|
||||||
|
assert(0);
|
||||||
|
} else {
|
||||||
|
modstk(cur->size * sizeof(cell));
|
||||||
|
}
|
||||||
|
if (dofree)
|
||||||
|
{
|
||||||
|
tmp = cur->prev;
|
||||||
|
free(cur);
|
||||||
|
cur = tmp;
|
||||||
|
} else {
|
||||||
|
cur = cur->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dofree)
|
||||||
|
{
|
||||||
|
stack->head = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pops a heap list and frees it.
|
* Pops a heap list and frees it.
|
||||||
*/
|
*/
|
||||||
@ -128,4 +184,30 @@ void popheaplist()
|
|||||||
heapusage=oldlist;
|
heapusage=oldlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void genstackfree(int stop_id)
|
||||||
|
{
|
||||||
|
memuse_list_t *curlist = stackusage;
|
||||||
|
while (curlist && curlist->list_id > stop_id)
|
||||||
|
{
|
||||||
|
_stack_genusage(curlist, 0);
|
||||||
|
curlist = curlist->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void popstacklist()
|
||||||
|
{
|
||||||
|
memuse_list_t *oldlist;
|
||||||
|
assert(stackusage != NULL);
|
||||||
|
|
||||||
|
_stack_genusage(stackusage, 1);
|
||||||
|
assert(stackusage->head==NULL);
|
||||||
|
|
||||||
|
oldlist = stackusage->prev;
|
||||||
|
free(stackusage);
|
||||||
|
stackusage = oldlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetstacklist()
|
||||||
|
{
|
||||||
|
_reset_memlist(&stackusage);
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ typedef struct memuse_s {
|
|||||||
|
|
||||||
typedef struct memuse_list_s {
|
typedef struct memuse_list_s {
|
||||||
struct memuse_list_s *prev; /* last used list */
|
struct memuse_list_s *prev; /* last used list */
|
||||||
|
int list_id;
|
||||||
memuse_t *head; /* head of the current list */
|
memuse_t *head; /* head of the current list */
|
||||||
} memuse_list_t;
|
} memuse_list_t;
|
||||||
|
|
||||||
@ -29,6 +30,17 @@ int markheap(int type, int size);
|
|||||||
void pushstacklist();
|
void pushstacklist();
|
||||||
void popstacklist();
|
void popstacklist();
|
||||||
int markstack(int type, int size);
|
int markstack(int type, int size);
|
||||||
|
/**
|
||||||
|
* Generates code to free stack usage, but does not pop the list.
|
||||||
|
* This is used for code like dobreak()/docont()/doreturn().
|
||||||
|
* stop_id is the list at which to stop generating.
|
||||||
|
*/
|
||||||
|
void genstackfree(int stop_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the stack list by freeing everything
|
||||||
|
*/
|
||||||
|
void resetstacklist();
|
||||||
|
|
||||||
extern memuse_list_t *heapusage;
|
extern memuse_list_t *heapusage;
|
||||||
extern memuse_list_t *stackusage;
|
extern memuse_list_t *stackusage;
|
||||||
|
Loading…
Reference in New Issue
Block a user