Kernel: Use vector<array<Module*>> instead of flat array

As it turns out ON_CONFIG_RELOAD filled the previous array size of 32
entries. Using vector<array<...>> here does incur a memory indirection,
which Arthur rightly points out will have a performance penalty in a hot
path. That being said, we'll use this for now. Eventually it might make
sense to move to array<array<...>> with a sufficiently large size.
Kernel: Add bounds checking in register_for_event

This seems like a no-brainer. There really shouldn't be any
performance-sensitive code calling this.
Kernel: Add bounds checks to call_event

This might be a bit more controversial although honestly an inequality
check should be dirt cheap in terms of clock cycles
Gcode: Use operator[] instead of string::at to avoid allocation

Not entire sure why at allocates, but we don't need bounds checking
regardless
Gcode: Use const_cast to silence warning