Fix inc/dec operations on accessors.

This commit is contained in:
David Anderson 2014-07-20 11:18:38 -07:00
parent 8436a3ea6c
commit 5daa420aed
3 changed files with 27 additions and 7 deletions

View File

@ -718,6 +718,7 @@ SC_FUNC void pushval(cell val);
SC_FUNC void popreg(regid reg); SC_FUNC void popreg(regid reg);
SC_FUNC void genarray(int dims, int _autozero); SC_FUNC void genarray(int dims, int _autozero);
SC_FUNC void swap1(void); SC_FUNC void swap1(void);
SC_FUNC void xchg(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);
SC_FUNC void ffcall(symbol *sym,const char *label,int numargs); SC_FUNC void ffcall(symbol *sym,const char *label,int numargs);

View File

@ -218,7 +218,8 @@ static void (*unopers[])(void) = { lneg, neg, user_inc, user_dec };
assert(lval!=NULL); assert(lval!=NULL);
if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR) if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR)
pushreg(sPRI); /* save current address in PRI */ pushreg(sPRI); /* save current address in PRI */
rvalue(lval); /* get the symbol's value in PRI */ if (lval->ident!=iACCESSOR)
rvalue(lval); /* get the symbol's value in PRI */
} /* if */ } /* if */
assert(!savepri || !savealt); /* either one MAY be set, but not both */ assert(!savepri || !savealt); /* either one MAY be set, but not both */
@ -277,8 +278,10 @@ static void (*unopers[])(void) = { lneg, neg, user_inc, user_dec };
assert(lval!=NULL); assert(lval!=NULL);
if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR) if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR)
popreg(sALT); /* restore address (in ALT) */ popreg(sALT); /* restore address (in ALT) */
store(lval); /* store PRI in the symbol */ if (lval->ident!=iACCESSOR) {
moveto1(); /* make sure PRI is restored on exit */ store(lval); /* store PRI in the symbol */
moveto1(); /* make sure PRI is restored on exit */
}
} /* if */ } /* if */
return TRUE; return TRUE;
} }
@ -1901,10 +1904,15 @@ static int hier2(value *lval)
} else { } else {
pushreg(sPRI); // save obj pushreg(sPRI); // save obj
invoke_getter(lval->accessor); invoke_getter(lval->accessor);
swap1(); // pri = obj, stack = [oldval] move_alt(); // alt = oldval
pushreg(sPRI); // pri = obj, stack = [oldval, obj] swap1(); // pri = saved obj, stack = [oldval]
pushreg(sPRI); // pri = obj, alt = oldval, stack = [obj, oldval]
moveto1(); // pri = oldval, stack = [obj, oldval]
// check_userop on an iACCESSOR acts as though the value is an rvalue.
if (!check_userop(user_inc, lval->tag, 0, 1, lval, &lval->tag)) if (!check_userop(user_inc, lval->tag, 0, 1, lval, &lval->tag))
inc_pri(); inc_pri();
popreg(sALT); popreg(sALT);
invoke_setter(lval->accessor, FALSE); invoke_setter(lval->accessor, FALSE);
popreg(sPRI); popreg(sPRI);
@ -1932,10 +1940,15 @@ static int hier2(value *lval)
} else { } else {
pushreg(sPRI); // save obj pushreg(sPRI); // save obj
invoke_getter(lval->accessor); invoke_getter(lval->accessor);
swap1(); // pri = obj, stack = [oldval] move_alt(); // alt = oldval
pushreg(sPRI); // pri = obj, stack = [oldval, obj] swap1(); // pri = saved obj, stack = [oldval]
pushreg(sPRI); // pri = obj, alt = oldval, stack = [obj, oldval]
moveto1(); // pri = oldval, stack = [obj, oldval]
// check_userop on an iACCESSOR acts as though the value is an rvalue.
if (!check_userop(user_dec, lval->tag, 0, 1, lval, &lval->tag)) if (!check_userop(user_dec, lval->tag, 0, 1, lval, &lval->tag))
dec_pri(); dec_pri();
popreg(sALT); popreg(sALT);
invoke_setter(lval->accessor, FALSE); invoke_setter(lval->accessor, FALSE);
popreg(sPRI); popreg(sPRI);

View File

@ -1394,6 +1394,12 @@ SC_FUNC void jmp_eq0(int number)
code_idx+=opcodes(1)+opargs(1); code_idx+=opcodes(1)+opargs(1);
} }
SC_FUNC void xchg(void)
{
stgwrite("\txchg\n");
code_idx+=opcodes(1);
}
/* write a value in hexadecimal; optionally adds a newline */ /* write a value in hexadecimal; optionally adds a newline */
SC_FUNC void outval(cell val,int newline) SC_FUNC void outval(cell val,int newline)
{ {