mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 06:45:37 +03:00
Compiler: Fix in recursion detection.
Original fix imported from pawn 3.1.3522. This fixes where for some plugins you would have: Stack/heap size: 16384 bytes; usage is unknown, due to recursion Now, you get: Stack/heap size: 16384 bytes; estimated max. usage=782 cells (3128 bytes)
This commit is contained in:
parent
520493fab1
commit
6978e2dc4c
@ -4178,7 +4178,7 @@ static void reduce_referrers(symbol *root)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined SC_LIGHT
|
#if !defined SC_LIGHT
|
||||||
static long max_stacksize_recurse(symbol *sym,long basesize,int *pubfuncparams)
|
static long max_stacksize_recurse(symbol *sourcesym, symbol *sym, long basesize, int *pubfuncparams)
|
||||||
{
|
{
|
||||||
long size,maxsize;
|
long size,maxsize;
|
||||||
int i;
|
int i;
|
||||||
@ -4186,17 +4186,15 @@ static long max_stacksize_recurse(symbol *sym,long basesize,int *pubfuncparams)
|
|||||||
assert(sym!=NULL);
|
assert(sym!=NULL);
|
||||||
assert(sym->ident==iFUNCTN);
|
assert(sym->ident==iFUNCTN);
|
||||||
assert((sym->usage & uNATIVE)==0);
|
assert((sym->usage & uNATIVE)==0);
|
||||||
/* recursion detection */
|
|
||||||
if (sym->compound==0)
|
|
||||||
return -1; /* this function was processed already -> recursion */
|
|
||||||
sym->compound=0;
|
|
||||||
|
|
||||||
maxsize=sym->x.stacksize;
|
maxsize=sym->x.stacksize;
|
||||||
for (i=0; i<sym->numrefers; i++) {
|
for (i=0; i<sym->numrefers; i++) {
|
||||||
if (sym->refer[i]!=NULL) {
|
if (sym->refer[i]!=NULL) {
|
||||||
assert(sym->refer[i]->ident==iFUNCTN);
|
assert(sym->refer[i]->ident==iFUNCTN);
|
||||||
assert((sym->refer[i]->usage & uNATIVE)==0); /* a native function cannot refer to a user-function */
|
assert((sym->refer[i]->usage & uNATIVE)==0); /* a native function cannot refer to a user-function */
|
||||||
size=max_stacksize_recurse(sym->refer[i],sym->x.stacksize,pubfuncparams);
|
if (sym->refer[i] == sourcesym)
|
||||||
|
return -1; /* recursion detection */
|
||||||
|
size = max_stacksize_recurse(sourcesym, sym->refer[i], sym->x.stacksize, pubfuncparams);
|
||||||
if (size<0)
|
if (size<0)
|
||||||
return size; /* recursion was detected, quit */
|
return size; /* recursion was detected, quit */
|
||||||
if (maxsize<size)
|
if (maxsize<size)
|
||||||
@ -4248,27 +4246,17 @@ static long max_stacksize(symbol *root)
|
|||||||
maxsize=0;
|
maxsize=0;
|
||||||
maxparams=0;
|
maxparams=0;
|
||||||
for (sym=root->next; sym!=NULL; sym=sym->next) {
|
for (sym=root->next; sym!=NULL; sym=sym->next) {
|
||||||
symbol *tmpsym;
|
|
||||||
/* drop out if this is not a user-implemented function */
|
/* drop out if this is not a user-implemented function */
|
||||||
if (sym->ident!=iFUNCTN || (sym->usage & uNATIVE)!=0)
|
if (sym->ident!=iFUNCTN || (sym->usage & uNATIVE)!=0)
|
||||||
continue;
|
continue;
|
||||||
/* set a "mark" on all functions */
|
|
||||||
for (tmpsym=root->next; tmpsym!=NULL; tmpsym=tmpsym->next)
|
|
||||||
if (tmpsym->ident==iFUNCTN)
|
|
||||||
tmpsym->compound=1;
|
|
||||||
/* accumulate stack size for this symbol */
|
/* accumulate stack size for this symbol */
|
||||||
size=max_stacksize_recurse(sym,0L,&maxparams);
|
size=max_stacksize_recurse(sym,sym,0L,&maxparams);
|
||||||
if (size<0)
|
if (size<0)
|
||||||
return size; /* recursion was detected */
|
return size; /* recursion was detected */
|
||||||
if (maxsize<size)
|
if (maxsize<size)
|
||||||
maxsize=size;
|
maxsize=size;
|
||||||
} /* for */
|
} /* for */
|
||||||
|
|
||||||
/* clear all marks */
|
|
||||||
for (sym=root->next; sym!=NULL; sym=sym->next)
|
|
||||||
if (sym->ident==iFUNCTN)
|
|
||||||
sym->compound=0;
|
|
||||||
|
|
||||||
maxsize++; /* +1 because a zero cell is always pushed on top
|
maxsize++; /* +1 because a zero cell is always pushed on top
|
||||||
* of the stack to catch stack overwrites */
|
* of the stack to catch stack overwrites */
|
||||||
return maxsize+(maxparams+1);/* +1 because # of parameters is always pushed on entry */
|
return maxsize+(maxparams+1);/* +1 because # of parameters is always pushed on entry */
|
||||||
|
Loading…
Reference in New Issue
Block a user