Specify whether the VM uses IO or not, and if not don't create
channels. These are more expensive than I expected, and
pointlessly creating/destroying them thousands of times is
a significant CPU drain.
- Store opcodes in an array rather than a map for faster lookup
(this means storing them as interface{} as otherwise the types
form a circular dependency, which is icky but worth the
performance boost).
- Don't dynamically create an 'Arg' function every step of the vm.
This was *super* expensive.
- Calculate a bitmask of the argument modes instead of relying
on on-demand div-modding.
- Only buffer a single value in the I/O buffers to reduce the
size of allocations.