@ -1337,18 +1337,20 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
* * ( everything but logical operators ' and ' / ' or ' and comparison
* * ( everything but logical operators ' and ' / ' or ' and comparison
* * operators ) .
* * operators ) .
* * Expression to produce final result will be encoded in ' e1 ' .
* * Expression to produce final result will be encoded in ' e1 ' .
* * Because ' luaK_exp2anyreg ' can free registers , its calls must be
* * in " stack order " ( that is , first on ' e2 ' , which may have more
* * recent registers to be released ) .
*/
*/
static void finishbinexpval ( FuncState * fs , expdesc * e1 , expdesc * e2 ,
static void finishbinexpval ( FuncState * fs , expdesc * e1 , expdesc * e2 ,
OpCode op , int v2 , int k , int line ) {
OpCode op , int v2 , int k , int line ,
OpCode mmop , TMS event ) {
int v1 = luaK_exp2anyreg ( fs , e1 ) ;
int v1 = luaK_exp2anyreg ( fs , e1 ) ;
int pc = luaK_codeABCk ( fs , op , 0 , v1 , v2 , k ) ;
int pc = luaK_codeABCk ( fs , op , 0 , v1 , v2 , k ) ;
freeexps ( fs , e1 , e2 ) ;
freeexps ( fs , e1 , e2 ) ;
e1 - > u . info = pc ;
e1 - > u . info = pc ;
e1 - > k = VRELOC ; /* all those operations are relocatable */
e1 - > k = VRELOC ; /* all those operations are relocatable */
luaK_fixline ( fs , line ) ;
luaK_fixline ( fs , line ) ;
if ( event ! = TM_SHL & & event ! = TM_SHR ) {
luaK_codeABCk ( fs , mmop , v1 , v2 , event , k ) ; /* to call metamethod */
luaK_fixline ( fs , line ) ;
}
}
}
@ -1359,7 +1361,9 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
static void codebinexpval ( FuncState * fs , OpCode op ,
static void codebinexpval ( FuncState * fs , OpCode op ,
expdesc * e1 , expdesc * e2 , int line ) {
expdesc * e1 , expdesc * e2 , int line ) {
int v2 = luaK_exp2anyreg ( fs , e2 ) ; /* both operands are in registers */
int v2 = luaK_exp2anyreg ( fs , e2 ) ; /* both operands are in registers */
finishbinexpval ( fs , e1 , e2 , op , v2 , 0 , line ) ;
lua_assert ( OP_ADD < = op & & op < = OP_SHR ) ;
finishbinexpval ( fs , e1 , e2 , op , v2 , 0 , line , OP_MMBIN ,
cast ( TMS , ( op - OP_ADD ) + TM_ADD ) ) ;
}
}
@ -1367,9 +1371,10 @@ static void codebinexpval (FuncState *fs, OpCode op,
* * Code binary operators ( ' + ' , ' - ' , . . . ) with immediate operands .
* * Code binary operators ( ' + ' , ' - ' , . . . ) with immediate operands .
*/
*/
static void codebini ( FuncState * fs , OpCode op ,
static void codebini ( FuncState * fs , OpCode op ,
expdesc * e1 , expdesc * e2 , int k , int line ) {
expdesc * e1 , expdesc * e2 , int k , int line ,
TMS event ) {
int v2 = cast_int ( e2 - > u . ival ) + OFFSET_sC ; /* immediate operand */
int v2 = cast_int ( e2 - > u . ival ) + OFFSET_sC ; /* immediate operand */
finishbinexpval ( fs , e1 , e2 , op , v2 , k , line ) ;
finishbinexpval ( fs , e1 , e2 , op , v2 , k , line , OP_MMBINI , event ) ;
}
}
@ -1383,16 +1388,18 @@ static void swapexps (expdesc *e1, expdesc *e2) {
* * constant in the proper range , use variant opcodes with immediate
* * constant in the proper range , use variant opcodes with immediate
* * operands or K operands .
* * operands or K operands .
*/
*/
static void codearith ( FuncState * fs , OpCode op ,
static void codearith ( FuncState * fs , BinOpr opr ,
expdesc * e1 , expdesc * e2 , int flip , int line ) {
expdesc * e1 , expdesc * e2 , int flip , int line ) {
TMS event = cast ( TMS , opr + TM_ADD ) ;
if ( isSCint ( e2 ) ) /* immediate operand? */
if ( isSCint ( e2 ) ) /* immediate operand? */
codebini ( fs , cast ( OpCode , op - OP_ADD + OP_ADDI ) , e1 , e2 , flip , line ) ;
codebini ( fs , cast ( OpCode , opr + OP_ADDI ) , e1 , e2 , flip , line , event ) ;
else if ( tonumeral ( e2 , NULL ) & & luaK_exp2K ( fs , e2 ) ) { /* K operand? */
else if ( tonumeral ( e2 , NULL ) & & luaK_exp2K ( fs , e2 ) ) { /* K operand? */
int v2 = e2 - > u . info ; /* K index */
int v2 = e2 - > u . info ; /* K index */
op = cast ( OpCode , op - OP_ADD + OP_ADDK ) ;
OpCode op = cast ( OpCode , opr + OP_ADDK ) ;
finishbinexpval ( fs , e1 , e2 , op , v2 , flip , line ) ;
finishbinexpval ( fs , e1 , e2 , op , v2 , flip , line , OP_MMBINK , event ) ;
}
}
else { /* 'e2' is neither an immediate nor a K operand */
else { /* 'e2' is neither an immediate nor a K operand */
OpCode op = cast ( OpCode , opr + OP_ADD ) ;
if ( flip )
if ( flip )
swapexps ( e1 , e2 ) ; /* back to original order */
swapexps ( e1 , e2 ) ; /* back to original order */
codebinexpval ( fs , op , e1 , e2 , line ) ; /* use standard operators */
codebinexpval ( fs , op , e1 , e2 , line ) ; /* use standard operators */
@ -1405,7 +1412,7 @@ static void codearith (FuncState *fs, OpCode op,
* * numeric constant , change order of operands to try to use an
* * numeric constant , change order of operands to try to use an
* * immediate or K operator .
* * immediate or K operator .
*/
*/
static void codecommutative ( FuncState * fs , OpCode op ,
static void codecommutative ( FuncState * fs , BinOpr op ,
expdesc * e1 , expdesc * e2 , int line ) {
expdesc * e1 , expdesc * e2 , int line ) {
int flip = 0 ;
int flip = 0 ;
if ( tonumeral ( e1 , NULL ) ) { /* is first operand a numeric constant? */
if ( tonumeral ( e1 , NULL ) ) { /* is first operand a numeric constant? */
@ -1430,14 +1437,15 @@ static void codebitwise (FuncState *fs, BinOpr opr,
inv = 1 ;
inv = 1 ;
}
}
else if ( ! ( e2 - > k = = VKINT & & luaK_exp2RK ( fs , e2 ) ) ) { /* no constants? */
else if ( ! ( e2 - > k = = VKINT & & luaK_exp2RK ( fs , e2 ) ) ) { /* no constants? */
op = cast ( OpCode , opr - OPR_BAND + OP_BAN D) ;
op = cast ( OpCode , opr + OP_AD D) ;
codebinexpval ( fs , op , e1 , e2 , line ) ; /* all-register opcodes */
codebinexpval ( fs , op , e1 , e2 , line ) ; /* all-register opcodes */
return ;
return ;
}
}
v2 = e2 - > u . info ; /* index in K array */
v2 = e2 - > u . info ; /* index in K array */
op = cast ( OpCode , opr - OPR_BAND + OP_BAN DK) ;
op = cast ( OpCode , opr + OP_AD DK) ;
lua_assert ( ttisinteger ( & fs - > f - > k [ v2 ] ) ) ;
lua_assert ( ttisinteger ( & fs - > f - > k [ v2 ] ) ) ;
finishbinexpval ( fs , e1 , e2 , op , v2 , inv , line ) ;
finishbinexpval ( fs , e1 , e2 , op , v2 , inv , line , OP_MMBINK ,
cast ( TMS , opr + TM_ADD ) ) ;
}
}
@ -1453,7 +1461,7 @@ static void codeshift (FuncState *fs, OpCode op,
changedir = 1 ;
changedir = 1 ;
e2 - > u . ival = - ( e2 - > u . ival ) ;
e2 - > u . ival = - ( e2 - > u . ival ) ;
}
}
codebini ( fs , OP_SHRI , e1 , e2 , changedir , line ) ;
codebini ( fs , OP_SHRI , e1 , e2 , changedir , line , TM_SHL ) ;
}
}
else
else
codebinexpval ( fs , op , e1 , e2 , line ) ;
codebinexpval ( fs , op , e1 , e2 , line ) ;
@ -1638,13 +1646,13 @@ void luaK_posfix (FuncState *fs, BinOpr opr,
}
}
case OPR_ADD : case OPR_MUL : {
case OPR_ADD : case OPR_MUL : {
if ( ! constfolding ( fs , opr + LUA_OPADD , e1 , e2 ) )
if ( ! constfolding ( fs , opr + LUA_OPADD , e1 , e2 ) )
codecommutative ( fs , cast ( OpCode , opr + OP_ADD ) , e1 , e2 , line ) ;
codecommutative ( fs , opr , e1 , e2 , line ) ;
break ;
break ;
}
}
case OPR_SUB : case OPR_DIV :
case OPR_SUB : case OPR_DIV :
case OPR_IDIV : case OPR_MOD : case OPR_POW : {
case OPR_IDIV : case OPR_MOD : case OPR_POW : {
if ( ! constfolding ( fs , opr + LUA_OPADD , e1 , e2 ) )
if ( ! constfolding ( fs , opr + LUA_OPADD , e1 , e2 ) )
codearith ( fs , cast ( OpCode , opr + OP_ADD ) , e1 , e2 , 0 , line ) ;
codearith ( fs , opr , e1 , e2 , 0 , line ) ;
break ;
break ;
}
}
case OPR_BAND : case OPR_BOR : case OPR_BXOR : {
case OPR_BAND : case OPR_BOR : case OPR_BXOR : {
@ -1656,7 +1664,7 @@ void luaK_posfix (FuncState *fs, BinOpr opr,
if ( ! constfolding ( fs , LUA_OPSHL , e1 , e2 ) ) {
if ( ! constfolding ( fs , LUA_OPSHL , e1 , e2 ) ) {
if ( isSCint ( e1 ) ) {
if ( isSCint ( e1 ) ) {
swapexps ( e1 , e2 ) ;
swapexps ( e1 , e2 ) ;
codebini ( fs , OP_SHLI , e1 , e2 , 1 , line ) ;
codebini ( fs , OP_SHLI , e1 , e2 , 1 , line , TM_SHL ) ;
}
}
else
else
codeshift ( fs , OP_SHL , e1 , e2 , line ) ;
codeshift ( fs , OP_SHL , e1 , e2 , line ) ;