Array rvals, lvals and dimension
Stefano Corsi <[email protected]> Thu, 1 May 2003 00:27:26 +0000
| Newsgroups | gmane.comp.lang.moto.devel |
|---|---|
| Organization | Moto Project |
| Message-ID | <[email protected]> |
Dave,=20
I have modified array_rval and array_lval in motov.c and motoc.c to refle=
ct=20
the way they are called in motoi.c, as you suggested. All tests pass and =
the=20
change seems to work fine.=20
Then I did something strange: I noticed that the for loop for all dimensi=
ons=20
in motoi_array_lval is never executed more than once. So I did some (dumb=
=20
monkey style) cutting job and I resized the motoi_array_lval to just=20
evaluate ONE array index without the for loop, and, quite unexpectedly, i=
t=20
works and passes all tests.=20
Can you see some side effects in the cutting job I did and maybe produce =
a=20
test to show it?
Here is the moto_array_lval after my work. If it's good, then implementin=
g the=20
[] overl. operator could be a bit nearer.
motoi_array_lval(const UnionCell *p){
MotoEnv *env =3D moto_getEnv();
MotoVal *val, *ival;
MotoVar *rvar;
UnArray *ua;
int *dimarr;
/* Evaluate the first operand to get the Array*/
motoi(uc_operand(p, 0));
val =3D opstack_pop(env);
/* Evaluate the ARRAY_INDEX element */
motoi(uc_operand(p, 1)); /* array_index list */
ival =3D opstack_pop(env);
/* Build an array of the specified indexes */
dimarr =3D (int*)emalloc(sizeof(int)* (1));=09
if (ival->type->kind =3D=3D INT32_TYPE)
dimarr[0] =3D iv(ival);
else /* (ival->type->kind =3D=3D INT64_TYPE) */
dimarr[0] =3D lv(ival);
moto_freeVal(env,ival);
rvar =3D moto_createVar(
env,NULL,
val->type->atype->name,
val->type->dim - 1,
'\1',
NULL
);
=20
/* Clean up val now since we might need to throw an exception */
moto_freeVal(env,val);
if (ua =3D=3D NULL){
/* Clean up and throw NullPointerException */
free(dimarr);
moto_freeVar(env,rvar);
MOTO_THROW("NullPointerException","Attempt to subscript null");
}
if(dimarr[0] < 0 || dimarr[0] >=3D ua->meta.length){
/* Clean up and throw ArrayBoundsException */
free(dimarr);
moto_freeVar(env,rvar);
MOTO_THROW("ArrayBoundsException","Attempt to subscript array out=
side=20
of declared bounds");
}
if (val->type->dim =3D=3D 1){
switch (val->type->atype->kind){
case INT32_TYPE: rvar->address =3D &ua->ia.data[dimarr[0]]; b=
reak;
case INT64_TYPE: rvar->address =3D &ua->la.data[dimarr[0]]; b=
reak;
case FLOAT_TYPE: rvar->address =3D &ua->fa.data[dimarr[0]]; b=
reak;
case DOUBLE_TYPE: rvar->address =3D &ua->da.data[dimarr[0]]; =
break;
case BOOLEAN_TYPE: rvar->address =3D &ua->ba.data[dimarr[0]];=
break;
case BYTE_TYPE: rvar->address =3D &ua->ya.data[dimarr[0]]; br=
eak;
case CHAR_TYPE: rvar->address =3D &ua->ca.data[dimarr[0]]; br=
eak;
case REF_TYPE: rvar->address =3D &ua->ra.data[dimarr[0]]; bre=
ak;
default: {THROW_D("MotoCellTypeException");}
}
} else {
rvar->address =3D &ua->aa.data[dimarr[0]];
}
free(dimarr);
opstack_push(env, (MotoVal*)rvar);
}