static void Main(string[] args) { ParseArguments(args); Console.WriteLine("[UnsafeUtilityPatcher] Patching assembly : " + s_AssemblyPath + " to : " + s_OutputPath); var assembly = AssemblyDefinition.ReadAssembly(s_AssemblyPath, new ReaderParameters { SymbolReaderProvider = CreateDebugReaderProviderFor(s_AssemblyPath) }); var UnsafeUtilityType = assembly.MainModule.Types.Single(t => t.Name.Equals(kUnsafeUtilityIdentifier)); var ctx = new UnsafeUtilityPatcherContext(UnsafeUtilityType, false); InjectUtilityCopyPtrToStructure(ctx); InjectUtilityCopyStructureToPtr(ctx); InjectUtilityAddressOf(ctx); InjectUtilitySizeOf(ctx); InjectUtilityAlignOf(ctx); InjectUtilityReadArrayElement(ctx); InjectUtilityReadArrayElementWithStride(ctx); InjectUtilityWriteArrayElement(ctx); InjectUtilityWriteArrayElementWithStride(ctx); InjectUtilityAsRef(ctx); EnsureTargetFolderExists(s_OutputPath); assembly.Write(s_OutputPath, new WriterParameters { SymbolWriterProvider = CreateDebugWriterProviderFor(s_AssemblyPath) }); }
private static void InjectUtilityArrayElementAsRef(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityArrayElementAsRef); /* * ldarg.0 * ldarg.1 * sizeof !T * mul * add * ret */ var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilityArrayElementAsRef)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8)); ilProcessor.Append(ilProcessor.Create(OpCodes.Sizeof, method.GenericParameters[0])); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8)); ilProcessor.Append(ilProcessor.Create(OpCodes.Mul)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I)); ilProcessor.Append(ilProcessor.Create(OpCodes.Add)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }
private static void InjectUtilityWriteArrayElementWithStride(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityWriteArrayElementWithStride); /* * ldarg.0 * ldarg.1 * conv.i8 * ldarg.2 * conv.i8 * mul * conv.i * add * ldarg.3 * stobj !T * ret */ var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilityWriteArrayElementWithStride)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_2)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8)); ilProcessor.Append(ilProcessor.Create(OpCodes.Mul)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I)); ilProcessor.Append(ilProcessor.Create(OpCodes.Add)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_3)); ilProcessor.Append(ilProcessor.Create(OpCodes.Stobj, method.GenericParameters[0])); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }
private static void LoadField(UnsafeUtilityPatcherContext ctx, string fieldName, ILProcessor ilProcessor) { ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0)); var field = ctx.m_PatchedClass.Fields.Single(f => f.Name == fieldName); var fieldReference = new FieldReference(field.Name, field.FieldType, ctx.m_GenericInstanceType); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldfld, fieldReference)); }
private static void InjectUtilityAsRef(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityAsRef); /* * ldarg.0 * ret */ ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }
private static void InjectUtilityAlignOf(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityAlignOf); /* * // @todo : Implement * ldc.i4 4 * ret */ ilProcessor.Append(ilProcessor.Create(OpCodes.Ldc_I4, 4)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }
private static void InjectUtilitySizeOfNonGeneric(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilitySizeOfNonGeneric); /* * sizeof !T * ret */ var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilitySizeOf) && m.HasGenericParameters); ilProcessor.Append(ilProcessor.Create(OpCodes.Sizeof, method.GenericParameters[0])); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }
private static ILProcessor GetILProcessorForMethod(UnsafeUtilityPatcherContext ctx, string methodName, bool clear = true) { var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(methodName) && m.HasGenericParameters); var ilProcessor = method.Body.GetILProcessor(); if (clear) { ilProcessor.Body.Instructions.Clear(); ilProcessor.Body.Variables.Clear(); ilProcessor.Body.ExceptionHandlers.Clear(); } return(ilProcessor); }
private static void InjectUtilityInternalEnumToInt(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityInternalEnumToInt); /* * ldarg.0 * conv.i4 * ret */ ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I4)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }
private static void CallMethod(UnsafeUtilityPatcherContext ctx, string methodName, ILProcessor ilProcessor) { var method = ctx.m_PatchedClass.GetMethods().Single(m => m.Name == methodName); var methodReference = new MethodReference(method.Name, method.ReturnType, ctx.m_GenericInstanceType) { CallingConvention = method.CallingConvention, HasThis = method.HasThis, }; foreach (var param in method.Parameters) { methodReference.Parameters.Add(param); } ilProcessor.Append(ilProcessor.Create(OpCodes.Call, methodReference)); }
private static void InjectUtilityCopyStructureToPtr(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityCopyStructureToPtr); /* * ldarg.0 * ldobj !T * ldarg.1 * stind.i * ret */ var method = ctx.m_PatchedClass.Methods.Single(m => m.Name.Equals(kUnsafeUtilityCopyStructureToPtr)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldobj, method.GenericParameters[0])); ilProcessor.Append(ilProcessor.Create(OpCodes.Stobj, method.GenericParameters[0])); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }
private static void InjectUtilityEnumEquals(UnsafeUtilityPatcherContext ctx) { var ilProcessor = GetILProcessorForMethod(ctx, kUnsafeUtilityEnumEquals); /* * ldarg.0 * conv.i8 * ldarg.1 * conv.i8 * ceq * ret */ ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_0)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ldarg_1)); ilProcessor.Append(ilProcessor.Create(OpCodes.Conv_I8)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ceq)); ilProcessor.Append(ilProcessor.Create(OpCodes.Ret)); }