initial import of.... DYNAMIC ARRAYS

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40123
This commit is contained in:
David Anderson 2006-10-16 02:05:26 +00:00
parent ea6e82d79a
commit b7180795ec
6 changed files with 104 additions and 34 deletions

View File

@ -590,6 +590,7 @@ SC_FUNC void moveto1(void);
SC_FUNC void pushreg(regid reg); SC_FUNC void pushreg(regid reg);
SC_FUNC void pushval(cell val); SC_FUNC void pushval(cell val);
SC_FUNC void popreg(regid reg); SC_FUNC void popreg(regid reg);
SC_FUNC void genarray(int dims);
SC_FUNC void swap1(void); SC_FUNC void swap1(void);
SC_FUNC void ffswitch(int label); SC_FUNC void ffswitch(int label);
SC_FUNC void ffcase(cell value,char *labelname,int newtable); SC_FUNC void ffcase(cell value,char *labelname,int newtable);

View File

@ -1926,7 +1926,8 @@ static int declloc(int fstatic)
*/ */
if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name,sGLOBAL)!=NULL) if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name,sGLOBAL)!=NULL)
error(219,name); /* variable shadows another symbol */ error(219,name); /* variable shadows another symbol */
while (matchtoken('[')){ if (matchtoken('[')) {
do {
ident=iARRAY; ident=iARRAY;
if (numdim == sDIMEN_MAX) { if (numdim == sDIMEN_MAX) {
error(53); /* exceeding maximum number of dimensions */ error(53); /* exceeding maximum number of dimensions */
@ -1938,7 +1939,32 @@ static int declloc(int fstatic)
error(105); /* overflow, exceeding capacity */ error(105); /* overflow, exceeding capacity */
#endif #endif
dim[numdim++]=(int)size; dim[numdim++]=(int)size;
} /* while */ } while (matchtoken('['));
} else if (matchtoken('(')) {
int dim_ident;
int dim_tag;
symbol *dim_sym;
do {
ident=iREFARRAY;
if (numdim == sDIMEN_MAX) {
error(53);
return iREFARRAY;
} /* if */
dim_ident = doexpr(TRUE,FALSE,FALSE,FALSE,&dim_tag,&dim_sym,0);
dim[numdim++] = 1;
if (dim_ident == iVARIABLE || dim_ident == iEXPRESSION) {
pushreg(sPRI);
} else if (dim_ident == iCONSTEXPR) {
pushreg(sPRI);
} else {
assert(0); //:TODO: make this an error
}
if (!matchtag(tag, dim_tag, FALSE))
error(213);
needtoken(')');
} while (matchtoken('('));
genarray(numdim);
}
if (getstates(name)) if (getstates(name))
error(88,name); /* local variables may not have states */ error(88,name); /* local variables may not have states */
if (ident==iARRAY || fstatic) { if (ident==iARRAY || fstatic) {
@ -1952,7 +1978,7 @@ static int declloc(int fstatic)
return ident; /* error message already given */ return ident; /* error message already given */
if (numdim==1) if (numdim==1)
dim[0]=(int)size; dim[0]=(int)size;
} /* if */ }
/* reserve memory (on the stack) for the variable */ /* reserve memory (on the stack) for the variable */
if (fstatic) { if (fstatic) {
/* write zeros for uninitialized fields */ /* write zeros for uninitialized fields */
@ -1960,7 +1986,7 @@ static int declloc(int fstatic)
litadd(0); litadd(0);
sym=addvariable(name,(cur_lit+glb_declared)*sizeof(cell),ident,sSTATIC, sym=addvariable(name,(cur_lit+glb_declared)*sizeof(cell),ident,sSTATIC,
tag,dim,numdim,idxtag); tag,dim,numdim,idxtag);
} else { } else if (ident!=iREFARRAY) {
declared+=(int)size; /* variables are put on stack, adjust "declared" */ declared+=(int)size; /* variables are put on stack, adjust "declared" */
sym=addvariable(name,-declared*sizeof(cell),ident,sLOCAL,tag, sym=addvariable(name,-declared*sizeof(cell),ident,sLOCAL,tag,
dim,numdim,idxtag); dim,numdim,idxtag);
@ -1977,6 +2003,15 @@ static int declloc(int fstatic)
assert((curfunc->usage & uNATIVE)==0); assert((curfunc->usage & uNATIVE)==0);
if (curfunc->x.stacksize<declared+1) if (curfunc->x.stacksize<declared+1)
curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */ curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */
} else if (ident==iREFARRAY) {
declared+=1; /* one cell for address */
sym=addvariable(name,-declared*sizeof(cell),ident,sLOCAL,tag,dim,numdim,idxtag);
//markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
/* genarray() pushes the address onto the stack, so we don't need to call modstk() here! */
markheap(MEMUSE_DYNAMIC, 0);
assert(curfunc != NULL && ((curfunc->usage & uNATIVE) == 0));
if (curfunc->x.stacksize<declared+1)
curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */
} /* if */ } /* if */
/* now that we have reserved memory for the variable, we can proceed /* now that we have reserved memory for the variable, we can proceed
* to initialize it */ * to initialize it */
@ -2017,7 +2052,7 @@ static int declloc(int fstatic)
* "uWRITTEN" flag that store() set */ * "uWRITTEN" flag that store() set */
if (!explicit_init) if (!explicit_init)
sym->usage &= ~uWRITTEN; sym->usage &= ~uWRITTEN;
} else { } else if (ident!=iREFARRAY) {
/* an array */ /* an array */
assert(cur_lit>=0 && cur_lit<=litidx && litidx<=litmax); assert(cur_lit>=0 && cur_lit<=litidx && litidx<=litmax);
assert(size>0 && size>=sym->dim.array.length); assert(size>0 && size>=sym->dim.array.length);
@ -3336,6 +3371,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
} /* if */ } /* if */
declared=0; /* number of local cells */ declared=0; /* number of local cells */
resetstacklist(); resetstacklist();
resetheaplist();
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 */
@ -4773,6 +4809,7 @@ static void compound(int stmt_sameline,int starttok)
int endtok; int endtok;
pushstacklist(); pushstacklist();
pushheaplist();
/* 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;
@ -4812,6 +4849,7 @@ static void compound(int stmt_sameline,int starttok)
if (lastst!=tRETURN) if (lastst!=tRETURN)
destructsymbols(&loctab,nestlevel); destructsymbols(&loctab,nestlevel);
if (lastst!=tRETURN && lastst!=tGOTO) { if (lastst!=tRETURN && lastst!=tGOTO) {
popheaplist();
popstacklist(); popstacklist();
} }
testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */ testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
@ -5506,6 +5544,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 */
genheapfree(-1);
genstackfree(-1); /* free everything on the stack */ genstackfree(-1); /* free everything on the stack */
ffret(strcmp(curfunc->name,uENTRYFUNC)!=0); ffret(strcmp(curfunc->name,uENTRYFUNC)!=0);
} }

