Skip to content

Commit

Permalink
Slice constructor taking a size will default-init all its members upf…
Browse files Browse the repository at this point in the history
…ront
  • Loading branch information
rymiel committed Jun 27, 2022
1 parent e798c49 commit 8891c4c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
14 changes: 3 additions & 11 deletions example/bf.ym
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ def parse(input U8[]) Instruction[]
# This should be dynamically sized...
let stack = I32[](512)
let stack_i = 0
# TODO
# This could be simplified if i had better iteration, i.e. something akin
# to a for-each loop
while i < input.size
let chr = input[i]
let instruction = Instruction(0, 0)
Expand Down Expand Up @@ -58,17 +61,6 @@ def main(argc I32, argv U8 ptr ptr) I32
let ptr I32 = 0
let memory = U8[](65535)

# TODO
# This could be simplified if i had better iteration, i.e. something akin
# to a for-each loop
let i I32 = 0
# TODO
# There should be an easier way to zero-fill a slice
while i < memory.size
memory[i] = ?\0
i = i + 1
end

while pc < instructions.size
let instr = instructions[pc]
if instr::type == 1
Expand Down
35 changes: 32 additions & 3 deletions src/compiler/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,8 @@ template <> auto Compiler::expression(const ast::CtorExpr& expr, bool mut) -> Va
auto slice_size = body_expression(slice_size_expr);

auto* llvm_slice_type = llvm_type(*slice_type);
auto* base_type = llvm_type(*slice_type->ptr_base()); // ???
const auto& base_ty_type = *slice_type->ptr_base(); // ???
auto* base_type = llvm_type(base_ty_type);

//// Stack allocation
// if (auto* const_value = dyn_cast<llvm::ConstantInt>(slice_size.llvm())) {
Expand Down Expand Up @@ -659,12 +660,40 @@ template <> auto Compiler::expression(const ast::CtorExpr& expr, bool mut) -> Va
// TODO: the above `malloc` is literally never `free`d because the language doesn't yet have destructors.

auto* data_ptr = m_builder->Insert(array_alloc);
auto* data_size = m_builder->CreateSExtOrBitCast(slice_size, m_builder->getInt64Ty());
llvm::Value* slice_inst = llvm::UndefValue::get(llvm_slice_type);
slice_inst = m_builder->CreateInsertValue(slice_inst, data_ptr, 0);
slice_inst = m_builder->CreateInsertValue(slice_inst,
m_builder->CreateSExtOrBitCast(slice_size, m_builder->getInt64Ty()), 1);
slice_inst = m_builder->CreateInsertValue(slice_inst, data_size, 1);
slice_inst->setName("sl.ctor.inst");

auto* current_block = m_builder->GetInsertBlock();
m_builder->SetInsertPoint(m_current_fn->m_decl_bb);
auto* iter_alloc = m_builder->CreateAlloca(m_builder->getInt64Ty(), nullptr, "sl.ctor.definit.iter");
m_builder->SetInsertPoint(current_block);
m_builder->CreateStore(m_builder->getInt64(0), iter_alloc);

auto* iter_test = BasicBlock::Create(*m_context, "sl.ctor.definit.test", *m_current_fn);
auto* iter_body = BasicBlock::Create(*m_context, "sl.ctor.definit.head", *m_current_fn);
auto* iter_merge = BasicBlock::Create(*m_context, "sl.ctor.definit.merge", *m_current_fn);

m_builder->CreateBr(iter_test);
m_builder->SetInsertPoint(iter_test);

auto* iter_less = m_builder->CreateICmpSLT(m_builder->CreateLoad(m_builder->getInt64Ty(), iter_alloc), data_size,
"sl.ctor.definit.cmp");
m_builder->CreateCondBr(iter_less, iter_body, iter_merge);

m_builder->SetInsertPoint(iter_body);
auto* iter_next_addr = m_builder->CreateInBoundsGEP(
base_type, data_ptr, m_builder->CreateLoad(m_builder->getInt64Ty(), iter_alloc), "sl.ctor.definit.gep");
m_builder->CreateStore(default_init(base_ty_type), iter_next_addr);
m_builder->CreateStore(
m_builder->CreateAdd(m_builder->CreateLoad(m_builder->getInt64Ty(), iter_alloc), m_builder->getInt64(1)),
iter_alloc);
m_builder->CreateBr(iter_test);

m_builder->SetInsertPoint(iter_merge);

return slice_inst;
}

Expand Down

0 comments on commit 8891c4c

Please sign in to comment.