public void Unserialize(GMDataReader reader) { Name = reader.ReadStringPointerObject(); Length = reader.ReadInt32(); if (reader.VersionInfo.FormatID <= 14) { BytecodeEntry = new Bytecode(this); BytecodeEntry.Unserialize(reader, Length); } else { LocalsCount = reader.ReadInt16(); int v = reader.ReadInt16(); ArgumentsCount = (short)(v & 0b1111111111111); Flags = (byte)(v >> 13); int relativeBytecodeAddr = reader.ReadInt32(); int absoluteBytecodeAddr = (reader.Offset - 4) + relativeBytecodeAddr; bool childCandidate = false; if (reader.PointerOffsets.TryGetValue(absoluteBytecodeAddr, out GMSerializable s)) { if (s is Bytecode b) { BytecodeEntry = b; childCandidate = true; } } if (BytecodeEntry == null) { BytecodeEntry = new Bytecode(this); if (Length != 0) // prevent pointer overlap of entries with 0 instructions { reader.PointerOffsets[absoluteBytecodeAddr] = BytecodeEntry; } int returnTo = reader.Offset; reader.Offset = absoluteBytecodeAddr; BytecodeEntry.Unserialize(reader, Length); reader.Offset = returnTo; } BytecodeOffset = reader.ReadInt32(); if (childCandidate && Length != 0 && BytecodeOffset != 0) { // Assign parents and children of this entry ParentEntry = BytecodeEntry.Parent; BytecodeEntry.Parent.ChildEntries.Add(this); } } }
public Bytecode(GMCode parent) { Parent = parent; }