Skip to content

Commit

Permalink
Avoid mutating Instruction instances during emit
Browse files Browse the repository at this point in the history
  • Loading branch information
nike4613 committed Nov 24, 2024
1 parent 0260e82 commit 2c79cbb
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions src/MonoMod.Utils/DMDGenerators/DMDEmit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,20 +181,21 @@ public static void Generate(DynamicMethodDefinition dmd, MethodBase _mb, ILGener
il.Emit(_ReflOpCodes[instr.OpCode.Value]);
else
{
var opcode = instr.OpCode;
var operand = instr.Operand;

if (operand is Instruction[] targets)
{
operand = targets.Select(target => labelMap[target]).ToArray();
// Let's hope that the JIT treats the long forms identically to the short forms.
instr.OpCode = instr.OpCode.ToLongOp();
opcode = opcode.ToLongOp();

}
else if (operand is Instruction target)
{
operand = labelMap[target];
// Let's hope that the JIT treats the long forms identically to the short forms.
instr.OpCode = instr.OpCode.ToLongOp();
opcode = opcode.ToLongOp();

}
else if (operand is VariableDefinition var)
Expand Down Expand Up @@ -235,7 +236,7 @@ public static void Generate(DynamicMethodDefinition dmd, MethodBase _mb, ILGener
if (dm != null)
{
// SignatureHelper in unmanaged contexts cannot be fully made use of for DynamicMethods.
_EmitCallSite(dm, il, _ReflOpCodes[instr.OpCode.Value], csite);
_EmitCallSite(dm, il, _ReflOpCodes[opcode.Value], csite);
continue;
}
#if NETFRAMEWORK
Expand All @@ -251,7 +252,7 @@ public static void Generate(DynamicMethodDefinition dmd, MethodBase _mb, ILGener
#if NETFRAMEWORK
if (mb != null && operand is MethodBase called && called.DeclaringType == null) {
// "Global" methods (f.e. DynamicMethods) cannot be tokenized.
if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Call) {
if (opcode == Mono.Cecil.Cil.OpCodes.Call) {
if (called is MethodInfo target && target.IsDynamicMethod()) {
// This should be heavily optimizable.
operand = _CreateMethodProxy(mb, target);
Expand All @@ -263,19 +264,19 @@ public static void Generate(DynamicMethodDefinition dmd, MethodBase _mb, ILGener
else
il.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long) ptr);
il.Emit(System.Reflection.Emit.OpCodes.Conv_I);
instr.OpCode = Mono.Cecil.Cil.OpCodes.Calli;
opcode = Mono.Cecil.Cil.OpCodes.Calli;
operand = ((MethodReference) instr.Operand).ResolveReflectionSignature(mb.Module);
}
} else {
throw new NotSupportedException($"Unsupported global method operand on opcode {instr.OpCode.Name}");
throw new NotSupportedException($"Unsupported global method operand on opcode {opcode.Name}");
}
}
#endif

if (operand == null)
throw new InvalidOperationException($"Unexpected null in {def} @ {instr}");

il.DynEmit(_ReflOpCodes[instr.OpCode.Value], operand);
il.DynEmit(_ReflOpCodes[opcode.Value], operand);
}

if (!checkTryEndEarly)
Expand Down

0 comments on commit 2c79cbb

Please sign in to comment.