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:
parent
59be55b326
commit
30e0f39055
@ -1174,6 +1174,8 @@ const char* parse_variable(const char* p)
|
|||||||
add_scriptl(word);
|
add_scriptl(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_scriptc(C_REF);
|
||||||
|
|
||||||
if( type == C_ADD_PP || type == C_SUB_PP )
|
if( type == C_ADD_PP || type == C_SUB_PP )
|
||||||
{// incremental operator for the method
|
{// incremental operator for the method
|
||||||
add_scripti(1);
|
add_scripti(1);
|
||||||
@ -3209,12 +3211,22 @@ void op_2num(struct script_state* st, int op, int i1, int i2)
|
|||||||
/// Binary operators
|
/// Binary operators
|
||||||
void op_2(struct script_state *st, int op)
|
void op_2(struct script_state *st, int op)
|
||||||
{
|
{
|
||||||
struct script_data* left;
|
struct script_data* left, leftref;
|
||||||
struct script_data* right;
|
struct script_data* right;
|
||||||
|
|
||||||
|
leftref.type = C_NOP;
|
||||||
|
|
||||||
left = script_getdatatop(st, -2);
|
left = script_getdatatop(st, -2);
|
||||||
right = script_getdatatop(st, -1);
|
right = script_getdatatop(st, -1);
|
||||||
|
|
||||||
|
if (st->op2ref)
|
||||||
|
{
|
||||||
|
if (data_isreference(left))
|
||||||
|
leftref = *left;
|
||||||
|
|
||||||
|
st->op2ref = 0;
|
||||||
|
}
|
||||||
|
|
||||||
get_val(st, left);
|
get_val(st, left);
|
||||||
get_val(st, right);
|
get_val(st, right);
|
||||||
|
|
||||||
@ -3236,14 +3248,24 @@ void op_2(struct script_state *st, int op)
|
|||||||
if( data_isstring(left) && data_isstring(right) )
|
if( data_isstring(left) && data_isstring(right) )
|
||||||
{// ss => op_2str
|
{// ss => op_2str
|
||||||
op_2str(st, op, left->u.str, right->u.str);
|
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) )
|
else if( data_isint(left) && data_isint(right) )
|
||||||
{// ii => op_2num
|
{// ii => op_2num
|
||||||
int i1 = left->u.num;
|
int i1 = left->u.num;
|
||||||
int i2 = right->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);
|
op_2num(st, op, i1, i2);
|
||||||
|
|
||||||
|
if (leftref.type != C_NOP)
|
||||||
|
*left = leftref;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{// invalid argument
|
{// invalid argument
|
||||||
@ -3685,6 +3707,10 @@ void run_script_main(struct script_state *st)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case C_REF:
|
||||||
|
st->op2ref = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case C_NEG:
|
case C_NEG:
|
||||||
case C_NOT:
|
case C_NOT:
|
||||||
case C_LNOT:
|
case C_LNOT:
|
||||||
|
@ -47,6 +47,7 @@ typedef enum c_op {
|
|||||||
C_RETINFO,
|
C_RETINFO,
|
||||||
C_USERFUNC, // internal script function
|
C_USERFUNC, // internal script function
|
||||||
C_USERFUNC_POS, // internal script function label
|
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
|
// operators
|
||||||
C_OP3, // a ? b : c
|
C_OP3, // a ? b : c
|
||||||
@ -130,6 +131,7 @@ struct script_state {
|
|||||||
struct script_state *bk_st;
|
struct script_state *bk_st;
|
||||||
int bk_npcid;
|
int bk_npcid;
|
||||||
unsigned freeloop : 1;// used by buildin_freeloop
|
unsigned freeloop : 1;// used by buildin_freeloop
|
||||||
|
unsigned op2ref : 1;// used by op_2
|
||||||
};
|
};
|
||||||
|
|
||||||
struct script_reg {
|
struct script_reg {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user