-
Notifications
You must be signed in to change notification settings - Fork 238
Bytecode version differences
TODO: test if these are actually bytecode related, or just a newer version of GMS runtime (like with the padding or GMS2 stuff)
v15 | v16 |
---|---|
No LANG chunk | Contains a new LANG chunk |
No ROOM.GameObject.PreCreate | Contains a new ID reference to a Pre-Create code entry |
These two changes is literally all I could see. Let me know if you can find anything else.
To begin, here are the major file format updates between the two.
v14 | v15 |
---|---|
No code local information | The end of the FUNC chunk has code locals |
VARI chunk does not have initial 3 integers, variables do not have InstanceType or ID | VARI chunk has initial 3 integers (InstanceVarCount, InstanceVarCountAgain, MaxLocalVarCount), variables have InstanceType and ID |
FUNC chunk is only an array with NO length, containing function information | FUNC chunk has an array WITH length, containing function information, followed by an array (with length) containing code local information |
Each code entry has a string pointer to its name, followed by int32 length, immediately followed by the bytecode (using length) | Each code entry has a string pointer to its name, followed by int32 length, followed by int32 code local count, followed by int32 bytecode relative address, followed by int32 offset within the bytecode |
Additionally, from bytecode 14 to 15, the entire instruction set was changed. Here's a list of the basic operation opcode changes, with their patterns
Name | v14 Opcode | v15 Opcode |
---|---|---|
(Pattern for operations) | v15 opcode - 0x04 | v14 opcode + 0x04 |
Conv | 0x03 | 0x07 |
Mul | 0x04 | 0x08 |
Div | 0x05 | 0x09 |
Rem | 0x06 | 0x0A |
Mod | 0x07 | 0x0B |
Add | 0x08 | 0x0C |
Sub | 0x09 | 0x0D |
And | 0x0A | 0x0E |
Or | 0x0B | 0x0F |
Xor | 0x0C | 0x10 |
Neg | 0x0D | 0x11 |
Not | 0x0E | 0x12 |
Shl (shift left) | 0x0F | 0x13 |
Shr (shift right) | 0x10 | 0x14 |
Pop | 0x41 | 0x45 |
Dup | 0x82 | 0x86 |
(Pattern for most others) | v15 opcode + 0x01 | v14 opcode - 0x01 |
Ret | 0x9D | 0x9C |
Exit | 0x9E | 0x9D |
Popz | 0x9F | 0x9E |
B | 0xB7 | 0xB6 |
Bt | 0xB8 | 0xB7 |
Bf | 0xB9 | 0xB8 |
PushEnv | 0xBB | 0xBA |
PopEnv | 0xBC | 0xBB |
Call | 0xDA | 0xD9 |
(Exceptions) | ||
Cmp (not in v14 as one) | 0x11 to 0x16 | 0x15 |
Cmp (<) | 0x11 | N/A |
Cmp (<=) | 0x12 | N/A |
Cmp (==) | 0x13 | N/A |
Cmp (!=) | 0x14 | N/A |
Cmp (>=) | 0x15 | N/A |
Cmp (>) | 0x16 | N/A |
Push | 0xC0 | 0xC0 |
PushLoc | N/A | 0xC1 |
PushGlb | N/A | 0xC2 |
PushVar (builtin) | N/A | 0xC3 |
PushI (int16) | N/A | 0x84 |
Break (unchanged) | 0xFF | 0xFF |
In this list are some major exceptions - the Cmp instruction(s) and Push instruction(s).
For the Cmp instructions in bytecode 14, the ComparisonType parameter is unused (zero), and the opcode takes its place. Conveniently, they are in the same order as ComparisonType.
For the Push instruction in bytecode 14, it obviously only has one opcode instead of bytecode 15's five. This means that it depends on the instruction's data type heavily. To put it simply, if the data type is Variable, then the first two bytes of the instruction have the variable scope as an int16, be it -5 (global, PushGlb), -6 (builtin, PushVar), or -7 (local, PushLoc). Other types such as -1 (self) also exist, but is unnecessary because it already assumes them. Also, if the data type is Int16, then the instruction is the equivalent of bytecode 15's PushI.
As a side note, this means that instructions like push.e
and pushi.e
are now equivalent.
One other final note is that exiting a with statement early produces a PopEnv
with a magic number (in both versions), and in the case of bytecode 14, it seemingly produces 00 00 F0 BC
.
TODO: test if these are actually bytecode related, or just a newer version of GMS runtime (like with the padding or GMS2 stuff)
v13 | v14 |
---|---|
No AGRP chunk | Contains a new AGRP chunk |
No debugger port | Has a debugger port in GEN8 |
Different font padding | Consistent font padding |
It's also worth noting that some version within bytecode 13 changed the OPTN chunk drastically. Previously there were numerous 32-bit booleans for options, and these became a single 64-bit bitflag.