From a5b550432067d562205a57cffc788df44ab6c103 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Sun, 12 May 2024 23:27:27 +0100 Subject: [PATCH] v0.9.1+luau625 --- Cargo.toml | 2 +- luau/Ast/src/Parser.cpp | 26 +++++------ luau/CodeGen/include/Luau/BytecodeAnalysis.h | 3 +- luau/CodeGen/include/Luau/CodeGen.h | 42 +++++++++++++++-- luau/CodeGen/include/Luau/IrBuilder.h | 10 ++-- luau/CodeGen/src/BytecodeAnalysis.cpp | 49 ++++++++++++++++++-- luau/CodeGen/src/CodeGen.cpp | 42 +++++++++++++---- luau/CodeGen/src/CodeGenAssembly.cpp | 6 +-- luau/CodeGen/src/CodeGenContext.cpp | 22 ++++----- luau/CodeGen/src/CodeGenContext.h | 4 +- luau/CodeGen/src/IrBuilder.cpp | 26 +++++++---- luau/CodeGen/src/IrTranslation.cpp | 30 ++++++++++-- luau/CodeGen/src/IrTranslation.h | 2 +- luau/CodeGen/src/lcodegen.cpp | 3 +- 14 files changed, 202 insertions(+), 65 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d86597e..8bc081e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "luau0-src" -version = "0.9.0+luau624" +version = "0.9.1+luau625" authors = ["Aleksandr Orlenko "] edition = "2021" repository = "https://github.com/khvzak/luau-src-rs" diff --git a/luau/Ast/src/Parser.cpp b/luau/Ast/src/Parser.cpp index a736355..8bbdf30 100644 --- a/luau/Ast/src/Parser.cpp +++ b/luau/Ast/src/Parser.cpp @@ -17,7 +17,6 @@ LUAU_FASTINTVARIABLE(LuauParseErrorLimit, 100) // flag so that we don't break production games by reverting syntax changes. // See docs/SyntaxChanges.md for an explanation. LUAU_FASTFLAG(LuauCheckedFunctionSyntax) -LUAU_FASTFLAGVARIABLE(LuauReadWritePropertySyntax, false) LUAU_FASTFLAGVARIABLE(DebugLuauDeferredConstraintResolution, false) namespace Luau @@ -1340,22 +1339,19 @@ AstType* Parser::parseTableType(bool inDeclarationContext) AstTableAccess access = AstTableAccess::ReadWrite; std::optional accessLocation; - if (FFlag::LuauReadWritePropertySyntax || FFlag::DebugLuauDeferredConstraintResolution) + if (lexer.current().type == Lexeme::Name && lexer.lookahead().type != ':') { - if (lexer.current().type == Lexeme::Name && lexer.lookahead().type != ':') + if (AstName(lexer.current().name) == "read") { - if (AstName(lexer.current().name) == "read") - { - accessLocation = lexer.current().location; - access = AstTableAccess::Read; - lexer.next(); - } - else if (AstName(lexer.current().name) == "write") - { - accessLocation = lexer.current().location; - access = AstTableAccess::Write; - lexer.next(); - } + accessLocation = lexer.current().location; + access = AstTableAccess::Read; + lexer.next(); + } + else if (AstName(lexer.current().name) == "write") + { + accessLocation = lexer.current().location; + access = AstTableAccess::Write; + lexer.next(); } } diff --git a/luau/CodeGen/include/Luau/BytecodeAnalysis.h b/luau/CodeGen/include/Luau/BytecodeAnalysis.h index 11af90d..edfa6e3 100644 --- a/luau/CodeGen/include/Luau/BytecodeAnalysis.h +++ b/luau/CodeGen/include/Luau/BytecodeAnalysis.h @@ -13,10 +13,11 @@ namespace CodeGen { struct IrFunction; +struct HostIrHooks; void loadBytecodeTypeInfo(IrFunction& function); void buildBytecodeBlocks(IrFunction& function, const std::vector& jumpTargets); -void analyzeBytecodeTypes(IrFunction& function); +void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks); } // namespace CodeGen } // namespace Luau diff --git a/luau/CodeGen/include/Luau/CodeGen.h b/luau/CodeGen/include/Luau/CodeGen.h index 9b56034..4399323 100644 --- a/luau/CodeGen/include/Luau/CodeGen.h +++ b/luau/CodeGen/include/Luau/CodeGen.h @@ -66,6 +66,39 @@ struct CompilationResult } }; +struct IrBuilder; + +using HostVectorOperationBytecodeType = uint8_t (*)(const char* member, size_t memberLength); +using HostVectorAccessHandler = bool (*)(IrBuilder& builder, const char* member, size_t memberLength, int resultReg, int sourceReg, int pcpos); +using HostVectorNamecallHandler = bool (*)( + IrBuilder& builder, const char* member, size_t memberLength, int argResReg, int sourceReg, int params, int results, int pcpos); + +struct HostIrHooks +{ + // Suggest result type of a vector field access + HostVectorOperationBytecodeType vectorAccessBytecodeType = nullptr; + + // Suggest result type of a vector function namecall + HostVectorOperationBytecodeType vectorNamecallBytecodeType = nullptr; + + // Handle vector value field access + // 'sourceReg' is guaranteed to be a vector + // Guards should take a VM exit to 'pcpos' + HostVectorAccessHandler vectorAccess = nullptr; + + // Handle namecalled performed on a vector value + // 'sourceReg' (self argument) is guaranteed to be a vector + // All other arguments can be of any type + // Guards should take a VM exit to 'pcpos' + HostVectorNamecallHandler vectorNamecall = nullptr; +}; + +struct CompilationOptions +{ + unsigned int flags = 0; + HostIrHooks hooks; +}; + struct CompilationStats { size_t bytecodeSizeBytes = 0; @@ -118,8 +151,11 @@ void setNativeExecutionEnabled(lua_State* L, bool enabled); using ModuleId = std::array; // Builds target function and all inner functions -CompilationResult compile(lua_State* L, int idx, unsigned int flags = 0, CompilationStats* stats = nullptr); -CompilationResult compile(const ModuleId& moduleId, lua_State* L, int idx, unsigned int flags = 0, CompilationStats* stats = nullptr); +CompilationResult compile(lua_State* L, int idx, unsigned int flags, CompilationStats* stats = nullptr); +CompilationResult compile(const ModuleId& moduleId, lua_State* L, int idx, unsigned int flags, CompilationStats* stats = nullptr); + +CompilationResult compile(lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats = nullptr); +CompilationResult compile(const ModuleId& moduleId, lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats = nullptr); using AnnotatorFn = void (*)(void* context, std::string& result, int fid, int instpos); @@ -164,7 +200,7 @@ struct AssemblyOptions Target target = Host; - unsigned int flags = 0; + CompilationOptions compilationOptions; bool outputBinary = false; diff --git a/luau/CodeGen/include/Luau/IrBuilder.h b/luau/CodeGen/include/Luau/IrBuilder.h index 6c975e8..8ad75fb 100644 --- a/luau/CodeGen/include/Luau/IrBuilder.h +++ b/luau/CodeGen/include/Luau/IrBuilder.h @@ -16,11 +16,11 @@ namespace Luau namespace CodeGen { -struct AssemblyOptions; +struct HostIrHooks; struct IrBuilder { - IrBuilder(); + IrBuilder(const HostIrHooks& hostHooks); void buildFunctionIr(Proto* proto); @@ -64,13 +64,17 @@ struct IrBuilder IrOp vmExit(uint32_t pcpos); + const HostIrHooks& hostHooks; + bool inTerminatedBlock = false; bool interruptRequested = false; bool activeFastcallFallback = false; IrOp fastcallFallbackReturn; - int fastcallSkipTarget = -1; + + // Force builder to skip source commands + int cmdSkipTarget = -1; IrFunction function; diff --git a/luau/CodeGen/src/BytecodeAnalysis.cpp b/luau/CodeGen/src/BytecodeAnalysis.cpp index e3ce916..a2f67eb 100644 --- a/luau/CodeGen/src/BytecodeAnalysis.cpp +++ b/luau/CodeGen/src/BytecodeAnalysis.cpp @@ -2,6 +2,7 @@ #include "Luau/BytecodeAnalysis.h" #include "Luau/BytecodeUtils.h" +#include "Luau/CodeGen.h" #include "Luau/IrData.h" #include "Luau/IrUtils.h" @@ -17,6 +18,8 @@ LUAU_FASTFLAG(LuauLoadTypeInfo) // Because new VM typeinfo loa LUAU_FASTFLAGVARIABLE(LuauCodegenTypeInfo, false) // New analysis is flagged separately LUAU_FASTFLAG(LuauTypeInfoLookupImprovement) LUAU_FASTFLAGVARIABLE(LuauCodegenVectorMispredictFix, false) +LUAU_FASTFLAGVARIABLE(LuauCodegenAnalyzeHostVectorOps, false) +LUAU_FASTFLAGVARIABLE(LuauCodegenLoadTypeUpvalCheck, false) namespace Luau { @@ -95,7 +98,10 @@ void loadBytecodeTypeInfo(IrFunction& function) uint32_t upvalCount = readVarInt(data, offset); uint32_t localCount = readVarInt(data, offset); - CODEGEN_ASSERT(upvalCount == unsigned(proto->nups)); + if (!FFlag::LuauCodegenLoadTypeUpvalCheck) + { + CODEGEN_ASSERT(upvalCount == unsigned(proto->nups)); + } if (typeSize != 0) { @@ -114,6 +120,11 @@ void loadBytecodeTypeInfo(IrFunction& function) if (upvalCount != 0) { + if (FFlag::LuauCodegenLoadTypeUpvalCheck) + { + CODEGEN_ASSERT(upvalCount == unsigned(proto->nups)); + } + typeInfo.upvalueTypes.resize(upvalCount); uint8_t* types = (uint8_t*)data + offset; @@ -611,7 +622,7 @@ void buildBytecodeBlocks(IrFunction& function, const std::vector& jumpT } } -void analyzeBytecodeTypes(IrFunction& function) +void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks) { Proto* proto = function.proto; CODEGEN_ASSERT(proto); @@ -662,6 +673,8 @@ void analyzeBytecodeTypes(IrFunction& function) for (int i = proto->numparams; i < proto->maxstacksize; ++i) regTags[i] = LBC_TYPE_ANY; + LuauBytecodeType knownNextCallResult = LBC_TYPE_ANY; + for (int i = block.startpc; i <= block.finishpc;) { const Instruction* pc = &proto->code[i]; @@ -790,6 +803,9 @@ void analyzeBytecodeTypes(IrFunction& function) if (ch == 'x' || ch == 'y' || ch == 'z') regTags[ra] = LBC_TYPE_NUMBER; } + + if (FFlag::LuauCodegenAnalyzeHostVectorOps && regTags[ra] == LBC_TYPE_ANY && hostHooks.vectorAccessBytecodeType) + regTags[ra] = hostHooks.vectorAccessBytecodeType(field, str->len); } } else @@ -1161,6 +1177,34 @@ void analyzeBytecodeTypes(IrFunction& function) regTags[ra + 1] = bcType.a; bcType.result = LBC_TYPE_FUNCTION; + + if (FFlag::LuauCodegenAnalyzeHostVectorOps && bcType.a == LBC_TYPE_VECTOR && hostHooks.vectorNamecallBytecodeType) + { + TString* str = gco2ts(function.proto->k[kc].value.gc); + const char* field = getstr(str); + + knownNextCallResult = LuauBytecodeType(hostHooks.vectorNamecallBytecodeType(field, str->len)); + } + } + break; + } + case LOP_CALL: + { + if (FFlag::LuauCodegenAnalyzeHostVectorOps) + { + int ra = LUAU_INSN_A(*pc); + + if (knownNextCallResult != LBC_TYPE_ANY) + { + bcType.result = knownNextCallResult; + + knownNextCallResult = LBC_TYPE_ANY; + + regTags[ra] = bcType.result; + } + + if (FFlag::LuauCodegenTypeInfo) + refineRegType(bcTypeInfo, ra, i, bcType.result); } break; } @@ -1199,7 +1243,6 @@ void analyzeBytecodeTypes(IrFunction& function) } case LOP_GETGLOBAL: case LOP_SETGLOBAL: - case LOP_CALL: case LOP_RETURN: case LOP_JUMP: case LOP_JUMPBACK: diff --git a/luau/CodeGen/src/CodeGen.cpp b/luau/CodeGen/src/CodeGen.cpp index a5f6721..3938ab1 100644 --- a/luau/CodeGen/src/CodeGen.cpp +++ b/luau/CodeGen/src/CodeGen.cpp @@ -201,12 +201,12 @@ static void logPerfFunction(Proto* p, uintptr_t addr, unsigned size) } template -static std::optional createNativeFunction( - AssemblyBuilder& build, ModuleHelpers& helpers, Proto* proto, uint32_t& totalIrInstCount, CodeGenCompilationResult& result) +static std::optional createNativeFunction(AssemblyBuilder& build, ModuleHelpers& helpers, Proto* proto, uint32_t& totalIrInstCount, + const HostIrHooks& hooks, CodeGenCompilationResult& result) { CODEGEN_ASSERT(!FFlag::LuauCodegenContext); - IrBuilder ir; + IrBuilder ir(hooks); ir.buildFunctionIr(proto); unsigned instCount = unsigned(ir.function.instructions.size()); @@ -476,7 +476,7 @@ void setNativeExecutionEnabled(lua_State* L, bool enabled) } } -static CompilationResult compile_OLD(lua_State* L, int idx, unsigned int flags, CompilationStats* stats) +static CompilationResult compile_OLD(lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats) { CompilationResult compilationResult; @@ -485,7 +485,7 @@ static CompilationResult compile_OLD(lua_State* L, int idx, unsigned int flags, Proto* root = clvalue(func)->l.p; - if ((flags & CodeGen_OnlyNativeModules) != 0 && (root->flags & LPF_NATIVE_MODULE) == 0) + if ((options.flags & CodeGen_OnlyNativeModules) != 0 && (root->flags & LPF_NATIVE_MODULE) == 0) { compilationResult.result = CodeGenCompilationResult::NotNativeModule; return compilationResult; @@ -500,7 +500,7 @@ static CompilationResult compile_OLD(lua_State* L, int idx, unsigned int flags, } std::vector protos; - gatherFunctions(protos, root, flags); + gatherFunctions(protos, root, options.flags); // Skip protos that have been compiled during previous invocations of CodeGen::compile protos.erase(std::remove_if(protos.begin(), protos.end(), @@ -541,7 +541,7 @@ static CompilationResult compile_OLD(lua_State* L, int idx, unsigned int flags, { CodeGenCompilationResult protoResult = CodeGenCompilationResult::Success; - if (std::optional np = createNativeFunction(build, helpers, p, totalIrInstCount, protoResult)) + if (std::optional np = createNativeFunction(build, helpers, p, totalIrInstCount, options.hooks, protoResult)) results.push_back(*np); else compilationResult.protoFailures.push_back({protoResult, p->debugname ? getstr(p->debugname) : "", p->linedefined}); @@ -618,13 +618,15 @@ static CompilationResult compile_OLD(lua_State* L, int idx, unsigned int flags, CompilationResult compile(lua_State* L, int idx, unsigned int flags, CompilationStats* stats) { + Luau::CodeGen::CompilationOptions options{flags}; + if (FFlag::LuauCodegenContext) { - return compile_NEW(L, idx, flags, stats); + return compile_NEW(L, idx, options, stats); } else { - return compile_OLD(L, idx, flags, stats); + return compile_OLD(L, idx, options, stats); } } @@ -632,7 +634,27 @@ CompilationResult compile(const ModuleId& moduleId, lua_State* L, int idx, unsig { CODEGEN_ASSERT(FFlag::LuauCodegenContext); - return compile_NEW(moduleId, L, idx, flags, stats); + Luau::CodeGen::CompilationOptions options{flags}; + return compile_NEW(moduleId, L, idx, options, stats); +} + +CompilationResult compile(lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats) +{ + if (FFlag::LuauCodegenContext) + { + return compile_NEW(L, idx, options, stats); + } + else + { + return compile_OLD(L, idx, options, stats); + } +} + +CompilationResult compile(const ModuleId& moduleId, lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats) +{ + CODEGEN_ASSERT(FFlag::LuauCodegenContext); + + return compile_NEW(moduleId, L, idx, options, stats); } void setPerfLog(void* context, PerfLogFn logFn) diff --git a/luau/CodeGen/src/CodeGenAssembly.cpp b/luau/CodeGen/src/CodeGenAssembly.cpp index 8324b7c..e940242 100644 --- a/luau/CodeGen/src/CodeGenAssembly.cpp +++ b/luau/CodeGen/src/CodeGenAssembly.cpp @@ -183,11 +183,11 @@ static std::string getAssemblyImpl(AssemblyBuilder& build, const TValue* func, A { Proto* root = clvalue(func)->l.p; - if ((options.flags & CodeGen_OnlyNativeModules) != 0 && (root->flags & LPF_NATIVE_MODULE) == 0) + if ((options.compilationOptions.flags & CodeGen_OnlyNativeModules) != 0 && (root->flags & LPF_NATIVE_MODULE) == 0) return std::string(); std::vector protos; - gatherFunctions(protos, root, options.flags); + gatherFunctions(protos, root, options.compilationOptions.flags); protos.erase(std::remove_if(protos.begin(), protos.end(), [](Proto* p) { @@ -215,7 +215,7 @@ static std::string getAssemblyImpl(AssemblyBuilder& build, const TValue* func, A for (Proto* p : protos) { - IrBuilder ir; + IrBuilder ir(options.compilationOptions.hooks); ir.buildFunctionIr(p); unsigned asmSize = build.getCodeSize(); unsigned asmCount = build.getInstructionCount(); diff --git a/luau/CodeGen/src/CodeGenContext.cpp b/luau/CodeGen/src/CodeGenContext.cpp index d9e3c4b..cb54203 100644 --- a/luau/CodeGen/src/CodeGenContext.cpp +++ b/luau/CodeGen/src/CodeGenContext.cpp @@ -478,12 +478,12 @@ void create_NEW(lua_State* L, SharedCodeGenContext* codeGenContext) } template -[[nodiscard]] static NativeProtoExecDataPtr createNativeFunction( - AssemblyBuilder& build, ModuleHelpers& helpers, Proto* proto, uint32_t& totalIrInstCount, CodeGenCompilationResult& result) +[[nodiscard]] static NativeProtoExecDataPtr createNativeFunction(AssemblyBuilder& build, ModuleHelpers& helpers, Proto* proto, + uint32_t& totalIrInstCount, const HostIrHooks& hooks, CodeGenCompilationResult& result) { CODEGEN_ASSERT(FFlag::LuauCodegenContext); - IrBuilder ir; + IrBuilder ir(hooks); ir.buildFunctionIr(proto); unsigned instCount = unsigned(ir.function.instructions.size()); @@ -505,7 +505,7 @@ template } [[nodiscard]] static CompilationResult compileInternal( - const std::optional& moduleId, lua_State* L, int idx, unsigned int flags, CompilationStats* stats) + const std::optional& moduleId, lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats) { CODEGEN_ASSERT(FFlag::LuauCodegenContext); CODEGEN_ASSERT(lua_isLfunction(L, idx)); @@ -513,7 +513,7 @@ template Proto* root = clvalue(func)->l.p; - if ((flags & CodeGen_OnlyNativeModules) != 0 && (root->flags & LPF_NATIVE_MODULE) == 0) + if ((options.flags & CodeGen_OnlyNativeModules) != 0 && (root->flags & LPF_NATIVE_MODULE) == 0) return CompilationResult{CodeGenCompilationResult::NotNativeModule}; BaseCodeGenContext* codeGenContext = getCodeGenContext(L); @@ -521,7 +521,7 @@ template return CompilationResult{CodeGenCompilationResult::CodeGenNotInitialized}; std::vector protos; - gatherFunctions(protos, root, flags); + gatherFunctions(protos, root, options.flags); // Skip protos that have been compiled during previous invocations of CodeGen::compile protos.erase(std::remove_if(protos.begin(), protos.end(), @@ -572,7 +572,7 @@ template { CodeGenCompilationResult protoResult = CodeGenCompilationResult::Success; - NativeProtoExecDataPtr nativeExecData = createNativeFunction(build, helpers, protos[i], totalIrInstCount, protoResult); + NativeProtoExecDataPtr nativeExecData = createNativeFunction(build, helpers, protos[i], totalIrInstCount, options.hooks, protoResult); if (nativeExecData != nullptr) { nativeProtos.push_back(std::move(nativeExecData)); @@ -639,18 +639,18 @@ template return compilationResult; } -CompilationResult compile_NEW(const ModuleId& moduleId, lua_State* L, int idx, unsigned int flags, CompilationStats* stats) +CompilationResult compile_NEW(const ModuleId& moduleId, lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats) { CODEGEN_ASSERT(FFlag::LuauCodegenContext); - return compileInternal(moduleId, L, idx, flags, stats); + return compileInternal(moduleId, L, idx, options, stats); } -CompilationResult compile_NEW(lua_State* L, int idx, unsigned int flags, CompilationStats* stats) +CompilationResult compile_NEW(lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats) { CODEGEN_ASSERT(FFlag::LuauCodegenContext); - return compileInternal({}, L, idx, flags, stats); + return compileInternal({}, L, idx, options, stats); } [[nodiscard]] bool isNativeExecutionEnabled_NEW(lua_State* L) diff --git a/luau/CodeGen/src/CodeGenContext.h b/luau/CodeGen/src/CodeGenContext.h index ca338da..c47121b 100644 --- a/luau/CodeGen/src/CodeGenContext.h +++ b/luau/CodeGen/src/CodeGenContext.h @@ -107,8 +107,8 @@ void create_NEW(lua_State* L, size_t blockSize, size_t maxTotalSize, AllocationC // destroyed via lua_close. void create_NEW(lua_State* L, SharedCodeGenContext* codeGenContext); -CompilationResult compile_NEW(lua_State* L, int idx, unsigned int flags, CompilationStats* stats); -CompilationResult compile_NEW(const ModuleId& moduleId, lua_State* L, int idx, unsigned int flags, CompilationStats* stats); +CompilationResult compile_NEW(lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats); +CompilationResult compile_NEW(const ModuleId& moduleId, lua_State* L, int idx, const CompilationOptions& options, CompilationStats* stats); // Returns true if native execution is currently enabled for this VM [[nodiscard]] bool isNativeExecutionEnabled_NEW(lua_State* L); diff --git a/luau/CodeGen/src/IrBuilder.cpp b/luau/CodeGen/src/IrBuilder.cpp index 7d285aa..76d015e 100644 --- a/luau/CodeGen/src/IrBuilder.cpp +++ b/luau/CodeGen/src/IrBuilder.cpp @@ -15,6 +15,7 @@ LUAU_FASTFLAG(LuauLoadTypeInfo) // Because new VM typeinfo load changes the format used by Codegen, same flag is used LUAU_FASTFLAG(LuauTypeInfoLookupImprovement) +LUAU_FASTFLAG(LuauCodegenAnalyzeHostVectorOps) namespace Luau { @@ -23,8 +24,9 @@ namespace CodeGen constexpr unsigned kNoAssociatedBlockIndex = ~0u; -IrBuilder::IrBuilder() - : constantMap({IrConstKind::Tag, ~0ull}) +IrBuilder::IrBuilder(const HostIrHooks& hostHooks) + : hostHooks(hostHooks) + , constantMap({IrConstKind::Tag, ~0ull}) { } static bool hasTypedParameters_DEPRECATED(Proto* proto) @@ -230,7 +232,7 @@ void IrBuilder::buildFunctionIr(Proto* proto) rebuildBytecodeBasicBlocks(proto); // Infer register tags in bytecode - analyzeBytecodeTypes(function); + analyzeBytecodeTypes(function, hostHooks); function.bcMapping.resize(proto->sizecode, {~0u, ~0u}); @@ -283,10 +285,10 @@ void IrBuilder::buildFunctionIr(Proto* proto) translateInst(op, pc, i); - if (fastcallSkipTarget != -1) + if (cmdSkipTarget != -1) { - nexti = fastcallSkipTarget; - fastcallSkipTarget = -1; + nexti = cmdSkipTarget; + cmdSkipTarget = -1; } } @@ -613,7 +615,15 @@ void IrBuilder::translateInst(LuauOpcode op, const Instruction* pc, int i) translateInstCapture(*this, pc, i); break; case LOP_NAMECALL: - translateInstNamecall(*this, pc, i); + if (FFlag::LuauCodegenAnalyzeHostVectorOps) + { + if (translateInstNamecall(*this, pc, i)) + cmdSkipTarget = i + 3; + } + else + { + translateInstNamecall(*this, pc, i); + } break; case LOP_PREPVARARGS: inst(IrCmd::FALLBACK_PREPVARARGS, constUint(i), constInt(LUAU_INSN_A(*pc))); @@ -654,7 +664,7 @@ void IrBuilder::handleFastcallFallback(IrOp fallbackOrUndef, const Instruction* } else { - fastcallSkipTarget = i + skip + 2; + cmdSkipTarget = i + skip + 2; } } diff --git a/luau/CodeGen/src/IrTranslation.cpp b/luau/CodeGen/src/IrTranslation.cpp index 84e3b63..291f618 100644 --- a/luau/CodeGen/src/IrTranslation.cpp +++ b/luau/CodeGen/src/IrTranslation.cpp @@ -3,6 +3,7 @@ #include "Luau/Bytecode.h" #include "Luau/BytecodeUtils.h" +#include "Luau/CodeGen.h" #include "Luau/IrBuilder.h" #include "Luau/IrUtils.h" @@ -14,6 +15,7 @@ LUAU_FASTFLAGVARIABLE(LuauCodegenDirectUserdataFlow, false) LUAU_FASTFLAGVARIABLE(LuauCodegenFixVectorFields, false) +LUAU_FASTFLAG(LuauCodegenAnalyzeHostVectorOps) namespace Luau { @@ -1218,6 +1220,10 @@ void translateInstGetTableKS(IrBuilder& build, const Instruction* pc, int pcpos) } else { + if (FFlag::LuauCodegenAnalyzeHostVectorOps && build.hostHooks.vectorAccess && + build.hostHooks.vectorAccess(build, field, str->len, ra, rb, pcpos)) + return; + build.inst(IrCmd::FALLBACK_GETTABLEKS, build.constUint(pcpos), build.vmReg(ra), build.vmReg(rb), build.vmConst(aux)); } @@ -1376,7 +1382,7 @@ void translateInstCapture(IrBuilder& build, const Instruction* pc, int pcpos) } } -void translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos) +bool translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos) { int ra = LUAU_INSN_A(*pc); int rb = LUAU_INSN_B(*pc); @@ -1388,8 +1394,24 @@ void translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos) { build.loadAndCheckTag(build.vmReg(rb), LUA_TVECTOR, build.vmExit(pcpos)); + if (FFlag::LuauCodegenAnalyzeHostVectorOps && build.hostHooks.vectorNamecall) + { + Instruction call = pc[2]; + CODEGEN_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + + int callra = LUAU_INSN_A(call); + int nparams = LUAU_INSN_B(call) - 1; + int nresults = LUAU_INSN_C(call) - 1; + + TString* str = gco2ts(build.function.proto->k[aux].value.gc); + const char* field = getstr(str); + + if (build.hostHooks.vectorNamecall(build, field, str->len, callra, rb, nparams, nresults, pcpos)) + return true; + } + build.inst(IrCmd::FALLBACK_NAMECALL, build.constUint(pcpos), build.vmReg(ra), build.vmReg(rb), build.vmConst(aux)); - return; + return false; } if (FFlag::LuauCodegenDirectUserdataFlow && bcTypes.a == LBC_TYPE_USERDATA) @@ -1397,7 +1419,7 @@ void translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos) build.loadAndCheckTag(build.vmReg(rb), LUA_TUSERDATA, build.vmExit(pcpos)); build.inst(IrCmd::FALLBACK_NAMECALL, build.constUint(pcpos), build.vmReg(ra), build.vmReg(rb), build.vmConst(aux)); - return; + return false; } IrOp next = build.blockAtInst(pcpos + getOpLength(LOP_NAMECALL)); @@ -1451,6 +1473,8 @@ void translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos) build.inst(IrCmd::JUMP, next); build.beginBlock(next); + + return false; } void translateInstAndX(IrBuilder& build, const Instruction* pc, int pcpos, IrOp c) diff --git a/luau/CodeGen/src/IrTranslation.h b/luau/CodeGen/src/IrTranslation.h index b1f1e28..5eb0145 100644 --- a/luau/CodeGen/src/IrTranslation.h +++ b/luau/CodeGen/src/IrTranslation.h @@ -61,7 +61,7 @@ void translateInstGetGlobal(IrBuilder& build, const Instruction* pc, int pcpos); void translateInstSetGlobal(IrBuilder& build, const Instruction* pc, int pcpos); void translateInstConcat(IrBuilder& build, const Instruction* pc, int pcpos); void translateInstCapture(IrBuilder& build, const Instruction* pc, int pcpos); -void translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos); +bool translateInstNamecall(IrBuilder& build, const Instruction* pc, int pcpos); void translateInstAndX(IrBuilder& build, const Instruction* pc, int pcpos, IrOp c); void translateInstOrX(IrBuilder& build, const Instruction* pc, int pcpos, IrOp c); void translateInstNewClosure(IrBuilder& build, const Instruction* pc, int pcpos); diff --git a/luau/CodeGen/src/lcodegen.cpp b/luau/CodeGen/src/lcodegen.cpp index 0795cd4..1ad685a 100644 --- a/luau/CodeGen/src/lcodegen.cpp +++ b/luau/CodeGen/src/lcodegen.cpp @@ -17,5 +17,6 @@ void luau_codegen_create(lua_State* L) void luau_codegen_compile(lua_State* L, int idx) { - Luau::CodeGen::compile(L, idx); + Luau::CodeGen::CompilationOptions options; + Luau::CodeGen::compile(L, idx, options); }