|
8 | 8 | #include <scratchcpp/stage.h> |
9 | 9 | #include <scratchcpp/iengine.h> |
10 | 10 | #include <scratchcpp/variable.h> |
| 11 | +#include <scratchcpp/list.h> |
11 | 12 |
|
12 | 13 | #include "llvmcodebuilder.h" |
13 | 14 | #include "llvmexecutablecode.h" |
@@ -56,12 +57,13 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize() |
56 | 57 | m_builder.setFastMathFlags(fmf); |
57 | 58 |
|
58 | 59 | // Create function |
59 | | - // void *f(Target *, ValueData **) |
| 60 | + // void *f(Target *, ValueData **, List **) |
60 | 61 | llvm::PointerType *pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0); |
61 | | - llvm::FunctionType *funcType = llvm::FunctionType::get(pointerType, { pointerType, pointerType }, false); |
| 62 | + llvm::FunctionType *funcType = llvm::FunctionType::get(pointerType, { pointerType, pointerType, pointerType }, false); |
62 | 63 | llvm::Function *func = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "f", m_module.get()); |
63 | 64 | llvm::Value *targetPtr = func->getArg(0); |
64 | 65 | llvm::Value *targetVariables = func->getArg(1); |
| 66 | + llvm::Value *targetLists = func->getArg(2); |
65 | 67 |
|
66 | 68 | llvm::BasicBlock *entry = llvm::BasicBlock::Create(m_ctx, "entry", func); |
67 | 69 | m_builder.SetInsertPoint(entry); |
@@ -92,6 +94,10 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize() |
92 | 94 | m_scopeVariables.clear(); |
93 | 95 | m_scopeVariables.push_back({}); |
94 | 96 |
|
| 97 | + // Create list pointers |
| 98 | + for (auto &[list, listPtr] : m_listPtrs) |
| 99 | + listPtr.ptr = getListPtr(targetLists, list); |
| 100 | + |
95 | 101 | // Execute recorded steps |
96 | 102 | for (const LLVMInstruction &step : m_instructions) { |
97 | 103 | switch (step.type) { |
@@ -1315,6 +1321,22 @@ llvm::Value *LLVMCodeBuilder::getVariablePtr(llvm::Value *targetVariables, Varia |
1315 | 1321 | return m_builder.CreateIntToPtr(addr, m_valueDataType->getPointerTo()); |
1316 | 1322 | } |
1317 | 1323 |
|
| 1324 | +llvm::Value *LLVMCodeBuilder::getListPtr(llvm::Value *targetLists, List *list) |
| 1325 | +{ |
| 1326 | + if (!m_target->isStage() && list->target() == m_target) { |
| 1327 | + // If this is a local sprite list, use the list array at runtime (for clones) |
| 1328 | + assert(m_targetListMap.find(list) != m_targetListMap.cend()); |
| 1329 | + const size_t index = m_targetListMap[list]; |
| 1330 | + auto pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0); |
| 1331 | + llvm::Value *ptr = m_builder.CreateGEP(pointerType, targetLists, m_builder.getInt64(index)); |
| 1332 | + return m_builder.CreateLoad(pointerType, ptr); |
| 1333 | + } |
| 1334 | + |
| 1335 | + // Otherwise create a raw pointer at compile time |
| 1336 | + llvm::Value *addr = m_builder.getInt64((uintptr_t)list); |
| 1337 | + return m_builder.CreateIntToPtr(addr, m_valueDataType->getPointerTo()); |
| 1338 | +} |
| 1339 | + |
1318 | 1340 | void LLVMCodeBuilder::syncVariables(llvm::Value *targetVariables) |
1319 | 1341 | { |
1320 | 1342 | // Copy stack variables to the actual variables |
|
0 commit comments