From 931d8d619d18c9f3c22611dcc30d920fbf624e91 Mon Sep 17 00:00:00 2001 From: birds3345 <31601136+birds3345@users.noreply.github.com> Date: Fri, 12 Jul 2024 01:33:12 -0400 Subject: [PATCH 1/2] constant fold string comparisons --- Compiler/src/ConstantFolding.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Compiler/src/ConstantFolding.cpp b/Compiler/src/ConstantFolding.cpp index 3b3f9dd2..c4990f52 100644 --- a/Compiler/src/ConstantFolding.cpp +++ b/Compiler/src/ConstantFolding.cpp @@ -6,6 +6,8 @@ #include #include +LUAU_FASTFLAGVARIABLE(LuauConstantFoldStringComparisons, false) + namespace Luau { namespace Compile @@ -157,6 +159,11 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l result.type = Constant::Type_Boolean; result.valueBoolean = la.valueNumber < ra.valueNumber; } + else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) + { + result.type = Constant::Type_Boolean; + result.valueBoolean = strcmp(la.valueString, ra.valueString) < 0; + } break; case AstExprBinary::CompareLe: @@ -165,6 +172,11 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l result.type = Constant::Type_Boolean; result.valueBoolean = la.valueNumber <= ra.valueNumber; } + else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) + { + result.type = Constant::Type_Boolean; + result.valueBoolean = strcmp(la.valueString, ra.valueString) <= 0; + } break; case AstExprBinary::CompareGt: @@ -173,6 +185,11 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l result.type = Constant::Type_Boolean; result.valueBoolean = la.valueNumber > ra.valueNumber; } + else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) + { + result.type = Constant::Type_Boolean; + result.valueBoolean = strcmp(la.valueString, ra.valueString) > 0; + } break; case AstExprBinary::CompareGe: @@ -181,6 +198,11 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l result.type = Constant::Type_Boolean; result.valueBoolean = la.valueNumber >= ra.valueNumber; } + else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) + { + result.type = Constant::Type_Boolean; + result.valueBoolean = strcmp(la.valueString, ra.valueString) >= 0; + } break; case AstExprBinary::And: From 2700bd070c07dae826e195de0f2c340563a2ffad Mon Sep 17 00:00:00 2001 From: birds3345 <31601136+birds3345@users.noreply.github.com> Date: Fri, 12 Jul 2024 02:38:10 -0400 Subject: [PATCH 2/2] correct comparison function --- Compiler/src/ConstantFolding.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Compiler/src/ConstantFolding.cpp b/Compiler/src/ConstantFolding.cpp index c4990f52..9c51aa13 100644 --- a/Compiler/src/ConstantFolding.cpp +++ b/Compiler/src/ConstantFolding.cpp @@ -74,6 +74,17 @@ static void foldUnary(Constant& result, AstExprUnary::Op op, const Constant& arg } } +static int compareStrings(const char* string1, const char* string2, unsigned int size1, unsigned int size2) +{ + unsigned int size = std::min(size1, size2); + + int res = memcmp(string1, string2, size); + if (res != 0 || size1 == size2) + return res; + + return size1 < size2 ? -1 : 1; +} + static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& la, const Constant& ra) { switch (op) @@ -162,7 +173,7 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) { result.type = Constant::Type_Boolean; - result.valueBoolean = strcmp(la.valueString, ra.valueString) < 0; + result.valueBoolean = compareStrings(la.valueString, ra.valueString, la.stringLength, ra.stringLength) < 0; } break; @@ -175,7 +186,7 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) { result.type = Constant::Type_Boolean; - result.valueBoolean = strcmp(la.valueString, ra.valueString) <= 0; + result.valueBoolean = compareStrings(la.valueString, ra.valueString, la.stringLength, ra.stringLength) <= 0; } break; @@ -188,7 +199,7 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) { result.type = Constant::Type_Boolean; - result.valueBoolean = strcmp(la.valueString, ra.valueString) > 0; + result.valueBoolean = compareStrings(la.valueString, ra.valueString, la.stringLength, ra.stringLength) > 0; } break; @@ -201,7 +212,7 @@ static void foldBinary(Constant& result, AstExprBinary::Op op, const Constant& l else if (FFlag::LuauConstantFoldStringComparisons && la.type == Constant::Type_String && ra.type == Constant::Type_String) { result.type = Constant::Type_Boolean; - result.valueBoolean = strcmp(la.valueString, ra.valueString) >= 0; + result.valueBoolean = compareStrings(la.valueString, ra.valueString, la.stringLength, ra.stringLength) >= 0; } break;