diff options
author | greenboxal2 <greenboxal2@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-06-15 00:30:20 +0000 |
---|---|---|
committer | greenboxal2 <greenboxal2@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-06-15 00:30:20 +0000 |
commit | 22d2718db209b1d75a75b4976b882ed659d22ee5 (patch) | |
tree | e5450a75b4d9feb15534e08799b5dad3902610b0 | |
parent | 7b1562b07d55a2712021803eab923200d6891494 (diff) | |
download | hercules-22d2718db209b1d75a75b4976b882ed659d22ee5.tar.gz hercules-22d2718db209b1d75a75b4976b882ed659d22ee5.tar.bz2 hercules-22d2718db209b1d75a75b4976b882ed659d22ee5.tar.xz hercules-22d2718db209b1d75a75b4976b882ed659d22ee5.zip |
Fixed bugreport:5740 var reference was not being restored to call buildin_set on assignment statements.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16300 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r-- | src/map/script.c | 32 | ||||
-rw-r--r-- | src/map/script.h | 2 |
2 files changed, 31 insertions, 3 deletions
diff --git a/src/map/script.c b/src/map/script.c index 9d683850c..8c3ce0e1f 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -1174,6 +1174,8 @@ const char* parse_variable(const char* p) add_scriptl(word); } + add_scriptc(C_REF); + if( type == C_ADD_PP || type == C_SUB_PP ) {// incremental operator for the method add_scripti(1); @@ -3209,12 +3211,22 @@ void op_2num(struct script_state* st, int op, int i1, int i2) /// Binary operators void op_2(struct script_state *st, int op) { - struct script_data* left; + struct script_data* left, leftref; struct script_data* right; + leftref.type = C_NOP; + left = script_getdatatop(st, -2); right = script_getdatatop(st, -1); + if (st->op2ref) + { + if (data_isreference(left)) + leftref = *left; + + st->op2ref = 0; + } + get_val(st, left); get_val(st, right); @@ -3236,14 +3248,24 @@ void op_2(struct script_state *st, int op) if( data_isstring(left) && data_isstring(right) ) {// ss => op_2str op_2str(st, op, left->u.str, right->u.str); - script_removetop(st, -3, -1);// pop the two values before the top one + script_removetop(st, leftref.type == C_NOP ? -3 : -2, -1);// pop the two values before the top one + + if (leftref.type != C_NOP) + { + aFree(left->u.str); + *left = leftref; + } } else if( data_isint(left) && data_isint(right) ) {// ii => op_2num int i1 = left->u.num; int i2 = right->u.num; - script_removetop(st, -2, 0); + + script_removetop(st, leftref.type == C_NOP ? -2 : -1, 0); op_2num(st, op, i1, i2); + + if (leftref.type != C_NOP) + *left = leftref; } else {// invalid argument @@ -3685,6 +3707,10 @@ void run_script_main(struct script_state *st) } break; + case C_REF: + st->op2ref = 1; + break; + case C_NEG: case C_NOT: case C_LNOT: diff --git a/src/map/script.h b/src/map/script.h index 4d7754241..eed4c20c8 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -47,6 +47,7 @@ typedef enum c_op { C_RETINFO, C_USERFUNC, // internal script function C_USERFUNC_POS, // internal script function label + C_REF, // the next call to c_op2 should push back a ref to the left operand // operators C_OP3, // a ? b : c @@ -130,6 +131,7 @@ struct script_state { struct script_state *bk_st; int bk_npcid; unsigned freeloop : 1;// used by buildin_freeloop + unsigned op2ref : 1;// used by op_2 }; struct script_reg { |