From 5daa420aed60c445a444a8f7c37ab325ede1dd0c Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 20 Jul 2014 11:18:38 -0700 Subject: [PATCH] Fix inc/dec operations on accessors. --- sourcepawn/compiler/sc.h | 1 + sourcepawn/compiler/sc3.c | 27 ++++++++++++++++++++------- sourcepawn/compiler/sc4.c | 6 ++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index 3b81465c..7e4d5bd1 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -718,6 +718,7 @@ SC_FUNC void pushval(cell val); SC_FUNC void popreg(regid reg); SC_FUNC void genarray(int dims, int _autozero); SC_FUNC void swap1(void); +SC_FUNC void xchg(void); SC_FUNC void ffswitch(int label); SC_FUNC void ffcase(cell value,char *labelname,int newtable); SC_FUNC void ffcall(symbol *sym,const char *label,int numargs); diff --git a/sourcepawn/compiler/sc3.c b/sourcepawn/compiler/sc3.c index 4e6e31f9..0816fa2a 100644 --- a/sourcepawn/compiler/sc3.c +++ b/sourcepawn/compiler/sc3.c @@ -218,7 +218,8 @@ static void (*unopers[])(void) = { lneg, neg, user_inc, user_dec }; assert(lval!=NULL); if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR) 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 */ 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); if (lval->ident==iARRAYCELL || lval->ident==iARRAYCHAR) popreg(sALT); /* restore address (in ALT) */ - store(lval); /* store PRI in the symbol */ - moveto1(); /* make sure PRI is restored on exit */ + if (lval->ident!=iACCESSOR) { + store(lval); /* store PRI in the symbol */ + moveto1(); /* make sure PRI is restored on exit */ + } } /* if */ return TRUE; } @@ -1901,10 +1904,15 @@ static int hier2(value *lval) } else { pushreg(sPRI); // save obj invoke_getter(lval->accessor); - swap1(); // pri = obj, stack = [oldval] - pushreg(sPRI); // pri = obj, stack = [oldval, obj] + move_alt(); // alt = oldval + 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)) inc_pri(); + popreg(sALT); invoke_setter(lval->accessor, FALSE); popreg(sPRI); @@ -1932,10 +1940,15 @@ static int hier2(value *lval) } else { pushreg(sPRI); // save obj invoke_getter(lval->accessor); - swap1(); // pri = obj, stack = [oldval] - pushreg(sPRI); // pri = obj, stack = [oldval, obj] + move_alt(); // alt = oldval + 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)) dec_pri(); + popreg(sALT); invoke_setter(lval->accessor, FALSE); popreg(sPRI); diff --git a/sourcepawn/compiler/sc4.c b/sourcepawn/compiler/sc4.c index 70c6f06f..e7f00d23 100644 --- a/sourcepawn/compiler/sc4.c +++ b/sourcepawn/compiler/sc4.c @@ -1394,6 +1394,12 @@ SC_FUNC void jmp_eq0(int number) 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 */ SC_FUNC void outval(cell val,int newline) {