/// <summary> /// Converts a <see cref="Code"/> to an <see cref="OpCode"/>, using a module context to look /// up potential experimental opcodes /// </summary> /// <param name="code">The code</param> /// <param name="context">The module context</param> /// <returns>A <see cref="OpCode"/> or <c>null</c> if it's invalid</returns> public static OpCode ToOpCode(this Code code, ModuleContext context) { byte hi = (byte)((ushort)code >> 8); byte lo = (byte)code; if (hi == 0) { return(OpCodes.OneByteOpCodes[lo]); } if (hi == 0xFE) { return(OpCodes.TwoByteOpCodes[lo]); } if (context.GetExperimentalOpCode(hi, lo) is OpCode op) { return(op); } if (code == Code.UNKNOWN1) { return(OpCodes.UNKNOWN1); } if (code == Code.UNKNOWN2) { return(OpCodes.UNKNOWN2); } return(null); }
/// <summary> /// Reads the next OpCode from the current position /// </summary> OpCode ReadOpCode() { var op = reader.ReadByte(); if (op == 0xFE) { return(OpCodes.TwoByteOpCodes[reader.ReadByte()]); } if (op >= 0xF0 && op <= 0xFB && context is not null && reader.BytesLeft >= 1) { if (context.GetExperimentalOpCode(op, reader.ReadByte()) is OpCode opCode) { return(opCode); } else { reader.Position--; } } return(OpCodes.OneByteOpCodes[op]); }