1
1
#include < scratchcpp/project.h>
2
- #include < scratchcpp/target.h>
2
+ #include < scratchcpp/sprite.h>
3
+ #include < scratchcpp/costume.h>
4
+ #include < scratchcpp/sound.h>
5
+ #include < scratchcpp/iengine.h>
3
6
#include < scratchcpp/list.h>
4
7
#include < engine/internal/llvm/llvmcodeanalyzer.h>
5
8
#include < engine/internal/llvm/llvmcompilercontext.h>
@@ -18,17 +21,33 @@ class LLVMCodeAnalyzer_ListTypeAnalysis : public testing::Test
18
21
void SetUp () override
19
22
{
20
23
auto engine = m_project.engine ();
21
- m_ctx = std::make_unique<LLVMCompilerContext>(engine.get (), &m_target);
24
+ m_target = std::make_shared<Target>();
25
+ m_spriteWithUnsafeConstants = std::make_shared<Sprite>();
26
+
27
+ auto costume = std::make_shared<Costume>(m_unsafeCostumeNumConstant, " " , " " );
28
+ m_spriteWithUnsafeConstants->addCostume (costume);
29
+
30
+ auto sound = std::make_shared<Sound>(m_unsafeSoundNumConstant, " " , " " );
31
+ m_spriteWithUnsafeConstants->addSound (sound);
32
+
33
+ engine->setTargets ({ m_target, m_spriteWithUnsafeConstants });
34
+
35
+ m_ctx = std::make_unique<LLVMCompilerContext>(engine.get (), m_target.get ());
22
36
m_builder = std::make_unique<llvm::IRBuilder<>>(*m_ctx->llvmCtx ());
23
37
m_utils = std::make_unique<LLVMBuildUtils>(m_ctx.get (), *m_builder, Compiler::CodeType::Script);
24
38
m_analyzer = std::make_unique<LLVMCodeAnalyzer>(*m_utils);
25
39
}
26
40
27
41
std::unique_ptr<LLVMCodeAnalyzer> m_analyzer;
28
42
43
+ const std::string m_safeNumConstant = " 3.14" ;
44
+ const std::string m_unsafeCostumeNumConstant = " 12" ;
45
+ const std::string m_unsafeSoundNumConstant = " -27.672" ;
46
+
29
47
private:
30
48
Project m_project;
31
- Target m_target;
49
+ std::shared_ptr<Target> m_target;
50
+ std::shared_ptr<Sprite> m_spriteWithUnsafeConstants;
32
51
std::unique_ptr<LLVMCompilerContext> m_ctx;
33
52
std::unique_ptr<llvm::IRBuilder<>> m_builder;
34
53
std::unique_ptr<LLVMBuildUtils> m_utils;
@@ -155,7 +174,7 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear)
155
174
list.addInstruction (clearList);
156
175
157
176
auto appendList1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::AppendToList, false );
158
- LLVMConstantRegister value1 (Compiler::StaticType::String, " 3.14 " );
177
+ LLVMConstantRegister value1 (Compiler::StaticType::String, m_safeNumConstant );
159
178
appendList1->targetList = &targetList;
160
179
appendList1->args .push_back ({ Compiler::StaticType::Unknown, &value1 });
161
180
list.addInstruction (appendList1);
@@ -170,7 +189,7 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear)
170
189
171
190
ASSERT_EQ (appendList1->targetType , Compiler::StaticType::Void);
172
191
173
- // String "3.14" optimized to Number, so second write sees Number type
192
+ // String gets optimized to Number, so second write sees Number type
174
193
ASSERT_EQ (appendList2->targetType , Compiler::StaticType::Number);
175
194
}
176
195
@@ -203,6 +222,64 @@ TEST_F(LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_Differen
203
222
ASSERT_EQ (appendList2->targetType , Compiler::StaticType::String);
204
223
}
205
224
225
+ TEST_F (LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeCostumeConstant)
226
+ {
227
+ LLVMInstructionList list;
228
+ List targetList (" " , " " );
229
+
230
+ auto clearList = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::ClearList, false );
231
+ clearList->targetList = &targetList;
232
+ list.addInstruction (clearList);
233
+
234
+ auto appendList1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::AppendToList, false );
235
+ LLVMConstantRegister value1 (Compiler::StaticType::String, m_unsafeCostumeNumConstant);
236
+ appendList1->targetList = &targetList;
237
+ appendList1->args .push_back ({ Compiler::StaticType::Unknown, &value1 });
238
+ list.addInstruction (appendList1);
239
+
240
+ auto appendList2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::AppendToList, false );
241
+ LLVMConstantRegister value2 (Compiler::StaticType::Bool, true );
242
+ appendList2->targetList = &targetList;
243
+ appendList2->args .push_back ({ Compiler::StaticType::Unknown, &value2 });
244
+ list.addInstruction (appendList2);
245
+
246
+ m_analyzer->analyzeScript (list);
247
+
248
+ ASSERT_EQ (appendList1->targetType , Compiler::StaticType::Void);
249
+
250
+ // String does NOT get optimized to Number because there's a costume with the same name
251
+ ASSERT_EQ (appendList2->targetType , Compiler::StaticType::String);
252
+ }
253
+
254
+ TEST_F (LLVMCodeAnalyzer_ListTypeAnalysis, StringOptimization_AfterClear_UnsafeSoundConstant)
255
+ {
256
+ LLVMInstructionList list;
257
+ List targetList (" " , " " );
258
+
259
+ auto clearList = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::ClearList, false );
260
+ clearList->targetList = &targetList;
261
+ list.addInstruction (clearList);
262
+
263
+ auto appendList1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::AppendToList, false );
264
+ LLVMConstantRegister value1 (Compiler::StaticType::String, m_unsafeSoundNumConstant);
265
+ appendList1->targetList = &targetList;
266
+ appendList1->args .push_back ({ Compiler::StaticType::Unknown, &value1 });
267
+ list.addInstruction (appendList1);
268
+
269
+ auto appendList2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::AppendToList, false );
270
+ LLVMConstantRegister value2 (Compiler::StaticType::Bool, true );
271
+ appendList2->targetList = &targetList;
272
+ appendList2->args .push_back ({ Compiler::StaticType::Unknown, &value2 });
273
+ list.addInstruction (appendList2);
274
+
275
+ m_analyzer->analyzeScript (list);
276
+
277
+ ASSERT_EQ (appendList1->targetType , Compiler::StaticType::Void);
278
+
279
+ // String does NOT get optimized to Number because there's a sound with the same name
280
+ ASSERT_EQ (appendList2->targetType , Compiler::StaticType::String);
281
+ }
282
+
206
283
TEST_F (LLVMCodeAnalyzer_ListTypeAnalysis, ClearListOperation)
207
284
{
208
285
LLVMInstructionList list;
0 commit comments