Fix multiple string interps

This commit is contained in:
Kampfkarren 2022-07-26 15:44:51 -07:00
parent 24f61dfeb5
commit 7ace43e29f
2 changed files with 12 additions and 6 deletions

View file

@ -14,6 +14,7 @@
#include <algorithm> #include <algorithm>
#include <bitset> #include <bitset>
#include <memory>
#include <math.h> #include <math.h>
LUAU_FASTINTVARIABLE(LuauCompileLoopUnrollThreshold, 25) LUAU_FASTINTVARIABLE(LuauCompileLoopUnrollThreshold, 25)
@ -1495,14 +1496,21 @@ struct Compiler
formatString += "%s"; formatString += "%s";
} }
std::string& formatStringRef = interpFormatStrings.emplace_back(formatString); auto formatStringSize = formatString.size();
AstArray<char> formatStringArray{formatStringRef.data(), formatStringRef.size()}; // We can't use formatStringRef.data() directly, because short strings don't have their data
// pinned in memory, so when interpFormatStrings grows, these pointers will move and become invalid.
std::shared_ptr<char[]> formatStringPtr(new char[formatStringSize]);
memcpy(formatStringPtr.get(), formatString.data(), formatStringSize);
auto formatStringPtrRef = interpFormatStrings.emplace_back(formatStringPtr);
AstArray<char> formatStringArray{formatStringPtrRef.get(), formatStringSize};
int32_t formatStringIndex = bytecode.addConstantString(sref(formatStringArray)); int32_t formatStringIndex = bytecode.addConstantString(sref(formatStringArray));
if (formatStringIndex < 0) if (formatStringIndex < 0)
CompileError::raise(expr->location, "Exceeded constant limit; simplify the code to compile"); CompileError::raise(expr->location, "Exceeded constant limit; simplify the code to compile");
bytecode.emitABC(LOP_LOADK, target, formatStringIndex, 0); bytecode.emitABC(LOP_LOADK, target, formatStringIndex, 0);
// INTERP CODE REVIEW: Why do I need this? // INTERP CODE REVIEW: Why do I need this?
@ -1513,9 +1521,7 @@ struct Compiler
RegScope rs(this); RegScope rs(this);
for (AstExpr* expression : expr->expressions) for (AstExpr* expression : expr->expressions)
{
compileExprAuto(expression, rs); compileExprAuto(expression, rs);
}
BytecodeBuilder::StringRef formatMethod = sref(AstName("format")); BytecodeBuilder::StringRef formatMethod = sref(AstName("format"));
@ -3630,7 +3636,7 @@ struct Compiler
std::vector<Loop> loops; std::vector<Loop> loops;
std::vector<InlineFrame> inlineFrames; std::vector<InlineFrame> inlineFrames;
std::vector<Capture> captures; std::vector<Capture> captures;
std::vector<std::string> interpFormatStrings; std::vector<std::shared_ptr<char[]>> interpFormatStrings;
}; };
void compileOrThrow(BytecodeBuilder& bytecode, const ParseResult& parseResult, const AstNameTable& names, const CompileOptions& inputOptions) void compileOrThrow(BytecodeBuilder& bytecode, const ParseResult& parseResult, const AstNameTable& names, const CompileOptions& inputOptions)

View file

@ -9,7 +9,7 @@ end
assertEq(`hello {"world"}`, "hello world") assertEq(`hello {"world"}`, "hello world")
-- assertEq(`2 + 2 = {2 + 2}`, "2 + 2 = 4") assertEq(`2 + 2 = {2 + 2}`, "2 + 2 = 4")
-- assertEq(`{1} {2} {3} {4} {5} {6} {7}`, "1 2 3 4 5 6 7") -- assertEq(`{1} {2} {3} {4} {5} {6} {7}`, "1 2 3 4 5 6 7")