initial import of.... DYNAMIC ARRAYS
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40123
This commit is contained in:
parent
ea6e82d79a
commit
b7180795ec
@ -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);
|
||||||
|
@ -1667,7 +1667,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
|
|||||||
ispublic=TRUE; /* implicitly public variable */
|
ispublic=TRUE; /* implicitly public variable */
|
||||||
assert(!fstatic);
|
assert(!fstatic);
|
||||||
} /* if */
|
} /* if */
|
||||||
while (matchtoken('[')) {
|
while (matchtoken('[')) {
|
||||||
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 */
|
||||||
@ -1926,19 +1926,45 @@ 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('[')) {
|
||||||
ident=iARRAY;
|
do {
|
||||||
if (numdim == sDIMEN_MAX) {
|
ident=iARRAY;
|
||||||
error(53); /* exceeding maximum number of dimensions */
|
if (numdim == sDIMEN_MAX) {
|
||||||
return ident;
|
error(53); /* exceeding maximum number of dimensions */
|
||||||
} /* if */
|
return ident;
|
||||||
size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
|
} /* if */
|
||||||
#if INT_MAX < LONG_MAX
|
size=needsub(&idxtag[numdim],&enumroot); /* get size; size==0 for "var[]" */
|
||||||
if (size > INT_MAX)
|
#if INT_MAX < LONG_MAX
|
||||||
error(105); /* overflow, exceeding capacity */
|
if (size > INT_MAX)
|
||||||
#endif
|
error(105); /* overflow, exceeding capacity */
|
||||||
dim[numdim++]=(int)size;
|
#endif
|
||||||
} /* while */
|
dim[numdim++]=(int)size;
|
||||||
|
} 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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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 },
|
||||||
|
@ -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,11 +133,19 @@ void _heap_freeusage(memuse_list_t *heap)
|
|||||||
} else {
|
} else {
|
||||||
modheap_i();
|
modheap_i();
|
||||||
}
|
}
|
||||||
tmp=cur->prev;
|
if (dofree)
|
||||||
free(cur);
|
{
|
||||||
cur=tmp;
|
tmp=cur->prev;
|
||||||
|
free(cur);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user