mirror of
https://github.com/luau-lang/luau.git
synced 2025-04-07 04:10:54 +01:00
# What's Changed * Fix a case where the stack wasn't completely cleaned up where `debug.info` errored when passed `"f"` option and a thread. * Fix a case of uninitialized field in `luaF_newproto`. ### New Type Solver * When a local is captured in a function, don't add a new entry to the `DfgScope::bindings` if the capture occurs within a loop. * Fix a poor performance characteristic during unification by not trying to simplify an intersection. * Fix a case of multiple constraints mutating the same blocked type causing incorrect inferences. * Fix a case of assertion failure when overload resolution encounters a return typepack mismatch. * When refining a property of the top `table` type, we no longer signal an unknown property error. * Fix a misuse of free types when trying to infer the type of a subscript expression. * Fix a case of assertion failure when trying to resolve an overload from `never`. ### Native Code Generation * Fix dead store optimization issues caused by partial stores. --- ### Internal Contributors Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: David Cope <dcope@roblox.com> Co-authored-by: Lily Brown <lbrown@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> --------- Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Vighnesh <vvijay@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: David Cope <dcope@roblox.com> Co-authored-by: Lily Brown <lbrown@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
118 lines
3.7 KiB
C++
118 lines
3.7 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
#include "EmitBuiltinsX64.h"
|
|
|
|
#include "Luau/Bytecode.h"
|
|
|
|
#include "Luau/AssemblyBuilderX64.h"
|
|
#include "Luau/IrCallWrapperX64.h"
|
|
#include "Luau/IrRegAllocX64.h"
|
|
|
|
#include "EmitCommonX64.h"
|
|
#include "NativeState.h"
|
|
|
|
#include "lstate.h"
|
|
|
|
LUAU_FASTFLAG(LuauCodegenRemoveDeadStores3)
|
|
|
|
namespace Luau
|
|
{
|
|
namespace CodeGen
|
|
{
|
|
namespace X64
|
|
{
|
|
|
|
static void emitBuiltinMathFrexp(IrRegAllocX64& regs, AssemblyBuilderX64& build, int ra, int arg, int nresults)
|
|
{
|
|
IrCallWrapperX64 callWrap(regs, build);
|
|
callWrap.addArgument(SizeX64::xmmword, luauRegValue(arg));
|
|
callWrap.addArgument(SizeX64::qword, sTemporarySlot);
|
|
callWrap.call(qword[rNativeContext + offsetof(NativeContext, libm_frexp)]);
|
|
|
|
build.vmovsd(luauRegValue(ra), xmm0);
|
|
|
|
if (FFlag::LuauCodegenRemoveDeadStores3)
|
|
build.mov(luauRegTag(ra), LUA_TNUMBER);
|
|
|
|
if (nresults > 1)
|
|
{
|
|
build.vcvtsi2sd(xmm0, xmm0, dword[sTemporarySlot + 0]);
|
|
build.vmovsd(luauRegValue(ra + 1), xmm0);
|
|
|
|
if (FFlag::LuauCodegenRemoveDeadStores3)
|
|
build.mov(luauRegTag(ra + 1), LUA_TNUMBER);
|
|
}
|
|
}
|
|
|
|
static void emitBuiltinMathModf(IrRegAllocX64& regs, AssemblyBuilderX64& build, int ra, int arg, int nresults)
|
|
{
|
|
IrCallWrapperX64 callWrap(regs, build);
|
|
callWrap.addArgument(SizeX64::xmmword, luauRegValue(arg));
|
|
callWrap.addArgument(SizeX64::qword, sTemporarySlot);
|
|
callWrap.call(qword[rNativeContext + offsetof(NativeContext, libm_modf)]);
|
|
|
|
build.vmovsd(xmm1, qword[sTemporarySlot + 0]);
|
|
build.vmovsd(luauRegValue(ra), xmm1);
|
|
|
|
if (FFlag::LuauCodegenRemoveDeadStores3)
|
|
build.mov(luauRegTag(ra), LUA_TNUMBER);
|
|
|
|
if (nresults > 1)
|
|
{
|
|
build.vmovsd(luauRegValue(ra + 1), xmm0);
|
|
|
|
if (FFlag::LuauCodegenRemoveDeadStores3)
|
|
build.mov(luauRegTag(ra + 1), LUA_TNUMBER);
|
|
}
|
|
}
|
|
|
|
static void emitBuiltinMathSign(IrRegAllocX64& regs, AssemblyBuilderX64& build, int ra, int arg)
|
|
{
|
|
ScopedRegX64 tmp0{regs, SizeX64::xmmword};
|
|
ScopedRegX64 tmp1{regs, SizeX64::xmmword};
|
|
ScopedRegX64 tmp2{regs, SizeX64::xmmword};
|
|
ScopedRegX64 tmp3{regs, SizeX64::xmmword};
|
|
|
|
build.vmovsd(tmp0.reg, luauRegValue(arg));
|
|
build.vxorpd(tmp1.reg, tmp1.reg, tmp1.reg);
|
|
|
|
// Set tmp2 to -1 if arg < 0, else 0
|
|
build.vcmpltsd(tmp2.reg, tmp0.reg, tmp1.reg);
|
|
build.vmovsd(tmp3.reg, build.f64(-1));
|
|
build.vandpd(tmp2.reg, tmp2.reg, tmp3.reg);
|
|
|
|
// Set mask bit to 1 if 0 < arg, else 0
|
|
build.vcmpltsd(tmp0.reg, tmp1.reg, tmp0.reg);
|
|
|
|
// Result = (mask-bit == 1) ? 1.0 : tmp2
|
|
// If arg < 0 then tmp2 is -1 and mask-bit is 0, result is -1
|
|
// If arg == 0 then tmp2 is 0 and mask-bit is 0, result is 0
|
|
// If arg > 0 then tmp2 is 0 and mask-bit is 1, result is 1
|
|
build.vblendvpd(tmp0.reg, tmp2.reg, build.f64x2(1, 1), tmp0.reg);
|
|
|
|
build.vmovsd(luauRegValue(ra), tmp0.reg);
|
|
|
|
if (FFlag::LuauCodegenRemoveDeadStores3)
|
|
build.mov(luauRegTag(ra), LUA_TNUMBER);
|
|
}
|
|
|
|
void emitBuiltin(IrRegAllocX64& regs, AssemblyBuilderX64& build, int bfid, int ra, int arg, OperandX64 arg2, int nparams, int nresults)
|
|
{
|
|
switch (bfid)
|
|
{
|
|
case LBF_MATH_FREXP:
|
|
CODEGEN_ASSERT(nparams == 1 && (nresults == 1 || nresults == 2));
|
|
return emitBuiltinMathFrexp(regs, build, ra, arg, nresults);
|
|
case LBF_MATH_MODF:
|
|
CODEGEN_ASSERT(nparams == 1 && (nresults == 1 || nresults == 2));
|
|
return emitBuiltinMathModf(regs, build, ra, arg, nresults);
|
|
case LBF_MATH_SIGN:
|
|
CODEGEN_ASSERT(nparams == 1 && nresults == 1);
|
|
return emitBuiltinMathSign(regs, build, ra, arg);
|
|
default:
|
|
CODEGEN_ASSERT(!"Missing x64 lowering");
|
|
}
|
|
}
|
|
|
|
} // namespace X64
|
|
} // namespace CodeGen
|
|
} // namespace Luau
|