public RecompileMethod ( Mono.Cecil methodDef ) : |
||
methodDef | Mono.Cecil | |
return |
public void aa() { var obj = new TestClass1(); var cecilTestClass1 = CurrentAssembly.FindRuntimeType(typeof(TestClass1)); cecilTestClass1.Methods.First(method => method.Name == "TestMethod"); var method1 = cecilTestClass1.GetMethodByName("TestMethod"); var dynMethod = Recompiler.RecompileMethod(method1); var result = dynMethod.Invoke(obj, new object[] { obj }); Assert.AreEqual("ab", (string)result); Assert.AreEqual(obj.a, 1); }
public void HotPatch(string assemblyFilename) { Debug.LogFormat("Started hotpatching {0}", assemblyFilename); var newAssembly = Cecil.AssemblyDefinition.ReadAssembly(assemblyFilename); foreach (var method in IterateMethods(newAssembly)) { int hashcode; if (methodHashes.TryGetValue(method.FullName, out hashcode)) { if (hashcode == GenBodyHashcode(method)) { continue; } string oldBody = methodBodies[method.FullName]; string newBody = ConcatBody(method); Debug.Log("Trying to hotpatch " + method.FullName); var ourType = recompiler.FindType(method.DeclaringType); if (ourType == null) { continue; } var patchField = ourType.GetField(method.GetHotpatchFieldName(), BindingFlags.Static | BindingFlags.NonPublic); if (patchField == null) { Debug.LogWarningFormat("Cannot patch {0} - function is not hotpatchable", method.FullName); continue; } Debug.Trace("Hotswapping {0}", method.FullName); Debug.Trace("Method signature was: {0}, is: {1}", methodHashes[method.FullName], GenBodyHashcode(method)); Debug.Trace("Method body was:"); Debug.Trace(methodBodies[method.FullName]); Debug.Trace("Method body is:"); Debug.Trace(ConcatBody(method)); try { var dynmethod = recompiler.RecompileMethod(method); if (dynmethod != null) { patchField.SetValue(null, dynmethod); methodHashes[method.FullName] = GenBodyHashcode(method); methodBodies[method.FullName] = ConcatBody(method); } } catch (Exception e) { Debug.LogWarningFormat("Failed to patch {0} - {1}. See full stacktrace in Temp/hotpatch.log.", method.FullName, e.Message); Debug.Trace(e.StackTrace); } } } }
public void HotPatch(string assemblyFilename) { Debug.Trace("Started hotpatching {0}", assemblyFilename); var newAssembly = Cecil.AssemblyDefinition.ReadAssembly(assemblyFilename); foreach (var method in IterateMethods(newAssembly)) { Debug.Trace($"Searching for {method.FullName}"); LocalMethod localMethod; if (!localMethods.TryGetValue(method.FullName, out localMethod)) { Debug.Trace($"Did not find loaded method {method.FullName}. New method or a bug."); continue; } string newBody = ConcatBody(method); int newBodyHash = newBody.GetHashCode(); if (localMethod.BodyHashCode == newBody.GetHashCode()) { Debug.Trace($"Found {method.FullName}, but hash code didn't change."); continue; } string oldBody = localMethod.BodyString; Debug.Log($"<i>Trying to hotpatch {method.FullName}...</i>"); if (localMethod.Method == null) { Debug.Log($"Can't hotpatch {method.FullName} - local method not found,"); continue; } Debug.Trace("----------"); Debug.Trace("Hotswapping {0}", method.FullName); Debug.Trace("Method body hashcode was: {0}, is: {1}", localMethod.BodyHashCode, newBodyHash); Debug.Trace("Method body was:"); Debug.Trace(oldBody); Debug.Trace("Method body is:"); Debug.Trace(newBody); try { var dynmethod = recompiler.RecompileMethod(method); if (dynmethod != null) { SwapMethod(localMethod.Method, dynmethod); localMethod.CurrentSwap = dynmethod; localMethod.BodyString = newBody; localMethod.BodyHashCode = newBodyHash; } } catch (Exception e) { Debug.LogWarningFormat("Failed to patch {0}. <i>See full stacktrace in Temp/hotpatch.log.</i>\nError is: {1}", method.FullName, e.Message); Debug.Trace(e.StackTrace); } finally { Debug.Trace("----------"); } } }