diff --git a/Common/include/Luau/Bytecode.h b/Common/include/Luau/Bytecode.h index a4f1d67e..05916c2c 100644 --- a/Common/include/Luau/Bytecode.h +++ b/Common/include/Luau/Bytecode.h @@ -560,6 +560,9 @@ enum LuauBuiltinFunction // tonumber/tostring LBF_TONUMBER, LBF_TOSTRING, + + // bit32.byteswap(n) + LBF_BIT32_BYTESWAP, }; // Capture type, used in LOP_CAPTURE diff --git a/Compiler/src/Builtins.cpp b/Compiler/src/Builtins.cpp index a15c8f08..d1c29d45 100644 --- a/Compiler/src/Builtins.cpp +++ b/Compiler/src/Builtins.cpp @@ -4,6 +4,8 @@ #include "Luau/Bytecode.h" #include "Luau/Compiler.h" +LUAU_FASTFLAG(LuauBit32ByteswapBuiltin) + namespace Luau { namespace Compile @@ -166,6 +168,11 @@ static int getBuiltinFunctionId(const Builtin& builtin, const CompileOptions& op return LBF_BIT32_COUNTLZ; if (builtin.method == "countrz") return LBF_BIT32_COUNTRZ; + if (builtin.method == "byteswap") + { + LUAU_ASSERT(FFlag::LuauBit32ByteswapBuiltin); + return LBF_BIT32_BYTESWAP; + } } if (builtin.object == "string") @@ -402,6 +409,9 @@ BuiltinInfo getBuiltinInfo(int bfid) case LBF_TOSTRING: return {1, 1}; + + case LBF_BIT32_BYTESWAP: + return {1, 1, BuiltinInfo::Flag_NoneSafe}; }; LUAU_UNREACHABLE(); diff --git a/VM/src/lbuiltins.cpp b/VM/src/lbuiltins.cpp index a916f73a..0fa52adc 100644 --- a/VM/src/lbuiltins.cpp +++ b/VM/src/lbuiltins.cpp @@ -1319,6 +1319,21 @@ static int luauF_tostring(lua_State* L, StkId res, TValue* arg0, int nresults, S return -1; } +static int luauF_byteswap(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + unsigned n; + luai_num2unsigned(n, a1); + + setnvalue(res, double(((n >> 24) & 0xff) | ((n << 8) & 0xff0000) | ((n >> 8) & 0xff00) | ((n << 24) & 0xff000000))); + return 1; + } + + return -1; +} + static int luauF_missing(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) { return -1; @@ -1486,6 +1501,8 @@ const luau_FastFunction luauF_table[256] = { luauF_tonumber, luauF_tostring, + luauF_byteswap, + // When adding builtins, add them above this line; what follows is 64 "dummy" entries with luauF_missing fallback. // This is important so that older versions of the runtime that don't support newer builtins automatically fall back via luauF_missing. // Given the builtin addition velocity this should always provide a larger compatibility window than bytecode versions suggest.