src
XnaToFnaUtil.Stubber.cs
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using XnaToFna.ProxyForms;
using System.Xml.Serialization;
using System.Xml;
using System.Linq;
namespace XnaToFna {
public partial clast XnaToFnaUtil : IDisposable {
public static System.Reflection.ConstructorInfo m_UnverifiableCodeAttribute_ctor = typeof(System.Security.UnverifiableCodeAttribute).GetConstructor(Type.EmptyTypes);
public void Stub(ModuleDefinition mod) {
Log($"[Stub] Stubbing {mod.astembly.Name.Name}");
Modder.Module = mod;
ApplyCommonChanges(mod, "Stub");
// MonoMod needs to relink some types (f.e. XnaToFnaHelper) via FindType, which requires a dependency map.
Log("[Stub] Mapping dependencies for MonoMod");
Modder.MapDependencies(mod);
Log($"[Stub] Stubbing");
foreach (TypeDefinition type in mod.Types)
StubType(type);
Log($"[Stub] Pre-processing");
foreach (TypeDefinition type in mod.Types)
PreProcessType(type);
Log($"[Stub] Relinking (MonoMod PatchRefs past)");
Modder.PatchRefs();
Log($"[Stub] Post-processing");
foreach (TypeDefinition type in mod.Types)
PostProcessType(type);
Log($"[Stub] Rewriting and disposing module\n");
#if !CECIL0_9
Modder.Module.Write(Modder.WriterParameters);
#else
Modder.Module.Write(ModulePaths[Modder.Module], Modder.WriterParameters);
#endif
// Dispose the module so other modules can read it as a dependency again.
#if !CECIL0_9
Modder.Module.Dispose();
#endif
Modder.Module = null;
Modder.ClearCaches(moduleSpecific: true);
}
public void StubType(TypeDefinition type) {
foreach (FieldDefinition field in type.Fields) {
field.Attributes &= ~FieldAttributes.HasFieldRVA;
}
foreach (MethodDefinition method in type.Methods) {
if (method.HasPInvokeInfo)
method.PInvokeInfo = null;
method.IsManaged = true;
method.IsIL = true;
method.IsNative = false;
method.PInvokeInfo = null;
method.IsPreserveSig = false;
method.IsInternalCall = false;
method.IsPInvokeImpl = false;
MethodBody body = method.Body = new MethodBody(method);
body.InitLocals = true;
ILProcessor il = body.GetILProcessor();
for (int i = 0; i < method.Parameters.Count; i++) {
ParameterDefinition param = method.Parameters[i];
if (param.IsOut || param.IsReturnValue) {
il.Emit(OpCodes.Ldarg, param);
il.EmitDefault(param.ParameterType, true);
}
}
il.EmitDefault(method.ReturnType ?? method.Module.TypeSystem.Void);
il.Emit(OpCodes.Ret);
}
foreach (TypeDefinition nested in type.NestedTypes)
StubType(nested);
}
}
}