Fixed bugreport:5740 var reference was not being restored to call buildin_set on assignment statements.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16300 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
greenboxal2 2012-06-15 00:30:20 +00:00
parent 59be55b326
commit 30e0f39055
2 changed files with 31 additions and 3 deletions

View File

@ -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:

View File

@ -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 {