Currently the API `cs_disasm` allocates memory internally for disassembled instructions, which is expensive if we need to decode a lot of instructions. Here are some proposals to eliminate this issue to achieve better performance for Capstone. --- ## Proposal 1 This proposal proposes 2 new API: * `cs_disasm_malloc`: pre-allocate buffer for instructions * `cs_disasm_buf`: disassemble instructions into pre-allocated buffer provided by `cs_disasm_malloc` --- Prototype: ``` // pre-allocate memory for @count instructions cs_err cs_disasm_malloc(csh handle, size_t count, cs_insn **insn); // disassemble @count instructions using buffer pre-allocated // by cs_disasm_malloc() size_t cs_disasm_buf(csh handle, const uint8_t *code, size_t code_size, uint64_t address, size_t count, cs_insn *insn); ``` --- Sample code will be like below (C-pseudo) ``` if (cs_disasm_malloc(h, count, &insns) == CS_ERR_OK) { // mycount <= count while(c = cs_disasm_buf(h, code, size, address, mycount, insns)) { // analyze *c* instructions in @insns ... // then update input code/size/address for the next iteration length = CS_INSN_OFFSET(insns, c); code += length; size -= length; address += length; } // free memory when done cs_free(insns, count); } ``` --- ## Proposal 2 (by @danghvu) This proposal proposes 3 new API: * `cs_disasm_malloc`: pre-allocate buffer for 1 instruction * `cs_disasm_free`: free memory allocated by `cs_disasm_malloc`. Or we can just use `cs_free(insn, 1)` instead. * `cs_disasm_iter`: disassemble one instruction a time into pre-allocated buffer provided by `cs_disasm_malloc`, and update code/size/address at the same time. --- Prototype: ``` // pre-allocate memory for 1 instruction cs_err cs_disasm_malloc(csh handle, cs_insn **insn); // disassemble 1 instruction using buffer pre-allocated // by cs_disasm_malloc() bool cs_disasm_iter(csh handle, const uint8_t **code, size_t *code_size, uint64_t *address, cs_insn *insn); ``` --- Sample code will be like below (C-pseudo) ``` if (cs_disasm_malloc(h, &insn) == CS_ERR_OK) { while(cs_disasm_iter(h, &code, &size, &address, insn)) { // analyze instruction in @insn ... } // free memory when done cs_disasm_free(insn); } ```