View File

@ -672,6 +672,16 @@ SC_FUNC void popreg(regid reg)
code_idx+=opcodes(1); code_idx+=opcodes(1);
} }
/*
* Generate an array
*/
SC_FUNC void genarray(int dims)
{
stgwrite("\tgenarray ");
outval(dims, TRUE);
code_idx+=opcodes(1)+opargs(1);
}
/* /*
* swap the top-of-stack with the value in primary register * swap the top-of-stack with the value in primary register
*/ */
@ -846,13 +856,8 @@ SC_FUNC void modheap(int delta)
SC_FUNC void modheap_i() SC_FUNC void modheap_i()
{ {
pushreg(sPRI); stgwrite("\theap.i\n");
pushreg(sALT); code_idx+=opcodes(1);
stgwrite("\tpop.h.pri\n");
stgwrite("\theap.pri\n");
code_idx+=opcodes(2);
popreg(sALT);
popreg(sPRI);
} }
SC_FUNC void setheap_save(cell value) SC_FUNC void setheap_save(cell value)

View File

@ -489,11 +489,12 @@ static OPCODEC opcodelist[] = {
{105, "eq.c.pri", sIN_CSEG, parm1 }, {105, "eq.c.pri", sIN_CSEG, parm1 },
/*{124, "file", sIN_CSEG, do_file }, */ /*{124, "file", sIN_CSEG, do_file }, */
{119, "fill", sIN_CSEG, parm1 }, {119, "fill", sIN_CSEG, parm1 },
{162, "genarray", sIN_CSEG, parm1 },
{100, "geq", sIN_CSEG, parm0 }, {100, "geq", sIN_CSEG, parm0 },
{ 99, "grtr", sIN_CSEG, parm0 }, { 99, "grtr", sIN_CSEG, parm0 },
{120, "halt", sIN_CSEG, parm1 }, {120, "halt", sIN_CSEG, parm1 },
{ 45, "heap", sIN_CSEG, parm1 }, { 45, "heap", sIN_CSEG, parm1 },
{160, "heap.pri", sIN_CSEG, parm0 }, {160, "heap.i", sIN_CSEG, parm0 },
{ 27, "idxaddr", sIN_CSEG, parm0 }, { 27, "idxaddr", sIN_CSEG, parm0 },
{ 28, "idxaddr.b", sIN_CSEG, parm1 }, { 28, "idxaddr.b", sIN_CSEG, parm1 },
{109, "inc", sIN_CSEG, parm1 }, {109, "inc", sIN_CSEG, parm1 },
@ -544,7 +545,6 @@ static OPCODEC opcodelist[] = {
{ 84, "not", sIN_CSEG, parm0 }, { 84, "not", sIN_CSEG, parm0 },
{ 82, "or", sIN_CSEG, parm0 }, { 82, "or", sIN_CSEG, parm0 },
{ 43, "pop.alt", sIN_CSEG, parm0 }, { 43, "pop.alt", sIN_CSEG, parm0 },
{162, "pop.h.pri", sIN_CSEG, parm0 },
{ 42, "pop.pri", sIN_CSEG, parm0 }, { 42, "pop.pri", sIN_CSEG, parm0 },
{ 46, "proc", sIN_CSEG, parm0 }, { 46, "proc", sIN_CSEG, parm0 },
{ 40, "push", sIN_CSEG, parm1 }, { 40, "push", sIN_CSEG, parm1 },

View File

@ -121,7 +121,7 @@ int markstack(int type, int size)
/** /**
* Generates code to free all heap allocations on a tracker * Generates code to free all heap allocations on a tracker
*/ */
void _heap_freeusage(memuse_list_t *heap) void _heap_freeusage(memuse_list_t *heap, int dofree)
{ {
memuse_t *cur=heap->head; memuse_t *cur=heap->head;
memuse_t *tmp; memuse_t *tmp;
@ -133,12 +133,20 @@ void _heap_freeusage(memuse_list_t *heap)
} else { } else {
modheap_i(); modheap_i();
} }
if (dofree)
{
tmp=cur->prev; tmp=cur->prev;
free(cur); free(cur);
cur=tmp; cur=tmp;
} else {
cur=cur->prev;
} }
}
if (dofree)
{
heap->head=NULL; heap->head=NULL;
} }
}
void _stack_genusage(memuse_list_t *stack, int dofree) void _stack_genusage(memuse_list_t *stack, int dofree)
{ {
@ -176,7 +184,7 @@ void popheaplist()
memuse_list_t *oldlist; memuse_list_t *oldlist;
assert(heapusage!=NULL); assert(heapusage!=NULL);
_heap_freeusage(heapusage); _heap_freeusage(heapusage, 1);
assert(heapusage->head==NULL); assert(heapusage->head==NULL);
oldlist=heapusage->prev; oldlist=heapusage->prev;
@ -194,6 +202,16 @@ void genstackfree(int stop_id)
} }
} }
void genheapfree(int stop_id)
{
memuse_list_t *curlist = heapusage;
while (curlist && curlist->list_id > stop_id)
{
_heap_freeusage(curlist, 0);
curlist = curlist->prev;
}
}
void popstacklist() void popstacklist()
{ {
memuse_list_t *oldlist; memuse_list_t *oldlist;
@ -211,3 +229,8 @@ void resetstacklist()
{ {
_reset_memlist(&stackusage); _reset_memlist(&stackusage);
} }
void resetheaplist()
{
_reset_memlist(&heapusage);
}

View File

@ -31,16 +31,18 @@ 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. * Generates code to free mem usage, but does not pop the list.
* This is used for code like dobreak()/docont()/doreturn(). * This is used for code like dobreak()/docont()/doreturn().
* stop_id is the list at which to stop generating. * stop_id is the list at which to stop generating.
*/ */
void genstackfree(int stop_id); void genstackfree(int stop_id);
void genheapfree(int stop_id);
/** /**
* Resets the stack list by freeing everything * Resets a mem list by freeing everything
*/ */
void resetstacklist(); void resetstacklist();
void resetheaplist();
extern memuse_list_t *heapusage; extern memuse_list_t *heapusage;
extern memuse_list_t *stackusage; extern memuse_list_t *stackusage;