static void BasicBlock_WriteByteCode(KonohaContext *kctx, bblock_t blockId, ByteCodeWriter *writer) { BasicBlock *bb = BasicBlock_FindById(kctx, blockId); while(bb != NULL && bb->codeoffset == -1) { intptr_t len = bb->size - sizeof(BasicBlock); bb->codeoffset = CodeOffset(writer); bb->lastoffset = -1; // reset lastoffset if(len > 0) { bblock_t id = BasicBlock_id(kctx, bb); WriteByteCode(writer, ((char *)bb) + sizeof(BasicBlock), len); bb = BasicBlock_FindById(kctx, id); // recheck bb->lastoffset = CodeOffset(writer) - sizeof(KVirtualCode); DBG_ASSERT(bb->codeoffset + ((len / sizeof(KVirtualCode)) - 1) * sizeof(KVirtualCode) == (size_t) bb->lastoffset); } else { DBG_ASSERT(bb->branchid == -1); } bb = BasicBlock_FindById(kctx, bb->nextid); } bb = BasicBlock_FindById(kctx, blockId); while(bb != NULL) { if(bb->branchid != -1) { BasicBlock *bbJ = BasicBlock_FindById(kctx, bb->branchid); if(bbJ->codeoffset == -1) { BasicBlock_WriteByteCode(kctx, bb->branchid, writer); } } bb = BasicBlock_FindById(kctx, bb->nextid); } }
static BasicBlock *new_BasicBlock(KonohaContext *kctx, size_t max, bblock_t oldId) { BasicBlock *bb; KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); bb = (BasicBlock *)KLIB KBuffer_Alloca(kctx, &wb, max); if(oldId != -1) { BasicBlock *oldbb = BasicBlock_FindById(kctx, oldId); if(((char *)oldbb) + oldbb->max == (char *)bb) { oldbb->max += (max - sizeof(BasicBlock)); wb.m->bytesize -= sizeof(BasicBlock); return oldbb; } memcpy(bb, oldbb, oldbb->size); oldbb->newid = BasicBlock_id(kctx, bb); oldbb->size = 0; } else { bb->size = sizeof(BasicBlock); bb->newid = -1; bb->nextid = -1; bb->branchid = -1; } bb->max = max; bb->codeoffset = -1; bb->lastoffset = -1; return bb; }
static void BasicBlock_WriteBuffer(KonohaContext *kctx, bblock_t blockId, KBuffer *wb) { BasicBlock *bb = BasicBlock_FindById(kctx, blockId); while(bb != NULL && bb->codeoffset == -1) { size_t len = bb->size - sizeof(BasicBlock); bb->codeoffset = CodeOffset(wb); if(bb->nextid == bb->branchid && bb->nextid != -1) { bb->branchid = -1; len -= sizeof(KVirtualCode); // remove unnecesarry jump .. } if(len > 0) { bblock_t id = BasicBlock_id(kctx, bb); char buf[len]; // bb is growing together with wb. memcpy(buf, ((char *)bb) + sizeof(BasicBlock), len); KLIB KBuffer_Write(kctx, wb, buf, len); bb = BasicBlock_FindById(kctx, id); // recheck bb->lastoffset = CodeOffset(wb) - sizeof(KVirtualCode); DBG_ASSERT(bb->codeoffset + ((len / sizeof(KVirtualCode)) - 1) * sizeof(KVirtualCode) == bb->lastoffset); } else { DBG_ASSERT(bb->branchid == -1); } bb = BasicBlock_FindById(kctx, bb->nextid); } bb = BasicBlock_FindById(kctx, blockId); while(bb != NULL) { if(bb->branchid != -1 /*&& bb->branchid != builder->bbReturnId*/) { BasicBlock *bbJ = BasicBlock_FindById(kctx, bb->branchid); if(bbJ->codeoffset == -1) { BasicBlock_WriteBuffer(kctx, bb->branchid, wb); } } bb = BasicBlock_FindById(kctx, bb->nextid); } }
static void MiniVMBuilder_setBlock(KonohaContext *kctx, KBuilder *builder, bblock_t labelId) { BasicBlock *labelNode; BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId); DBG_ASSERT(bb != NULL); labelNode = BasicBlock_FindById(kctx, labelId); labelNode->incoming += 1; builder->bbMainId = BasicBlock_id(kctx, labelNode); }
static void ASM_LABEL(KonohaContext *kctx, KBuilder *builder, bblock_t labelId) { BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId); DBG_ASSERT(bb != NULL); DBG_ASSERT(bb->nextid == -1); BasicBlock *labelNode = BasicBlock_FindById(kctx, labelId); labelNode->incoming += 1; builder->bbMainId = BasicBlock_id(kctx, labelNode); bb->nextid = builder->bbMainId; }
static void MiniVMBuilder_JumpTo(KonohaContext *kctx, KBuilder *builder, bblock_t labelId) { BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId); DBG_ASSERT(bb != NULL); //DBG_ASSERT(bb->nextid == -1); if(bb->branchid == -1) { BasicBlock *labelNode; ASM(JMP, NULL); labelNode = BasicBlock_FindById(kctx, labelId); bb = BasicBlock_FindById(kctx, builder->bbMainId); bb->branchid = BasicBlock_id(kctx, labelNode); labelNode->incoming += 1; } }
static bblock_t BasicBlock_Add(KonohaContext *kctx, bblock_t blockId, kfileline_t uline, KVirtualCode *op, size_t size, size_t padding_size) { BasicBlock *bb = BasicBlock_FindById(kctx, blockId); DBG_ASSERT(bb->newid == -1); DBG_ASSERT(size <= padding_size); DBG_ASSERT(bb->nextid == -1 && bb->branchid == -1); if(!(bb->size + size < bb->max)) { size_t newsize = newsize2(bb->max); bb = new_BasicBlock(kctx, newsize, blockId); } memcpy(((char *)bb) + bb->size, op, size); bb->size += padding_size; return BasicBlock_id(kctx, bb); }
static bblock_t AsmJMPF(KonohaContext *kctx, KBuilder *builder, int localStack, bblock_t jumpId) { BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId); DBG_ASSERT(bb != NULL); DBG_ASSERT(bb->nextid == -1 && bb->branchid == -1); bblock_t nextId = new_BasicBlockLABEL(kctx); ASM(JMPF, NULL, NC_(localStack)); bb = BasicBlock_FindById(kctx, builder->bbMainId); BasicBlock *jumpBlock = BasicBlock_FindById(kctx, jumpId); BasicBlock *nextBlock = BasicBlock_FindById(kctx, nextId); bb->branchid = BasicBlock_id(kctx, jumpBlock); bb->nextid = nextId; nextBlock->incoming += 1; jumpBlock->incoming += 1; builder->bbMainId = nextId; return nextId; }
static bblock_t new_BasicBlockLABEL(KonohaContext *kctx) { BasicBlock *bb = new_BasicBlock(kctx, sizeof(KVirtualCode) * 2 + sizeof(BasicBlock), -1); return BasicBlock_id(kctx, bb); }