OP_HALT = 1 now. This commit also adjusts the error checking in
inst_read_bytecode.
The main reasoning behind this is when other platforms or applications
target the AVM: whenever a new opcode may be added, the actual binary
for OP_HALT changes (as a result of how C enums work).
Say your application targets commit alpha of AVM. OP_HALT is, say,
98. In commit beta, AVM is updated with a new opcode so OP_HALT is
changed to 99 (due to the new opcode being placed before OP_HALT). If
your application builds a binary for AVM version alpha and AVM version
beta is used instead, OP_HALT will be interpreted as another
instruction, which can lead to undefined behaviour.
This can be hard to debug, so here I've made the decision to try and
not place new opcodes in between old ones; new ones will always be
placed *before* NUMBER_OF_OPCODES.
Instead of using a linked list, which is incredibly fragmented, a
vector keeps all pointers together. Keeps all our stuff together and
in theory we should have less cache misses when deleting pages.
It does introduce the issue of fragmenting, where if we allocate and
then delete many times a lot of the heap vector will be empty so
traversal will be over a ton of useless stuff.
Copied the code from stack overflow without thinking about it. The
first byte in little endian order should always be LSB so I construct
a more contrived example (0xFFFF0000) which should make it easier to
detect what the first byte is considered on the machine. If it's 0
then the LSB is the first byte hence little endian, otherwise it's big
endian.
On a greater note: Don't never copy no code from stack overflow, bro.
I went up there at 11 o'clock last night trynna get me some code.
Bro, I copied that shit, woke up, my motherfucking LITTLE_ENDIAN
detection don't work. Explain, bro.
While it helped with understanding to use unions as a safe way to
access the underlying bits, this shift based mechanism actually makes
more sense at a glance, particularly by utilising WORD_NTH_BYTE
The new general testing procedure is making a structure for tests that
include all the samples and expected results, then iterating over them
to run the test.
In particular, __LITTLE_ENDIAN__ was not a functioning macro.
Instead, I implemented a version by hand (copied from IBM) that
actually figures out if the machine is little endian or not.
Thank you unit testing!