Skip to content

Commit 2d2c139

Browse files
committed
Fix some issues with RK variant opcodes in LSL
1 parent 19ced5e commit 2d2c139

File tree

4 files changed

+56
-14
lines changed

4 files changed

+56
-14
lines changed

Compiler/src/LSLCompiler.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,21 +1459,31 @@ bool LuauVisitor::visit(LSLBinaryExpression* bin_expr)
14591459
}
14601460

14611461
// Check if we can use RK-variant opcodes for SUB/DIV
1462-
// Only check this for operations that actually have reversed K-variants
1463-
if ((op == '-' || op == '/') &&
1464-
lhs->getNodeSubType() == NODE_CONSTANT_EXPRESSION &&
1465-
(lhs->getIType() == LST_INTEGER || lhs->getIType() == LST_FLOATINGPOINT))
1462+
// SUBRK supports both integers and floats, DIVRK only supports floats
1463+
if (lhs->getNodeSubType() == NODE_CONSTANT_EXPRESSION)
14661464
{
1467-
auto* lhs_const = dynamic_cast<LSLConstantExpression*>(lhs);
1468-
auto lhs_const_idx = addConstant(lhs_const->getConstantValue());
1465+
LuauOpcode rk_op = LOP_NOP;
1466+
if (op == '-' && (lhs->getIType() == LST_INTEGER || lhs->getIType() == LST_FLOATINGPOINT))
1467+
{
1468+
rk_op = LOP_SUBRK;
1469+
}
1470+
else if (op == '/' && lhs->getIType() == LST_FLOATINGPOINT)
1471+
{
1472+
// DIVRK only works with floats - no IDIVRK exists
1473+
rk_op = LOP_DIVRK;
1474+
}
14691475

1470-
// Constant index is low enough to fit
1471-
if (lhs_const_idx >= 0 && lhs_const_idx <= 255)
1476+
if (rk_op != LOP_NOP)
14721477
{
1473-
LuauOpcode rk_op = (op == '-') ? LOP_SUBRK : LOP_DIVRK;
1474-
mBuilder->emitABC(rk_op, target_reg, (uint8_t)lhs_const_idx, rhs_reg);
1475-
// maybeMove(expected_target, target_reg);
1476-
return false;
1478+
auto* lhs_const = dynamic_cast<LSLConstantExpression*>(lhs);
1479+
auto lhs_const_idx = addConstant(lhs_const->getConstantValue());
1480+
1481+
// Constant index is low enough to fit
1482+
if (lhs_const_idx >= 0 && lhs_const_idx <= 255)
1483+
{
1484+
mBuilder->emitABC(rk_op, target_reg, (uint8_t)lhs_const_idx, rhs_reg);
1485+
return false;
1486+
}
14771487
}
14781488
}
14791489

VM/src/lvmexecute.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,14 +3041,18 @@ static void luau_execute(lua_State* L)
30413041
TValue* kv = VM_KV(LUAU_INSN_B(insn));
30423042
StkId rc = VM_REG(LUAU_INSN_C(insn));
30433043

3044-
// NOTE: ServerLua can't use these for integer-aware paths!
3045-
30463044
// fast-path
30473045
if (ttisnumber(rc))
30483046
{
30493047
setnvalue(ra, nvalue(kv) - nvalue(rc));
30503048
VM_NEXT();
30513049
}
3050+
else if (l_isinteger(kv) && l_isinteger(rc))
3051+
{
3052+
// ServerLua: integer math
3053+
setintvalue(ra, intvalue(kv) - intvalue(rc));
3054+
VM_NEXT();
3055+
}
30523056
else
30533057
{
30543058
// slow-path, may invoke C/Lua via metamethods

tests/LSL.test.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,11 @@ TEST_CASE("Extensive LSL Ares Test")
10311031
runAresYieldTest("conformance2_yield.lsl");
10321032
}
10331033

1034+
TEST_CASE("RK optimization issues")
1035+
{
1036+
runConformance("rk_issues.lsl");
1037+
}
1038+
10341039

10351040
static std::string mono_to_lower_string(const std::string &str)
10361041
{

tests/conformance/rk_issues.lsl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
checkTruth(string name, integer val)
2+
{
3+
if (!val)
4+
{
5+
llOwnerSay(name + ": FAILED");
6+
// Force a crash.
7+
llOwnerSay((string)(0/0));
8+
}
9+
}
10+
11+
default {
12+
state_entry() {
13+
integer a = (1 - (0 / 3));
14+
integer b = 3 - 4;
15+
float c = (1.0 - (0 / 3.0));
16+
float d = 3.0 - 4.0;
17+
list foo = [a, b, c, d];
18+
checkTruth("a is integer", llGetListEntryType(foo, 0) == TYPE_INTEGER);
19+
checkTruth("b is integer", llGetListEntryType(foo, 1) == TYPE_INTEGER);
20+
checkTruth("c is float", llGetListEntryType(foo, 2) == TYPE_FLOAT);
21+
checkTruth("d is float", llGetListEntryType(foo, 3) == TYPE_FLOAT);
22+
}
23+
}

0 commit comments

Comments
 (0)