Skip to content

Commit 6cb4141

Browse files
committed
Fix incorrect position of inserted instructions
1 parent b096f48 commit 6cb4141

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

ModLocalizer/Extensions/InstructionExtensions.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using dnlib.DotNet.Emit;
45

@@ -16,5 +17,40 @@ public static void Insert(this IList<Instruction> inst, int index, IEnumerable<I
1617
inst.Insert(index, instruction);
1718
}
1819
}
20+
21+
/// <summary>
22+
/// Inserts a group of instructions into given instructions at the arbitrary last.
23+
/// </summary>
24+
public static void AppendLast(this IList<Instruction> inst, IEnumerable<Instruction> instructions)
25+
{
26+
// create a copy of instructions to be inserted
27+
var list = instructions.ToList();
28+
if (!list.Any())
29+
{
30+
return;
31+
}
32+
33+
// valid target method should have `ret` as last instruction
34+
var retInst = inst.Last();
35+
if (retInst.OpCode != OpCodes.Ret)
36+
{
37+
throw new ArgumentOutOfRangeException(nameof(inst), "Invalid method instructions.");
38+
}
39+
40+
// alter the last instruction of the target
41+
var first = list.First();
42+
retInst.OpCode = first.OpCode;
43+
retInst.Operand = first.Operand;
44+
45+
// prepare instruction list
46+
list.Remove(first);
47+
list.Add(OpCodes.Ret.ToInstruction());
48+
49+
// insert into the target
50+
foreach (var instruction in list)
51+
{
52+
inst.Add(instruction);
53+
}
54+
}
1955
}
2056
}

ModLocalizer/TranslationEmitter.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,9 @@ public TranslationEmitter(ModuleDef module, string gameCulture, string modName)
8181
type.Methods.Add(loadMethod);
8282
}
8383

84-
var instructions = loadMethod.Body.Instructions;
85-
86-
// to prevert `call Localizer_setTranslation<>` being transfer target
87-
instructions[instructions.Count - 1].OpCode = OpCodes.Ldarg_0; // ret -> ldarg.0
88-
89-
instructions.Insert(instructions.Count, new[]
84+
loadMethod.Body.Instructions.AppendLast(new[]
9085
{
86+
OpCodes.Ldarg_0.ToInstruction(),
9187
OpCodes.Call.ToInstruction(_modSetTranslationMethod),
9288
OpCodes.Ret.ToInstruction()
9389
});
@@ -111,7 +107,7 @@ public void Emit(MethodDef method, string propertyName, string content)
111107
MethodSig.CreateInstance(new ClassSig(_modTranslationType)),
112108
method.DeclaringType.BaseType);
113109

114-
instructions.Insert(instructions.Count - 1, new[]
110+
instructions.AppendLast(new[]
115111
{
116112
OpCodes.Ldarg_0.ToInstruction(),
117113
OpCodes.Call.ToInstruction(translationPropertyGetter),
@@ -190,7 +186,7 @@ private string AddTranslation(string key, string @default, string content)
190186
{
191187
var instructions = _modSetTranslationMethod.Body.Instructions;
192188

193-
instructions.Insert(instructions.Count - 1, new[]
189+
instructions.AppendLast(new[]
194190
{
195191
OpCodes.Ldarg_0.ToInstruction(),
196192
OpCodes.Ldstr.ToInstruction(key),

0 commit comments

Comments
 (0)