Skip to content

Commit 8fa9790

Browse files
committed
Add LLVMInstructionList class
1 parent deda3a7 commit 8fa9790

File tree

6 files changed

+252
-0
lines changed

6 files changed

+252
-0
lines changed

src/engine/internal/llvm/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ target_sources(scratchcpp
55
llvmregister.h
66
llvmconstantregister.h
77
llvminstruction.h
8+
llvminstructionlist.cpp
9+
llvminstructionlist.h
810
llvmifstatement.h
911
llvmloop.h
1012
llvmcoroutine.cpp

src/engine/internal/llvm/llvminstruction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ struct LLVMInstruction
100100
size_t procedureArgIndex = 0;
101101
LLVMLoopScope *loopScope = nullptr;
102102
bool loopCondition = false; // whether the instruction is part of a loop condition
103+
104+
// Linked list
105+
LLVMInstruction *previous = nullptr;
106+
LLVMInstruction *next = nullptr;
103107
};
104108

105109
} // namespace libscratchcpp
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include <cassert>
4+
5+
#include "llvminstructionlist.h"
6+
#include "llvminstruction.h"
7+
8+
using namespace libscratchcpp;
9+
10+
LLVMInstruction *LLVMInstructionList::first()
11+
{
12+
return m_first.get();
13+
}
14+
15+
LLVMInstruction *LLVMInstructionList::last()
16+
{
17+
return m_last.get();
18+
}
19+
20+
void LLVMInstructionList::addInstruction(std::shared_ptr<LLVMInstruction> ins)
21+
{
22+
if (!(m_first && m_last)) {
23+
assert(!m_first && !m_last);
24+
25+
m_first = ins;
26+
m_last = ins;
27+
28+
ins->previous = nullptr;
29+
ins->next = nullptr;
30+
} else {
31+
m_last->next = ins.get();
32+
ins->previous = m_last.get();
33+
m_last = ins;
34+
}
35+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <memory>
6+
7+
namespace libscratchcpp
8+
{
9+
10+
struct LLVMInstruction;
11+
12+
class LLVMInstructionList
13+
{
14+
public:
15+
LLVMInstructionList() = default;
16+
LLVMInstructionList(const LLVMInstructionList &) = delete;
17+
18+
LLVMInstruction *first();
19+
LLVMInstruction *last();
20+
21+
void addInstruction(std::shared_ptr<LLVMInstruction> ins);
22+
23+
private:
24+
std::shared_ptr<LLVMInstruction> m_first;
25+
std::shared_ptr<LLVMInstruction> m_last;
26+
};
27+
28+
} // namespace libscratchcpp

test/llvm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ add_executable(
1919
llvmexecutioncontext_test.cpp
2020
llvmexecutablecode_test.cpp
2121
llvmcodebuilder_test.cpp
22+
llvminstructionlist_test.cpp
2223
)
2324

2425
target_link_libraries(
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#include <scratchcpp/thread.h>
2+
#include <engine/internal/llvm/llvminstructionlist.h>
3+
#include <engine/internal/llvm/llvminstruction.h>
4+
#include <gtest/gtest.h>
5+
6+
using namespace libscratchcpp;
7+
8+
TEST(LLVMInstructionListTest, EmptyList_First)
9+
{
10+
LLVMInstructionList list;
11+
ASSERT_EQ(list.first(), nullptr);
12+
}
13+
14+
TEST(LLVMInstructionListTest, EmptyList_Last)
15+
{
16+
LLVMInstructionList list;
17+
ASSERT_EQ(list.last(), nullptr);
18+
}
19+
20+
TEST(LLVMInstructionListTest, AddSingleInstruction_First)
21+
{
22+
LLVMInstructionList list;
23+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
24+
list.addInstruction(ins);
25+
26+
ASSERT_EQ(list.first(), ins.get());
27+
}
28+
29+
TEST(LLVMInstructionListTest, AddSingleInstruction_Last)
30+
{
31+
LLVMInstructionList list;
32+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
33+
list.addInstruction(ins);
34+
35+
ASSERT_EQ(list.last(), ins.get());
36+
}
37+
38+
TEST(LLVMInstructionListTest, AddSingleInstruction_Previous)
39+
{
40+
LLVMInstructionList list;
41+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
42+
list.addInstruction(ins);
43+
44+
ASSERT_EQ(ins->previous, nullptr);
45+
}
46+
47+
TEST(LLVMInstructionListTest, AddSingleInstruction_Next)
48+
{
49+
LLVMInstructionList list;
50+
auto ins = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
51+
list.addInstruction(ins);
52+
53+
ASSERT_EQ(ins->next, nullptr);
54+
}
55+
56+
TEST(LLVMInstructionListTest, AddMultipleInstructions_First)
57+
{
58+
LLVMInstructionList list;
59+
60+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
61+
list.addInstruction(ins1);
62+
63+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
64+
list.addInstruction(ins2);
65+
66+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
67+
list.addInstruction(ins3);
68+
69+
ASSERT_EQ(list.first(), ins1.get());
70+
}
71+
72+
TEST(LLVMInstructionListTest, AddMultipleInstructions_Last)
73+
{
74+
LLVMInstructionList list;
75+
76+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
77+
list.addInstruction(ins1);
78+
79+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
80+
list.addInstruction(ins2);
81+
82+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
83+
list.addInstruction(ins3);
84+
85+
ASSERT_EQ(list.last(), ins3.get());
86+
}
87+
88+
TEST(LLVMInstructionListTest, AddMultipleInstructions_PreviousOfFirst)
89+
{
90+
LLVMInstructionList list;
91+
92+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
93+
list.addInstruction(ins1);
94+
95+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
96+
list.addInstruction(ins2);
97+
98+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
99+
list.addInstruction(ins3);
100+
101+
ASSERT_EQ(ins1->previous, nullptr);
102+
}
103+
104+
TEST(LLVMInstructionListTest, AddMultipleInstructions_NextOfFirst)
105+
{
106+
LLVMInstructionList list;
107+
108+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
109+
list.addInstruction(ins1);
110+
111+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
112+
list.addInstruction(ins2);
113+
114+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
115+
list.addInstruction(ins3);
116+
117+
ASSERT_EQ(ins1->next, ins2.get());
118+
}
119+
120+
TEST(LLVMInstructionListTest, AddMultipleInstructions_PreviousOfMiddle)
121+
{
122+
LLVMInstructionList list;
123+
124+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
125+
list.addInstruction(ins1);
126+
127+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
128+
list.addInstruction(ins2);
129+
130+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
131+
list.addInstruction(ins3);
132+
133+
ASSERT_EQ(ins2->previous, ins1.get());
134+
}
135+
136+
TEST(LLVMInstructionListTest, AddMultipleInstructions_NextOfMiddle)
137+
{
138+
LLVMInstructionList list;
139+
140+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
141+
list.addInstruction(ins1);
142+
143+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
144+
list.addInstruction(ins2);
145+
146+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
147+
list.addInstruction(ins3);
148+
149+
ASSERT_EQ(ins2->next, ins3.get());
150+
}
151+
152+
TEST(LLVMInstructionListTest, AddMultipleInstructions_PreviousOfLast)
153+
{
154+
LLVMInstructionList list;
155+
156+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
157+
list.addInstruction(ins1);
158+
159+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
160+
list.addInstruction(ins2);
161+
162+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
163+
list.addInstruction(ins3);
164+
165+
ASSERT_EQ(ins3->previous, ins2.get());
166+
}
167+
168+
TEST(LLVMInstructionListTest, AddMultipleInstructions_NextOfLast)
169+
{
170+
LLVMInstructionList list;
171+
172+
auto ins1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
173+
list.addInstruction(ins1);
174+
175+
auto ins2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
176+
list.addInstruction(ins2);
177+
178+
auto ins3 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::FunctionCall, nullptr, false);
179+
list.addInstruction(ins3);
180+
181+
ASSERT_EQ(ins3->next, nullptr);
182+
}

0 commit comments

Comments
 (0)