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 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); } }