RZ_API RzAnalysisOp *rz_core_analysis_op(RzCore *core, ut64 addr, int mask) {
	int len;
	ut8 buf[32];
	ut8 *ptr;

	rz_return_val_if_fail(core, NULL);
	if (addr == UT64_MAX) {
		return NULL;
	}
	RzAnalysisOp *op = RZ_NEW0(RzAnalysisOp);
	if (!op) {
		return NULL;
	}
	int delta = (addr - core->offset);
	int minopsz = 8;
	if (delta > 0 && delta + minopsz < core->blocksize && addr >= core->offset && addr + 16 < core->offset + core->blocksize) {
		ptr = core->block + delta;
		len = core->blocksize - delta;
		if (len < 1) {
			goto err_op;
		}
	} else {
		if (!rz_io_read_at(core->io, addr, buf, sizeof(buf))) {
			goto err_op;
		}
		ptr = buf;
		len = sizeof(buf);
	}
	if (rz_analysis_op(core->analysis, op, addr, ptr, len, mask) < 1) {
		goto err_op;
	}
	// TODO This code block must be deleted when all the analysis plugins support disasm
	if (!op->mnemonic && mask & RZ_ANALYSIS_OP_MASK_DISASM) {
		RzAsmOp asmop;
		if (core->analysis->verbose) {
			eprintf("WARNING: Implement RzAnalysisOp.MASK_DISASM for current analysis.arch. Using the sluggish RzAsmOp fallback for now.\n");
		}
		rz_asm_set_pc(core->rasm, addr);
		rz_asm_op_init(&asmop);
		if (rz_asm_disassemble(core->rasm, &asmop, ptr, len) > 0) {
			op->mnemonic = strdup(rz_strbuf_get(&asmop.buf_asm));
		}
		rz_asm_op_fini(&asmop);
	}
	return op;
err_op:
	free(op);
	return NULL;
}
RZ_API RzAnalysisOp *rz_core_analysis_op(RzCore *core, ut64 addr, int mask) {
	int len;
	ut8 buf[32];
	ut8 *ptr;

	rz_return_val_if_fail(core, NULL);
	if (addr == UT64_MAX) {
		return NULL;
	}
	RzAnalysisOp *op = RZ_NEW0(RzAnalysisOp);
	if (!op) {
		return NULL;
	}
	int delta = (addr - core->offset);
	int minopsz = 8;
	if (delta > 0 && delta + minopsz < core->blocksize && addr >= core->offset && addr + 16 < core->offset + core->blocksize) {
		ptr = core->block + delta;
		len = core->blocksize - delta;
		if (len < 1) {
			goto err_op;
		}
	} else {
		if (!rz_io_read_at(core->io, addr, buf, sizeof(buf))) {
			goto err_op;
		}
		ptr = buf;
		len = sizeof(buf);
	}
	if (rz_analysis_op(core->analysis, op, addr, ptr, len, mask) < 1) {
		goto err_op;
	}
	 
	if (!op->mnemonic && mask & RZ_ANALYSIS_OP_MASK_DISASM) {
		RzAsmOp asmop;
		if (core->analysis->verbose) {
			eprintf("WARNING: Implement RzAnalysisOp.MASK_DISASM for current analysis.arch. Using the sluggish RzAsmOp fallback for now.\n");
		}
		rz_asm_set_pc(core->rasm, addr);
		rz_asm_op_init(&asmop);
		if (rz_asm_disassemble(core->rasm, &asmop, ptr, len) > 0) {
			op->mnemonic = strdup(rz_strbuf_get(&asmop.buf_asm));
		}
		rz_asm_op_fini(&asmop);
	}
	return op;
err_op:
	free(op);
	return NULL;
}