Fix 4d array initialization

adjust_indirectiontables() generated wrong values for certain array
dimensions in 4d arrays.

Fixes #43
This commit is contained in:
Zeex 2015-05-01 16:13:16 +06:00
parent 10a021b51e
commit d14f4870a8

View File

@ -2321,52 +2321,47 @@ static cell calc_arraysize(int dim[],int numdim,int cur)
return newsize; return newsize;
} }
static cell adjust_indirectiontables(int dim[],int numdim,int cur,cell increment, static void adjust_indirectiontables(int dim[],int numdim,int startlit,
int startlit,constvalue *lastdim,int *skipdim) constvalue *lastdim,int *skipdim)
{ {
static int base; static int base;
int d; int cur;
int i,d;
cell accum; cell accum;
cell size;
assert(cur>=0 && cur<numdim);
assert(increment>=0);
assert(cur>0 && startlit==-1 || startlit>=0 && startlit<=litidx); assert(cur>0 && startlit==-1 || startlit>=0 && startlit<=litidx);
if (cur==0) base=startlit;
base=startlit; size=1;
if (cur==numdim-1) for (cur=0; cur<numdim-1; cur++) {
return 0; for (i=0; i<size; i++) {
/* 2 or more dimensions left, fill in an indirection vector */ /* 2 or more dimensions left, fill in an indirection vector */
if (dim[cur+1]>0) { if (dim[cur+1]>0) {
for (d=0; d<dim[cur]; d++) for (d=0; d<dim[cur]; d++)
litq[base++]=(dim[cur]+d*(dim[cur+1]-1)+increment) * sizeof(cell); litq[base++]=((size+i)*dim[cur]+d*(dim[cur+1]-1)) * sizeof(cell);
accum=dim[cur]*(dim[cur+1]-1); } else {
} else { /* final dimension is variable length */
/* final dimension is variable length */ constvalue *ld;
constvalue *ld; assert(dim[cur+1]==0);
assert(dim[cur+1]==0); assert(lastdim!=NULL);
assert(lastdim!=NULL); assert(skipdim!=NULL);
assert(skipdim!=NULL); accum=0;
accum=0; /* skip the final dimension sizes for all earlier major dimensions */
/* skip the final dimension sizes for all earlier major dimensions */ for (d=0,ld=lastdim->next; d<*skipdim; d++,ld=ld->next) {
for (d=0,ld=lastdim->next; d<*skipdim; d++,ld=ld->next) { assert(ld!=NULL);
assert(ld!=NULL); } /* for */
for (d=0; d<dim[cur]; d++) {
assert(ld!=NULL);
assert(strtol(ld->name,NULL,16)==d);
litq[base++]=((size+i)*dim[cur]+accum) * sizeof(cell);
accum+=ld->value-1;
*skipdim+=1;
ld=ld->next;
} /* for */
} /* if */
} /* for */ } /* for */
for (d=0; d<dim[cur]; d++) { size*=dim[cur];
assert(ld!=NULL); } /* for */
assert(strtol(ld->name,NULL,16)==d);
litq[base++]=(dim[cur]+accum+increment) * sizeof(cell);
accum+=ld->value-1;
*skipdim+=1;
ld=ld->next;
} /* for */
} /* if */
/* create the indirection tables for the lower level */
if (cur+2<numdim) { /* are there at least 2 dimensions below this one? */
increment+=(dim[cur]-1)*dim[cur+1]; /* this many indirection tables follow */
for (d=0; d<dim[cur]; d++)
increment+=adjust_indirectiontables(dim,numdim,cur+1,increment,-1,lastdim,skipdim);
} /* if */
return accum;
} }
/* initials /* initials
@ -2407,7 +2402,7 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim,
for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--) for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
litadd(0); litadd(0);
if (dim[numdim-1]!=0) /* error 9 has already been given */ if (dim[numdim-1]!=0) /* error 9 has already been given */
adjust_indirectiontables(dim,numdim,0,0,curlit,NULL,NULL); adjust_indirectiontables(dim,numdim,curlit,NULL,NULL);
} /* if */ } /* if */
return; return;
} /* if */ } /* if */
@ -2473,7 +2468,7 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim,
* of the array and we can properly adjust the indirection vectors * of the array and we can properly adjust the indirection vectors
*/ */
if (err==0) if (err==0)
adjust_indirectiontables(dim,numdim,0,0,curlit,&lastdim,&skipdim); adjust_indirectiontables(dim,numdim,curlit,&lastdim,&skipdim);
delete_consttable(&lastdim); /* clear list of minor dimension sizes */ delete_consttable(&lastdim); /* clear list of minor dimension sizes */
} /* if */ } /* if */
} /* if */ } /* if */