My project has, among other things, emulation of a rather complex CPU. It would be useful to isolate it as a separate crate, so that it's easy to reuse in other projects.
In order to use the CPU, of course, you need to implement a number of functions so that it can communicate with the outside world. This often has to happen somewhere deep within the emulator, several call stacks deep.
One wrinkle is that for speed, I use
static muts instead of the more dynamic
self references. In the original C code, which this project is a port of, using statically allocated structures with a fixed compile-time address resulted in a 15-30% speedup over runtime allocated ones. Yes, I know this doesn't lead to very pretty code, but in this case, the performance improvements are large enough that I'm willing to stick to this.
In C, it was easy enough to pass around a few function pointers:
typedef void (*io_write_t)(void* opaque, int port, int value); void cpu_register_io_write(int port_range_start, int port_range_end, void* opaque, io_write_t handler);
opaque, in this case, roughly corresponds to
&mut self; you supply a reference to
&mut self along with the handler so that the handler has some idea what object it's supposed to act on, if more than one instance of
In Java, it was possible to create an interface containing all the functions that I needed.
this would be passed automatically, and personally I prefer this method over C's function pointers, since the interface lets you know beforehand what methods you need to implement.
The only way that I would be able to implement this with my current understanding of Rust is to create function pointers, passing
*mut u8 around as a
void* pointer and having the callee convert that back into a
&mut self reference. But that would lead to really ugly code, and I'd like to use traits instead. So far, trying to mix traits with statics has been exceedingly frustrating, and nothing has worked.
Is there a better way?