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