Skip to content

Commit a775a5b

Browse files
committed
LLVMCodeBuilder: Add string length instruction
1 parent a7bf600 commit a775a5b

File tree

6 files changed

+35
-1
lines changed

6 files changed

+35
-1
lines changed

src/engine/internal/icodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ICodeBuilder
2525
virtual CompilerValue *addFunctionCallWithCtx(const std::string &functionName, Compiler::StaticType returnType, const Compiler::ArgTypes &argTypes, const Compiler::Args &args) = 0;
2626
virtual CompilerConstant *addConstValue(const Value &value) = 0;
2727
virtual CompilerValue *addStringChar(CompilerValue *string, CompilerValue *index) = 0;
28+
virtual CompilerValue *addStringLength(CompilerValue *string) = 0;
2829
virtual CompilerValue *addLoopIndex() = 0;
2930
virtual CompilerValue *addLocalVariableValue(CompilerLocalVariable *variable) = 0;
3031
virtual CompilerValue *addVariableValue(Variable *variable) = 0;

src/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,16 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
629629
break;
630630
}
631631

632+
case LLVMInstruction::Type::StringLength: {
633+
assert(step.args.size() == 1);
634+
const auto &arg = step.args[0];
635+
llvm::Value *str = castValue(arg.second, arg.first);
636+
llvm::Value *sizeField = m_builder.CreateStructGEP(m_stringPtrType, str, 1);
637+
llvm::Value *size = m_builder.CreateLoad(m_builder.getInt64Ty(), sizeField);
638+
step.functionReturnReg->value = m_builder.CreateSIToFP(size, m_builder.getDoubleTy());
639+
break;
640+
}
641+
632642
case LLVMInstruction::Type::Select: {
633643
assert(step.args.size() == 3);
634644
const auto &arg1 = step.args[0];
@@ -1379,6 +1389,11 @@ CompilerValue *LLVMCodeBuilder::addStringChar(CompilerValue *string, CompilerVal
13791389
return createOp(LLVMInstruction::Type::StringChar, Compiler::StaticType::String, { Compiler::StaticType::String, Compiler::StaticType::Number }, { string, index });
13801390
}
13811391

1392+
CompilerValue *LLVMCodeBuilder::addStringLength(CompilerValue *string)
1393+
{
1394+
return createOp(LLVMInstruction::Type::StringLength, Compiler::StaticType::Number, Compiler::StaticType::String, { string });
1395+
}
1396+
13821397
CompilerValue *LLVMCodeBuilder::addLoopIndex()
13831398
{
13841399
return createOp(LLVMInstruction::Type::LoopIndex, Compiler::StaticType::Number, {}, {});

src/engine/internal/llvm/llvmcodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class LLVMCodeBuilder : public ICodeBuilder
3434
CompilerValue *addFunctionCallWithCtx(const std::string &functionName, Compiler::StaticType returnType, const Compiler::ArgTypes &argTypes, const Compiler::Args &args) override;
3535
CompilerConstant *addConstValue(const Value &value) override;
3636
CompilerValue *addStringChar(CompilerValue *string, CompilerValue *index) override;
37+
CompilerValue *addStringLength(CompilerValue *string) override;
3738
CompilerValue *addLoopIndex() override;
3839
CompilerValue *addLocalVariableValue(CompilerLocalVariable *variable) override;
3940
CompilerValue *addVariableValue(Variable *variable) override;

src/engine/internal/llvm/llvminstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ struct LLVMInstruction
4949
Exp10,
5050
StringConcat,
5151
StringChar,
52+
StringLength,
5253
Select,
5354
CreateLocalVariable,
5455
WriteLocalVariable,

test/llvm/llvmcodebuilder_test.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ class LLVMCodeBuilderTest : public testing::Test
5858
Exp,
5959
Exp10,
6060
StringConcat,
61-
StringChar
61+
StringChar,
62+
StringLength
6263
};
6364

6465
void SetUp() override
@@ -209,6 +210,9 @@ class LLVMCodeBuilderTest : public testing::Test
209210
case OpType::Exp10:
210211
return m_builder->createExp10(arg);
211212

213+
case OpType::StringLength:
214+
return m_builder->addStringLength(arg);
215+
212216
default:
213217
EXPECT_TRUE(false);
214218
return nullptr;
@@ -309,6 +313,9 @@ class LLVMCodeBuilderTest : public testing::Test
309313
case OpType::Not:
310314
return !v.toBool();
311315

316+
case OpType::StringLength:
317+
return v.toUtf16().size();
318+
312319
default:
313320
EXPECT_TRUE(false);
314321
return Value();
@@ -1757,6 +1764,14 @@ TEST_F(LLVMCodeBuilderTest, StringChar)
17571764
runOpTest(OpType::StringChar, "ábč", 0);
17581765
}
17591766

1767+
TEST_F(LLVMCodeBuilderTest, StringLength)
1768+
{
1769+
runUnaryNumOpTest(OpType::StringLength, "Hello world", 11);
1770+
runUnaryNumOpTest(OpType::StringLength, "abc", 3);
1771+
runUnaryNumOpTest(OpType::StringLength, "abcdef", 6);
1772+
runUnaryNumOpTest(OpType::StringLength, "ábč", 3);
1773+
}
1774+
17601775
TEST_F(LLVMCodeBuilderTest, LocalVariables)
17611776
{
17621777
Stage stage;

test/mocks/codebuildermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class CodeBuilderMock : public ICodeBuilder
1414
MOCK_METHOD(CompilerValue *, addFunctionCallWithCtx, (const std::string &, Compiler::StaticType, const Compiler::ArgTypes &, const Compiler::Args &), (override));
1515
MOCK_METHOD(CompilerConstant *, addConstValue, (const Value &), (override));
1616
MOCK_METHOD(CompilerValue *, addStringChar, (CompilerValue *, CompilerValue *), (override));
17+
MOCK_METHOD(CompilerValue *, addStringLength, (CompilerValue *), (override));
1718
MOCK_METHOD(CompilerValue *, addLoopIndex, (), (override));
1819
MOCK_METHOD(CompilerValue *, addLocalVariableValue, (CompilerLocalVariable *), (override));
1920
MOCK_METHOD(CompilerValue *, addVariableValue, (Variable *), (override));

0 commit comments

Comments
 (0)