From 8aea82c6788dbc2b27e1968056473f663fd87cba Mon Sep 17 00:00:00 2001 From: zc <2650838+Wack0@users.noreply.github.com> Date: Fri, 31 Mar 2023 12:52:45 +0100 Subject: [PATCH] libifps: fix loading and saving op2 for InlineCmpValueType (is instruction) libifps: document is instruction better libifps: document InlineCmpValueType better --- IFPSLib/Emit/Instruction.cs | 22 +++++++++++++++++++--- IFPSLib/Emit/OpCodes.cs | 1 + IFPSLib/Emit/OperandType.cs | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/IFPSLib/Emit/Instruction.cs b/IFPSLib/Emit/Instruction.cs index cb11f82..3f6f093 100644 --- a/IFPSLib/Emit/Instruction.cs +++ b/IFPSLib/Emit/Instruction.cs @@ -29,6 +29,8 @@ namespace IFPSLib.Emit private List m_Operands = new List(); + private static readonly Operand s_opU32 = Operand.Create(0); + /// /// Gets or sets the operand at the specified index. /// @@ -380,6 +382,13 @@ namespace IFPSLib.Emit return FixBranchOffset(br, br.Read()); } + private static Operand ReadTypeForCmpValueType(BinaryReader br, Script script, ScriptFunction function) + { + var operand = Operand.LoadValue(br, script, function); + if (operand.Type == BytecodeOperandType.Immediate) return Operand.Create(script.Types[(int)operand.ImmediateAs()]); + return operand; + } + internal static Instruction Load(BinaryReader br, Script script, ScriptFunction function) { var ret = new Instruction(); @@ -449,7 +458,7 @@ namespace IFPSLib.Emit ret.m_Operands = new List(3) { Operand.LoadValue(br, script, function), Operand.LoadValue(br, script, function), - Operand.Create(script.Types[(int)br.Read()]) + ReadTypeForCmpValueType(br, script, function) }; break; case OperandType.InlineEH: @@ -565,7 +574,7 @@ namespace IFPSLib.Emit ret += m_Operands[0].Size + m_Operands[1].Size + m_Operands[2].Size; break; case OperandType.InlineCmpValueType: - ret += m_Operands[0].Size + m_Operands[1].Size + sizeof(int); + ret += m_Operands[0].Size + m_Operands[1].Size + (m_Operands[2].Type != BytecodeOperandType.Immediate ? m_Operands[2] : s_opU32).Size; break; case OperandType.InlineEH: ret += sizeof(uint) * 4; @@ -664,7 +673,14 @@ namespace IFPSLib.Emit case OperandType.InlineCmpValueType: m_Operands[0].Save(bw, ctx); m_Operands[1].Save(bw, ctx); - bw.Write(ctx.GetTypeIndex(m_Operands[2].ImmediateAs())); + if (m_Operands[2].Type == BytecodeOperandType.Immediate) + { + Operand.Create((uint)ctx.GetTypeIndex(m_Operands[2].ImmediateAs())).Save(bw, ctx); + } + else + { + m_Operands[2].Save(bw, ctx); + } break; case OperandType.InlineEH: bw.Write(GetEHOffset(m_Operands[0], table)); diff --git a/IFPSLib/Emit/OpCodes.cs b/IFPSLib/Emit/OpCodes.cs index 82e091c..5792624 100644 --- a/IFPSLib/Emit/OpCodes.cs +++ b/IFPSLib/Emit/OpCodes.cs @@ -186,6 +186,7 @@ namespace IFPSLib.Emit /// /// Operand 1 must be a , operand 2 is a that must be a /// Checks if operand 1 is of the referenced by operand 2. + /// Operand 2 can also be a variable of type containing the index of the type to compare against. /// public static readonly OpCode Is = new OpCode("is", Code.Is, OperandType.InlineCmpValueType, FlowControl.Next, OpCodeType.Macro); diff --git a/IFPSLib/Emit/OperandType.cs b/IFPSLib/Emit/OperandType.cs index e2d203c..3ae7c1b 100644 --- a/IFPSLib/Emit/OperandType.cs +++ b/IFPSLib/Emit/OperandType.cs @@ -39,7 +39,7 @@ namespace IFPSLib.Emit /// InlineCmpValue, /// - /// Two s followed by + /// Three s where the last is a type index /// InlineCmpValueType, ///