R_API RAsmOp *r_core_disassemble (RCore *core, ut64 addr) {
	int delta;
	ut8 buf[128];
	static RBuffer *b = NULL; // XXX: never freed and non-thread safe. move to RCore
	RAsmOp *op;
	if (!b) {
		b = r_buf_new ();
		if (!b || !r_core_read_at (core, addr, buf, sizeof (buf))) {
			return NULL;
		}
		b->base = addr;
		r_buf_set_bytes (b, buf, sizeof (buf));
	} else {
		if ((addr < b->base) || addr > (b->base + b->length - 32)) {
			if (!r_core_read_at (core, addr, buf, sizeof (buf))) {
				return NULL;
			}
			b->base = addr;
			r_buf_set_bytes (b, buf, sizeof (buf));
		}
	}
	delta = addr - b->base;
	op = R_NEW0 (RAsmOp);
	r_asm_set_pc (core->assembler, addr);
	if (r_asm_disassemble (core->assembler, op, b->buf + delta, b->length) < 1) {
		free (op);
		return NULL;
	}
	return op;
}
R_API RAsmOp *r_core_disassemble (RCore *core, ut64 addr) {
	int delta;
	ut8 buf[128];
	static RBuffer *b = NULL;  
	RAsmOp *op;
	if (!b) {
		b = r_buf_new ();
		if (!b || !r_core_read_at (core, addr, buf, sizeof (buf))) {
			return NULL;
		}
		b->base = addr;
		r_buf_set_bytes (b, buf, sizeof (buf));
	} else {
		if ((addr < b->base) || addr > (b->base + b->length - 32)) {
			if (!r_core_read_at (core, addr, buf, sizeof (buf))) {
				return NULL;
			}
			b->base = addr;
			r_buf_set_bytes (b, buf, sizeof (buf));
		}
	}
	delta = addr - b->base;
	op = R_NEW0 (RAsmOp);
	r_asm_set_pc (core->assembler, addr);
	if (r_asm_disassemble (core->assembler, op, b->buf + delta, b->length) < 1) {
		free (op);
		return NULL;
	}
	return op;
}