public void GetTokenFor_String_Success() { DynamicMethod dynamicMethod = new DynamicMethod(nameof(HelloWorld), typeof(string), new Type[] { }, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(string), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x72, 0x01, 0x00, 0x00, 0x70, 0x6f, 0x04, 0x00, 0x00, 0x0a, 0x0a, 0x2b, 0x00, 0x06, 0x2a }; int token0 = dynamicILInfo.GetTokenFor("hello, world"); int token1 = dynamicILInfo.GetTokenFor(typeof(string).GetMethod("ToUpper", Type.EmptyTypes).MethodHandle); PutInteger4(token0, 0x0002, code); PutInteger4(token1, 0x0007, code); dynamicILInfo.SetCode(code, 1); string ret = (string)dynamicMethod.Invoke(null, null); Assert.Equal(ret, HelloWorld()); }
public void GetTokenFor_StringGenerics_Success() { DynamicMethod dynamicMethod = new DynamicMethod(nameof(ContactString), typeof(string), Type.EmptyTypes, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(MyList <string>), false); sigHelper.AddArgument(typeof(string), false); sigHelper.AddArgument(typeof(string), false); sigHelper.AddArgument(typeof(string), false); sigHelper.AddArgument(typeof(System.Collections.Generic.IEnumerator <string>), false); sigHelper.AddArgument(typeof(bool), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x73, 0x26, 0x00, 0x00, 0x0a, 0x0a, 0x06, 0x72, 0x29, 0x01, 0x00, 0x70, 0x6f, 0x27, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x72, 0x37, 0x01, 0x00, 0x70, 0x6f, 0x27, 0x00, 0x00, 0x0a, 0x00, 0x7e, 0x28, 0x00, 0x00, 0x0a, 0x0b, 0x00, 0x06, 0x6f, 0x29, 0x00, 0x00, 0x0a, 0x13, 0x04, 0x2b, 0x12, 0x11, 0x04, 0x6f, 0x2a, 0x00, 0x00, 0x0a, 0x0c, 0x00, 0x07, 0x08, 0x28, 0x2b, 0x00, 0x00, 0x0a, 0x0b, 0x00, 0x11, 0x04, 0x6f, 0x20, 0x00, 0x00, 0x0a, 0x13, 0x05, 0x11, 0x05, 0x2d, 0xe1, 0xde, 0x14, 0x11, 0x04, 0x14, 0xfe, 0x01, 0x13, 0x05, 0x11, 0x05, 0x2d, 0x08, 0x11, 0x04, 0x6f, 0x21, 0x00, 0x00, 0x0a, 0x00, 0xdc, 0x00, 0x07, 0x0d, 0x2b, 0x00, 0x09, 0x2a }; int token0 = dynamicILInfo.GetTokenFor(typeof(MyList <string>).GetConstructor(Type.EmptyTypes).MethodHandle, typeof(MyList <string>).TypeHandle); int token1 = dynamicILInfo.GetTokenFor("Hello~"); int token2 = dynamicILInfo.GetTokenFor(typeof(MyList <string>).GetMethod("Add").MethodHandle, typeof(MyList <string>).TypeHandle); int token3 = dynamicILInfo.GetTokenFor("World!"); int token4 = dynamicILInfo.GetTokenFor(typeof(string).GetField("Empty").FieldHandle); int token5 = dynamicILInfo.GetTokenFor(typeof(MyList <string>).GetMethod("GetEnumerator").MethodHandle, typeof(MyList <string>).TypeHandle); int token6 = dynamicILInfo.GetTokenFor(typeof(System.Collections.Generic.IEnumerator <string>).GetMethod("get_Current").MethodHandle, typeof(System.Collections.Generic.IEnumerator <string>).TypeHandle); int token7 = dynamicILInfo.GetTokenFor(typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }).MethodHandle); int token8 = dynamicILInfo.GetTokenFor(typeof(System.Collections.IEnumerator).GetMethod("MoveNext").MethodHandle); int token9 = dynamicILInfo.GetTokenFor(typeof(System.IDisposable).GetMethod("Dispose").MethodHandle); PutInteger4(token0, 0x0002, code); PutInteger4(token1, 0x0009, code); PutInteger4(token2, 0x000e, code); PutInteger4(token3, 0x0015, code); PutInteger4(token2, 0x001a, code); PutInteger4(token4, 0x0020, code); PutInteger4(token5, 0x0028, code); PutInteger4(token6, 0x0033, code); PutInteger4(token7, 0x003c, code); PutInteger4(token8, 0x0045, code); PutInteger4(token9, 0x005f, code); dynamicILInfo.SetCode(code, 2); byte[] exceptions = { 0x41, 0x1c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; dynamicILInfo.SetExceptions(exceptions); string ret = (string)dynamicMethod.Invoke(null, null); Assert.Equal(ret, ContactString()); }
/// <summary> /// Resolves the tokens given the code bytes and DynamicILInfo class /// </summary> /// <param name="code"></param> /// <param name="dynamicInfo"></param> /// <returns>byte[] - code bytes with resolved tokens</returns> public byte[] ResolveCodeTokens(byte[] code, DynamicILInfo dynamicInfo) { byte[] resolvedCode = new byte[code.Length]; //copy code bytes Array.Copy(code, resolvedCode, code.Length); //resolve fields foreach (int offset in m_fields.Keys) { int newMetadataToken = dynamicInfo.GetTokenFor(m_fields[offset]); OverwriteInt32(resolvedCode, offset, newMetadataToken); } //resolve methods foreach (int offset in m_methods.Keys) { int newMetadataToken; MethodBase methodBase; methodBase = m_methods[offset]; //generic types require the declaring type when resolving if (methodBase.DeclaringType != null && methodBase.DeclaringType.IsGenericType) { newMetadataToken = dynamicInfo.GetTokenFor(methodBase.MethodHandle, methodBase.DeclaringType.TypeHandle); } else { newMetadataToken = dynamicInfo.GetTokenFor(methodBase.MethodHandle); } OverwriteInt32(resolvedCode, offset, newMetadataToken); } //resolve types foreach (int offset in m_types.Keys) { int newMetadataToken = dynamicInfo.GetTokenFor(m_types[offset]); OverwriteInt32(resolvedCode, offset, newMetadataToken); } //resolve strings foreach (int offset in m_literalStrings.Keys) { int newMetadataToken = dynamicInfo.GetTokenFor(m_literalStrings[offset]); OverwriteInt32(resolvedCode, offset, newMetadataToken); } return(resolvedCode); }
internal static void _EmitCallSite(DynamicMethod dm, ILGenerator il, System.Reflection.Emit.OpCode opcode, CallSite csite) { /* The mess in this method is heavily based off of the code available at the following links: * https://github.com/Microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/reflection/emit/dynamicmethod.cs#L791 * https://github.com/Microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/reflection/emit/dynamicilgenerator.cs#L353 * https://github.com/mono/mono/blob/82e573122a55482bf6592f36f819597238628385/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs#L411 * https://github.com/mono/mono/blob/82e573122a55482bf6592f36f819597238628385/mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs#L800 * https://github.com/dotnet/coreclr/blob/0fbd855e38bc3ec269479b5f6bf561dcfd67cbb6/src/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs#L57 */ List<object> _tokens = null; int _GetTokenForType(Type v) { _tokens.Add(v.TypeHandle); return _tokens.Count - 1 | 0x02000000 /* (int) MetadataTokenType.TypeDef */; } int _GetTokenForSig(byte[] v) { _tokens.Add(v); return _tokens.Count - 1 | 0x11000000 /* (int) MetadataTokenType.Signature */; } #if !NETSTANDARD DynamicILInfo _info = null; if (DynamicMethodDefinition._IsMono) { // GetDynamicILInfo throws "invalid signature" in .NET - let's hope for the best for mono... _info = dm.GetDynamicILInfo(); } else { #endif // For .NET, we need to access DynamicScope m_scope and its List<object> m_tokens _tokens = f_DynScope_m_tokens.GetValue(f_DynILGen_m_scope.GetValue(il)) as List<object>; #if !NETSTANDARD } int GetTokenForType(Type v) => _info != null ? _info.GetTokenFor(v.TypeHandle) : _GetTokenForType(v); int GetTokenForSig(byte[] v) => _info != null ? _info.GetTokenFor(v) : _GetTokenForSig(v); #else int GetTokenForType(Type v) => _GetTokenForType(v); int GetTokenForSig(byte[] v) => _GetTokenForSig(v); #endif byte[] signature = new byte[32]; int currSig = 0; int sizeLoc = -1; // This expects a MdSigCallingConvention AddData((byte) csite.CallingConvention); sizeLoc = currSig++; List<Type> modReq = new List<Type>(); List<Type> modOpt = new List<Type>(); ResolveWithModifiers(csite.ReturnType, out Type returnType, out Type[] returnTypeModReq, out Type[] returnTypeModOpt, modReq, modOpt);
public override void VisitInlineMethodInstruction(InlineMethodInstruction inlineMethodInstruction) { OverwriteInt32(_ilInfo.GetTokenFor( inlineMethodInstruction.Method.MethodHandle, inlineMethodInstruction.Method.DeclaringType.TypeHandle), inlineMethodInstruction.Offset + inlineMethodInstruction.OpCode.Size); }
public void Test_TwoDimTest() { // 2-D array (set/address/get) DynamicMethod dynamicMethod = new DynamicMethod(nameof(TwoDimTest), typeof(int), Type.EmptyTypes, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(System.Int32[, ]), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(bool), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x1c, 0x0a, 0x1e, 0x0b, 0x06, 0x07, 0x73, 0x3e, 0x00, 0x00, 0x0a, 0x0c, 0x16, 0x0d, 0x2b, 0x27, 0x16, 0x13, 0x04, 0x2b, 0x13, 0x08, 0x09, 0x11, 0x04, 0x09, 0x11, 0x04, 0x5a, 0x28, 0x3f, 0x00, 0x00, 0x0a, 0x11, 0x04, 0x17, 0x58, 0x13, 0x04, 0x11, 0x04, 0x07, 0xfe, 0x04, 0x13, 0x06, 0x11, 0x06, 0x2d, 0xe2, 0x09, 0x17, 0x58, 0x0d, 0x09, 0x06, 0xfe, 0x04, 0x13, 0x06, 0x11, 0x06, 0x2d, 0xcf, 0x17, 0x0d, 0x2b, 0x3c, 0x17, 0x13, 0x04, 0x2b, 0x28, 0x08, 0x09, 0x11, 0x04, 0x28, 0x40, 0x00, 0x00, 0x0a, 0x25, 0x71, 0x1f, 0x00, 0x00, 0x01, 0x08, 0x09, 0x17, 0x59, 0x11, 0x04, 0x17, 0x59, 0x28, 0x41, 0x00, 0x00, 0x0a, 0x58, 0x81, 0x1f, 0x00, 0x00, 0x01, 0x11, 0x04, 0x17, 0x58, 0x13, 0x04, 0x11, 0x04, 0x07, 0xfe, 0x04, 0x13, 0x06, 0x11, 0x06, 0x2d, 0xcd, 0x09, 0x17, 0x58, 0x0d, 0x09, 0x06, 0xfe, 0x04, 0x13, 0x06, 0x11, 0x06, 0x2d, 0xba, 0x08, 0x06, 0x17, 0x59, 0x07, 0x17, 0x59, 0x28, 0x41, 0x00, 0x00, 0x0a, 0x13, 0x05, 0x2b, 0x00, 0x11, 0x05, 0x2a }; int token0 = dynamicILInfo.GetTokenFor(typeof(System.Int32[, ]).GetConstructor(new Type[] { typeof(int), typeof(int) }).MethodHandle); int token1 = dynamicILInfo.GetTokenFor(typeof(System.Int32[, ]).GetMethod("Set").MethodHandle); int token2 = dynamicILInfo.GetTokenFor(typeof(System.Int32[, ]).GetMethod("Address").MethodHandle); int token3 = dynamicILInfo.GetTokenFor(typeof(int).TypeHandle); int token4 = dynamicILInfo.GetTokenFor(typeof(System.Int32[, ]).GetMethod("Get").MethodHandle); PutInteger4(token0, 0x0008, code); PutInteger4(token1, 0x001f, code); PutInteger4(token2, 0x0050, code); PutInteger4(token3, 0x0056, code); PutInteger4(token4, 0x0063, code); PutInteger4(token3, 0x0069, code); PutInteger4(token4, 0x0094, code); dynamicILInfo.SetCode(code, 6); int ret = (int)dynamicMethod.Invoke(null, null); Assert.Equal(ret, TwoDimTest()); }
public void GetTokenFor_DynamicMethod_Success() { // Calling DynamicMethod recursively DynamicMethod dynamicMethod = new DynamicMethod(nameof(Fib), typeof(long), new Type[] { typeof(long) }, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(long), false); sigHelper.AddArgument(typeof(bool), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x02, 0x16, 0x6a, 0x2e, 0x0a, 0x02, 0x17, 0x6a, 0xfe, 0x01, 0x16, 0xfe, 0x01, 0x2b, 0x01, 0x16, 0x0b, 0x07, 0x2d, 0x04, 0x02, 0x0a, 0x2b, 0x16, 0x02, 0x17, 0x6a, 0x59, 0x28, 0x02, 0x00, 0x00, 0x06, 0x02, 0x18, 0x6a, 0x59, 0x28, 0x02, 0x00, 0x00, 0x06, 0x58, 0x0a, 0x2b, 0x00, 0x06, 0x2a }; int token0 = dynamicILInfo.GetTokenFor(dynamicMethod); PutInteger4(token0, 0x001e, code); PutInteger4(token0, 0x0027, code); dynamicILInfo.SetCode(code, 3); long ret = (long)dynamicMethod.Invoke(null, new object[] { 20 }); Assert.Equal(ret, Fib(20)); }
public void GetTokenFor_Type() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(Type), Type.EmptyTypes, typeof(DynamicILInfoTest), false); DynamicILInfo il = dm.GetDynamicILInfo(); byte[] code = { 0x00, 0xd0, 0x01, 0x00, 0x00, 0x70, 0x28, 0x04, 0x00, 0x00, 0x0a, 0x00, 0x2a }; int token0 = il.GetTokenFor(typeof(int).TypeHandle); int token1 = il.GetTokenFor(typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }).MethodHandle); PutInteger4(token0, 0x0002, code); PutInteger4(token1, 0x0007, code); il.SetCode(code, 8); var res = dm.Invoke(null, null); Assert.AreEqual(typeof(int), res); }
public void GetTokenFor_Method() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(string), Type.EmptyTypes, typeof(DynamicILInfoTest), false); DynamicILInfo il = dm.GetDynamicILInfo(); // ldstr "ABCD"; call string::ToLower (); ret byte[] code = { 0x00, 0x72, 0x01, 0x00, 0x00, 0x70, 0x28, 0x04, 0x00, 0x00, 0x0a, 0x00, 0x2a }; int token0 = il.GetTokenFor("ABCD"); int token1 = il.GetTokenFor(typeof(string).GetMethod("ToLower", Type.EmptyTypes).MethodHandle); PutInteger4(token0, 0x0002, code); PutInteger4(token1, 0x0007, code); il.SetCode(code, 8); var res = dm.Invoke(null, null); Assert.AreEqual("abcd", res); }
// Token: 0x060000FE RID: 254 RVA: 0x0000AAF8 File Offset: 0x00008CF8 private unsafe static void c8619f80da50369e47fcfd41a1f31ff9b(ref int ca0c61e7592f10963057a6d5e207fa679, DynamicILInfo c3c57c9acc0a08dbaa5fcc9490f2a3eac) { int num = BitConverter.ToInt32(c112201421a408a8f2963cee12a5d2e69.c271a832e629a79991d9eda7a270cb125, ca0c61e7592f10963057a6d5e207fa679); ca0c61e7592f10963057a6d5e207fa679 += 4; if (num == 0) { for (;;) { switch (2) { case 0: continue; } break; } if (!true) { RuntimeMethodHandle runtimeMethodHandle = methodof(c112201421a408a8f2963cee12a5d2e69.c8619f80da50369e47fcfd41a1f31ff9b(int *, DynamicILInfo)).MethodHandle; } return; } byte[] array = c4cbbd90ed4559089f2970be8fc52599d.cad714a49573fd585a8ab14c80a23536b(num); Buffer.BlockCopy(c112201421a408a8f2963cee12a5d2e69.c271a832e629a79991d9eda7a270cb125, ca0c61e7592f10963057a6d5e207fa679, array, 0, num); int num2 = 4; int num3 = (num - 4) / 24; for (int i = 0; i < num3; i++) { ExceptionHandlingClauseOptions exceptionHandlingClauseOptions = (ExceptionHandlingClauseOptions)BitConverter.ToInt32(array, num2); num2 += 20; switch (exceptionHandlingClauseOptions) { case ExceptionHandlingClauseOptions.Clause: { RuntimeTypeHandle type = c112201421a408a8f2963cee12a5d2e69.c5b2cbb035f512aa824f5593dd0096224.ResolveTypeHandle(BitConverter.ToInt32(array, num2)); int tokenFor = c3c57c9acc0a08dbaa5fcc9490f2a3eac.GetTokenFor(type); c112201421a408a8f2963cee12a5d2e69.c080978af586a672599ee810498652c16(tokenFor, num2, array); break; } case ExceptionHandlingClauseOptions.Fault: throw new NotSupportedException("dynamic method does not support fault clause"); } num2 += 4; } for (;;) { switch (2) { case 0: continue; } break; } c3c57c9acc0a08dbaa5fcc9490f2a3eac.SetExceptions(array); }
private static void SetExceptions(MethodBody body, DynamicILInfo ilInfo) { IList <ExceptionHandlingClause> ehcs = body.ExceptionHandlingClauses; int ehCount = ehcs.Count; if (ehCount == 0) { return; } // Let us do FAT exception header int size = 4 + 24 * ehCount; byte[] exceptions = new byte[size]; exceptions[0] = 0x01 | 0x40; //Offset: 0, Kind: CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat OverwriteInt32(size, 1, exceptions); // Offset: 1, DataSize: n * 24 + 4 int pos = 4; foreach (ExceptionHandlingClause ehc in ehcs) { // // Flags, TryOffset, TryLength, HandlerOffset, HandlerLength, // OverwriteInt32((int)ehc.Flags, pos, exceptions); pos += 4; OverwriteInt32(ehc.TryOffset, pos, exceptions); pos += 4; OverwriteInt32(ehc.TryLength, pos, exceptions); pos += 4; OverwriteInt32(ehc.HandlerOffset, pos, exceptions); pos += 4; OverwriteInt32(ehc.HandlerLength, pos, exceptions); pos += 4; // // ClassToken or FilterOffset // switch (ehc.Flags) { case ExceptionHandlingClauseOptions.Clause: int token = ilInfo.GetTokenFor(ehc.CatchType.TypeHandle); OverwriteInt32(token, pos, exceptions); break; case ExceptionHandlingClauseOptions.Filter: OverwriteInt32(ehc.FilterOffset, pos, exceptions); break; case ExceptionHandlingClauseOptions.Fault: throw new NotSupportedException("dynamic method does not support fault clause"); case ExceptionHandlingClauseOptions.Finally: break; } pos += 4; } ilInfo.SetExceptions(exceptions); }
static void HelloFromDynamicILInfo() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(void), Type.EmptyTypes, typeof(Foo), false); DynamicILInfo il = dm.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); il.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { /* ldstr */ 0x72, 0x00, 0x00, 0x00, 0x00, /* call */ 0x28, 0x00, 0x00, 0x00, 0x00, /* ret */ 0x2a }; byte[] strTokenBytes = BitConverter.GetBytes(il.GetTokenFor("Hello world!")); var writeLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); byte[] mTokenBytes = BitConverter.GetBytes(il.GetTokenFor(writeLine.MethodHandle)); Array.Copy(strTokenBytes, 0, code, 1, strTokenBytes.Length); Array.Copy(mTokenBytes, 0, code, 5, mTokenBytes.Length); il.SetCode(code, 3); var hello = (Action)dm.CreateDelegate(typeof(Action)); }
/// <inheritdoc/> public override EntityHandle getHandle(Type type) { if (m_tokenCache.tryGetValue(type, out int token)) { return(MetadataTokens.EntityHandle(token)); } token = m_dynamicILInfo.GetTokenFor(type.TypeHandle); m_tokenCache[type] = token; return(MetadataTokens.EntityHandle(token)); }
public void GetTokenFor_String() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(string), Type.EmptyTypes, typeof(DynamicILInfoTest), false); DynamicILInfo il = dm.GetDynamicILInfo(); byte[] code = { 0x00, 0x72, 0x01, 0x00, 0x00, 0x70, 0x2a }; int token0 = il.GetTokenFor("ABCD"); PutInteger4(token0, 0x0002, code); il.SetCode(code, 8); var res = dm.Invoke(null, null); Assert.AreEqual("ABCD", res); }
public void GetTokenFor_DynamicMethod() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(RuntimeMethodHandle), Type.EmptyTypes, typeof(DynamicILInfoTest), false); DynamicILInfo il = dm.GetDynamicILInfo(); byte[] code = { 0x00, 0xd0, 0x01, 0x00, 0x00, 0x70, 0x2a }; int token0 = il.GetTokenFor(dm); PutInteger4(token0, 0x0002, code); il.SetCode(code, 8); var res = dm.Invoke(null, null); Assert.AreEqual(dm.MethodHandle, res); }
public void GetTokenFor_Exception_Success() { DynamicMethod dynamicMethod = new DynamicMethod(nameof(ExceptionTest), typeof(int), Type.EmptyTypes, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(string), false); sigHelper.AddArgument(typeof(int), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x16, 0x0a, 0x00, 0x00, 0x16, 0x0b, 0x17, 0x07, 0x5b, 0x0c, 0x00, 0xde, 0x09, 0x26, 0x00, 0x06, 0x17, 0x58, 0x0a, 0x00, 0xde, 0x00, 0x00, 0x00, 0x72, 0xed, 0x01, 0x00, 0x70, 0x17, 0x28, 0x32, 0x00, 0x00, 0x0a, 0x26, 0x00, 0xde, 0x09, 0x26, 0x00, 0x06, 0x17, 0x58, 0x0a, 0x00, 0xde, 0x00, 0x00, 0x14, 0x0d, 0x09, 0x6f, 0x05, 0x00, 0x00, 0x0a, 0x26, 0x00, 0xde, 0x09, 0x26, 0x00, 0x06, 0x17, 0x58, 0x0a, 0x00, 0xde, 0x00, 0x00, 0xde, 0x07, 0x00, 0x06, 0x18, 0x58, 0x0a, 0x00, 0xdc, 0x00, 0x06, 0x13, 0x04, 0x2b, 0x00, 0x11, 0x04, 0x2a }; int token0 = dynamicILInfo.GetTokenFor("A.B"); int token1 = dynamicILInfo.GetTokenFor(typeof(System.Type).GetMethod("GetType", new Type[] { typeof(string), typeof(bool) }).MethodHandle); int token2 = dynamicILInfo.GetTokenFor(typeof(string).GetMethod("ToUpper", Type.EmptyTypes).MethodHandle); PutInteger4(token0, 0x001a, code); PutInteger4(token1, 0x0020, code); PutInteger4(token2, 0x0036, code); dynamicILInfo.SetCode(code, 2); int token3 = dynamicILInfo.GetTokenFor(typeof(System.Object).TypeHandle); int token4 = dynamicILInfo.GetTokenFor(typeof(System.Exception).TypeHandle); int token5 = dynamicILInfo.GetTokenFor(typeof(System.NullReferenceException).TypeHandle); byte[] exceptions = { 0x41, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; PutInteger4(token3, 0x0018, exceptions); PutInteger4(token4, 0x0030, exceptions); PutInteger4(token5, 0x0048, exceptions); dynamicILInfo.SetExceptions(exceptions); int ret = (int)dynamicMethod.Invoke(null, null); Assert.Equal(ret, ExceptionTest()); }
public void GetTokenFor_IntGenerics_Success() { DynamicMethod dynamicMethod = new DynamicMethod(nameof(SumInteger), typeof(int), new Type[] { }, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(MyList <int>), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(System.Collections.Generic.IEnumerator <int>), false); sigHelper.AddArgument(typeof(bool), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x73, 0x1c, 0x00, 0x00, 0x0a, 0x0a, 0x06, 0x1f, 0x64, 0x6f, 0x1d, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x20, 0xc8, 0x00, 0x00, 0x00, 0x6f, 0x1d, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x20, 0x2c, 0x01, 0x00, 0x00, 0x6f, 0x1d, 0x00, 0x00, 0x0a, 0x00, 0x16, 0x0b, 0x00, 0x06, 0x6f, 0x1e, 0x00, 0x00, 0x0a, 0x13, 0x04, 0x2b, 0x0e, 0x11, 0x04, 0x6f, 0x1f, 0x00, 0x00, 0x0a, 0x0c, 0x00, 0x07, 0x08, 0x58, 0x0b, 0x00, 0x11, 0x04, 0x6f, 0x20, 0x00, 0x00, 0x0a, 0x13, 0x05, 0x11, 0x05, 0x2d, 0xe5, 0xde, 0x14, 0x11, 0x04, 0x14, 0xfe, 0x01, 0x13, 0x05, 0x11, 0x05, 0x2d, 0x08, 0x11, 0x04, 0x6f, 0x21, 0x00, 0x00, 0x0a, 0x00, 0xdc, 0x00, 0x07, 0x0d, 0x2b, 0x00, 0x09, 0x2a }; int token0 = dynamicILInfo.GetTokenFor(typeof(MyList <int>).GetConstructors()[0].MethodHandle, typeof(MyList <int>).TypeHandle); int token1 = dynamicILInfo.GetTokenFor(typeof(MyList <int>).GetMethod("Add").MethodHandle, typeof(MyList <int>).TypeHandle); int token2 = dynamicILInfo.GetTokenFor(typeof(MyList <int>).GetMethod("GetEnumerator").MethodHandle, typeof(MyList <int>).TypeHandle); int token3 = dynamicILInfo.GetTokenFor(typeof(System.Collections.Generic.IEnumerator <int>).GetMethod("get_Current").MethodHandle, typeof(System.Collections.Generic.IEnumerator <int>).TypeHandle); int token4 = dynamicILInfo.GetTokenFor(typeof(System.Collections.IEnumerator).GetMethod("MoveNext").MethodHandle); int token5 = dynamicILInfo.GetTokenFor(typeof(System.IDisposable).GetMethod("Dispose").MethodHandle); PutInteger4(token0, 0x0002, code); PutInteger4(token1, 0x000b, code); PutInteger4(token1, 0x0017, code); PutInteger4(token1, 0x0023, code); PutInteger4(token2, 0x002d, code); PutInteger4(token3, 0x0038, code); PutInteger4(token4, 0x0046, code); PutInteger4(token5, 0x0060, code); dynamicILInfo.SetCode(code, 2); byte[] exceptions = { 0x41, 0x1c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; dynamicILInfo.SetExceptions(exceptions); int ret = (int)dynamicMethod.Invoke(null, null); Assert.Equal(ret, SumInteger()); }
public void GetTokenFor_FieldInfo() { aField = aField + 1; DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(RuntimeFieldHandle), Type.EmptyTypes, typeof(DynamicILInfoTest), false); DynamicILInfo il = dm.GetDynamicILInfo(); var f = typeof(DynamicILInfoTest).GetField("aField", BindingFlags.Static | BindingFlags.NonPublic).FieldHandle; byte[] code = { 0x00, 0xd0, 0x01, 0x00, 0x00, 0x70, 0x2a }; int token0 = il.GetTokenFor(f); PutInteger4(token0, 0x0002, code); il.SetCode(code, 8); var res = dm.Invoke(null, null); Assert.AreEqual(f, res); }
public void GetTokenFor_CtorMethodAndField_Success() { DynamicMethod dynamicMethod = new DynamicMethod(nameof(Mock), typeof(Person), new Type[] { }, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(Person), false); sigHelper.AddArgument(typeof(Person), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x72, 0x49, 0x00, 0x00, 0x70, 0x1f, 0x32, 0x22, 0x00, 0x60, 0xea, 0x46, 0x73, 0x0f, 0x00, 0x00, 0x06, 0x0a, 0x06, 0x72, 0x53, 0x00, 0x00, 0x70, 0x7d, 0x04, 0x00, 0x00, 0x04, 0x06, 0x25, 0x6f, 0x0c, 0x00, 0x00, 0x06, 0x17, 0x58, 0x6f, 0x0d, 0x00, 0x00, 0x06, 0x00, 0x06, 0x22, 0x00, 0x00, 0x96, 0x43, 0x6f, 0x10, 0x00, 0x00, 0x06, 0x00, 0x06, 0x0b, 0x2b, 0x00, 0x07, 0x2a }; int token0 = dynamicILInfo.GetTokenFor("Bill"); int token1 = dynamicILInfo.GetTokenFor(typeof(Person).GetConstructor(new Type[] { typeof(string), typeof(int), typeof(float) }).MethodHandle); int token2 = dynamicILInfo.GetTokenFor("Bill Gates"); int token3 = dynamicILInfo.GetTokenFor(typeof(Person).GetField("m_name").FieldHandle); int token4 = dynamicILInfo.GetTokenFor(typeof(Person).GetMethod("get_Age").MethodHandle); int token5 = dynamicILInfo.GetTokenFor(typeof(Person).GetMethod("set_Age").MethodHandle); int token6 = dynamicILInfo.GetTokenFor(typeof(Person).GetMethod("IncSalary").MethodHandle); PutInteger4(token0, 0x0002, code); PutInteger4(token1, 0x000e, code); PutInteger4(token2, 0x0015, code); PutInteger4(token3, 0x001a, code); PutInteger4(token4, 0x0021, code); PutInteger4(token5, 0x0028, code); PutInteger4(token6, 0x0034, code); dynamicILInfo.SetCode(code, 4); Person ret = (Person)dynamicMethod.Invoke(null, null); Assert.Equal(ret, Mock()); }
internal static void EmitCallSite(DynamicMethod dm, ILGenerator il, System.Reflection.Emit.OpCode opcode, CallSite csite) { /* The mess in this method is heavily based off of the code available at the following links: * https://github.com/Microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/reflection/emit/dynamicmethod.cs#L791 * https://github.com/Microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/reflection/emit/dynamicilgenerator.cs#L353 * https://github.com/mono/mono/blob/82e573122a55482bf6592f36f819597238628385/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs#L411 * https://github.com/mono/mono/blob/82e573122a55482bf6592f36f819597238628385/mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs#L800 * https://github.com/dotnet/coreclr/blob/0fbd855e38bc3ec269479b5f6bf561dcfd67cbb6/src/System.Private.CoreLib/src/System/Reflection/Emit/SignatureHelper.cs#L57 */ List<object> _tokens = null; int _GetTokenForType(Type v) { _tokens.Add(v.TypeHandle); return _tokens.Count - 1 | 0x02000000 /* (int) MetadataTokenType.TypeDef */; } int _GetTokenForSig(byte[] v) { _tokens.Add(v); return _tokens.Count - 1 | 0x11000000 /* (int) MetadataTokenType.Signature */; } #if !NETSTANDARD DynamicILInfo _info = null; if (Type.GetType("Mono.Runtime") != null) { // GetDynamicILInfo throws "invalid signature" in .NET - let's hope for the best for mono... _info = dm.GetDynamicILInfo(); } else { #endif // For .NET, we need to access DynamicScope m_scope and its List<object> m_tokens _tokens = f_DynScope_m_tokens.GetValue(f_DynILGen_m_scope.GetValue(il)) as List<object>; #if !NETSTANDARD } int GetTokenForType(Type v) => _info != null ? _info.GetTokenFor(v.TypeHandle) : _GetTokenForType(v); int GetTokenForSig(byte[] v) => _info != null ? _info.GetTokenFor(v) : _GetTokenForSig(v); #else int GetTokenForType(Type v) => _GetTokenForType(v); int GetTokenForSig(byte[] v) => _GetTokenForSig(v); #endif byte[] signature = new byte[32]; int currSig = 0; int sizeLoc = -1; // This expects a MdSigCallingConvention AddData((byte) csite.CallingConvention); sizeLoc = currSig++; List<Type> modReq = new List<Type>(); List<Type> modOpt = new List<Type>(); for ( TypeReference returnTypeRef = csite.ReturnType; returnTypeRef is TypeSpecification returnTypeSpec; returnTypeRef = returnTypeSpec.ElementType ) { switch (returnTypeRef) { case RequiredModifierType paramTypeModReq: modReq.Add(paramTypeModReq.ModifierType.ResolveReflection()); break; case OptionalModifierType paramTypeOptReq: modOpt.Add(paramTypeOptReq.ModifierType.ResolveReflection()); break; } } AddArgument(csite.ReturnType.ResolveReflection(), modReq.ToArray(), modOpt.ToArray()); foreach (ParameterDefinition param in csite.Parameters) { if (param.ParameterType.IsSentinel) AddElementType(0x41 /* CorElementType.Sentinel */); if (param.ParameterType.IsPinned) { AddElementType(0x45 /* CorElementType.Pinned */); // AddArgument(param.ParameterType.ResolveReflection()); // continue; } modOpt.Clear(); modReq.Clear(); for ( TypeReference paramTypeRef = param.ParameterType; paramTypeRef is TypeSpecification paramTypeSpec; paramTypeRef = paramTypeSpec.ElementType ) { switch (paramTypeRef) { case RequiredModifierType paramTypeModReq: modReq.Add(paramTypeModReq.ModifierType.ResolveReflection()); break; case OptionalModifierType paramTypeOptReq: modOpt.Add(paramTypeOptReq.ModifierType.ResolveReflection()); break; } } AddArgument(param.ParameterType.ResolveReflection(), modReq.ToArray(), modOpt.ToArray()); } AddElementType(0x00 /* CorElementType.End */); // For most signatures, this will set the number of elements in a byte which we have reserved for it. // However, if we have a field signature, we don't set the length and return. // If we have a signature with more than 128 arguments, we can't just set the number of elements, // we actually have to allocate more space (e.g. shift everything in the array one or more spaces to the // right. We do this by making a copy of the array and leaving the correct number of blanks. This new // array is now set to be m_signature and we use the AddData method to set the number of elements properly. // The forceCopy argument can be used to force SetNumberOfSignatureElements to make a copy of // the array. This is useful for GetSignature which promises to trim the array to be the correct size anyway. byte[] temp; int newSigSize; int currSigHolder = currSig; // We need to have more bytes for the size. Figure out how many bytes here. // Since we need to copy anyway, we're just going to take the cost of doing a // new allocation. if (csite.Parameters.Count < 0x80) { newSigSize = 1; } else if (csite.Parameters.Count < 0x4000) { newSigSize = 2; } else { newSigSize = 4; } // Allocate the new array. temp = new byte[currSig + newSigSize - 1]; // Copy the calling convention. The calling convention is always just one byte // so we just copy that byte. Then copy the rest of the array, shifting everything // to make room for the new number of elements. temp[0] = signature[0]; Buffer.BlockCopy(signature, sizeLoc + 1, temp, sizeLoc + newSigSize, currSigHolder - (sizeLoc + 1)); signature = temp; //Use the AddData method to add the number of elements appropriately compressed. currSig = sizeLoc; AddData(csite.Parameters.Count); currSig = currSigHolder + (newSigSize - 1); // This case will only happen if the user got the signature through // InternalGetSignature first and then called GetSignature. if (signature.Length > currSig) { temp = new byte[currSig]; Array.Copy(signature, temp, currSig); signature = temp; } // Emit. if (_ILGen_emit_int != null) { // Mono _ILGen_make_room(il, 6); _ILGen_ll_emit(il, opcode); _ILGen_emit_int(il, GetTokenForSig(signature)); } else { // .NET _ILGen_EnsureCapacity(il, 7); _ILGen_InternalEmit(il, opcode); // The only IL instruction that has VarPop behaviour, that takes a // Signature token as a parameter is calli. Pop the parameters and // the native function pointer. To be conservative, do not pop the // this pointer since this information is not easily derived from // SignatureHelper. if (opcode.StackBehaviourPop == System.Reflection.Emit.StackBehaviour.Varpop) { // Pop the arguments and native function pointer off the stack. _ILGen_UpdateStackSize(il, opcode, -csite.Parameters.Count - 1); } _ILGen_PutInteger4(il, GetTokenForSig(signature)); } void AddArgument(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) { if (optionalCustomModifiers != null) foreach (Type t in optionalCustomModifiers) InternalAddTypeToken(GetTokenForType(t), 0x20 /* CorElementType.CModOpt */); if (requiredCustomModifiers != null) foreach (Type t in requiredCustomModifiers) InternalAddTypeToken(GetTokenForType(t), 0x1F /* CorElementType.CModReqd */); AddOneArgTypeHelper(clsArgument); } void AddData(int data) { // A managed representation of CorSigCompressData; if (currSig + 4 > signature.Length) { signature = ExpandArray(signature); } if (data <= 0x7F) { signature[currSig++] = (byte) (data & 0xFF); } else if (data <= 0x3FFF) { signature[currSig++] = (byte) ((data >> 8) | 0x80); signature[currSig++] = (byte) (data & 0xFF); } else if (data <= 0x1FFFFFFF) { signature[currSig++] = (byte) ((data >> 24) | 0xC0); signature[currSig++] = (byte) ((data >> 16) & 0xFF); signature[currSig++] = (byte) ((data >> 8) & 0xFF); signature[currSig++] = (byte) ((data) & 0xFF); } else { throw new ArgumentException("Integer or token was too large to be encoded."); } } byte[] ExpandArray(byte[] inArray, int requiredLength = -1) { if (requiredLength < inArray.Length) requiredLength = inArray.Length * 2; byte[] outArray = new byte[requiredLength]; Buffer.BlockCopy(inArray, 0, outArray, 0, inArray.Length); return outArray; } void AddElementType(byte cvt) { // Adds an element to the signature. A managed represenation of CorSigCompressElement if (currSig + 1 > signature.Length) signature = ExpandArray(signature); signature[currSig++] = cvt; } void AddToken(int token) { // A managed represenation of CompressToken // Pulls the token appart to get a rid, adds some appropriate bits // to the token and then adds this to the signature. int rid = (token & 0x00FFFFFF); //This is RidFromToken; int type = (token & unchecked((int) 0xFF000000)); //This is TypeFromToken; if (rid > 0x3FFFFFF) { // token is too big to be compressed throw new ArgumentException("Integer or token was too large to be encoded."); } rid = (rid << 2); // TypeDef is encoded with low bits 00 // TypeRef is encoded with low bits 01 // TypeSpec is encoded with low bits 10 if (type == 0x01000000 /* MetadataTokenType.TypeRef */) { //if type is mdtTypeRef rid |= 0x1; } else if (type == 0x1b000000 /* MetadataTokenType.TypeSpec */) { //if type is mdtTypeSpec rid |= 0x2; } AddData(rid); } void InternalAddTypeToken(int clsToken, byte CorType) { // Add a type token into signature. CorType will be either CorElementType.Class or CorElementType.ValueType AddElementType(CorType); AddToken(clsToken); } void AddOneArgTypeHelper(Type clsArgument) { AddOneArgTypeHelperWorker(clsArgument, false); } void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst) { if (clsArgument.GetTypeInfo().IsGenericType && (!clsArgument.GetTypeInfo().IsGenericTypeDefinition || !lastWasGenericInst)) { AddElementType(0x15 /* CorElementType.GenericInst */); AddOneArgTypeHelperWorker(clsArgument.GetGenericTypeDefinition(), true); Type[] genargs = clsArgument.GetGenericArguments(); AddData(genargs.Length); foreach (Type t in genargs) AddOneArgTypeHelper(t); } else if (clsArgument.IsByRef) { AddElementType(0x10 /* CorElementType.ByRef */); clsArgument = clsArgument.GetElementType(); AddOneArgTypeHelper(clsArgument); } else if (clsArgument.IsPointer) { AddElementType(0x0F /* CorElementType.Ptr */); AddOneArgTypeHelper(clsArgument.GetElementType()); } else if (clsArgument.IsArray) { #if false if (clsArgument.IsArray && clsArgument == clsArgument.GetElementType().MakeArrayType()) { // .IsSZArray unavailable. AddElementType(0x1D /* CorElementType.SzArray */); AddOneArgTypeHelper(clsArgument.GetElementType()); } else #endif { AddElementType(0x14 /* CorElementType.Array */); AddOneArgTypeHelper(clsArgument.GetElementType()); // put the rank information int rank = clsArgument.GetArrayRank(); AddData(rank); // rank AddData(0); // upper bounds AddData(rank); // lower bound for (int i = 0; i < rank; i++) AddData(0); } } else { // This isn't 100% accurate, but... oh well. byte type = 0; // 0 is reserved anyway. for (int i = 0; i < CorElementTypes.Length; i++) { if (clsArgument == CorElementTypes[i]) { type = (byte) i; break; } } if (type == 0) { if (clsArgument == typeof(object)) { type = 0x1C /* CorElementType.Object */; } else if (clsArgument.GetTypeInfo().IsValueType) { type = 0x11 /* CorElementType.ValueType */; } else { // Let's hope for the best. type = 0x12 /* CorElementType.Class */; } } if (type <= 0x0E /* CorElementType.String */ || type == 0x16 /* CorElementType.TypedByRef */ || type == 0x18 /* CorElementType.I */ || type == 0x19 /* CorElementType.U */ || type == 0x1C /* CorElementType.Object */ ) { AddElementType(type); } else if (clsArgument.GetTypeInfo().IsValueType) { InternalAddTypeToken(GetTokenForType(clsArgument), 0x11 /* CorElementType.ValueType */); } else { InternalAddTypeToken(GetTokenForType(clsArgument), 0x12 /* CorElementType.Class */); } } } }
public void Test_GenericMethod() { DynamicMethod dynamicMethod = new DynamicMethod(nameof(GenericMethod), typeof(bool), Type.EmptyTypes, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(System.Int32[]), false); sigHelper.AddArgument(typeof(int), false); sigHelper.AddArgument(typeof(System.String[]), false); sigHelper.AddArgument(typeof(string), false); sigHelper.AddArgument(typeof(bool), false); sigHelper.AddArgument(typeof(System.String[]), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x1c, 0x8d, 0x1f, 0x00, 0x00, 0x01, 0x0a, 0x06, 0x16, 0x18, 0x9e, 0x06, 0x17, 0x1f, 0x09, 0x9e, 0x06, 0x18, 0x15, 0x9e, 0x06, 0x19, 0x1f, 0x0e, 0x9e, 0x06, 0x1a, 0x19, 0x9e, 0x06, 0x1b, 0x1f, 0x37, 0x9e, 0x06, 0x14, 0xfe, 0x06, 0x12, 0x00, 0x00, 0x06, 0x73, 0x3a, 0x00, 0x00, 0x0a, 0x28, 0x06, 0x00, 0x00, 0x2b, 0x0b, 0x1b, 0x8d, 0x0e, 0x00, 0x00, 0x01, 0x13, 0x05, 0x11, 0x05, 0x16, 0x72, 0x85, 0x02, 0x00, 0x70, 0xa2, 0x11, 0x05, 0x17, 0x72, 0x91, 0x02, 0x00, 0x70, 0xa2, 0x11, 0x05, 0x18, 0x72, 0x95, 0x02, 0x00, 0x70, 0xa2, 0x11, 0x05, 0x19, 0x72, 0xa1, 0x02, 0x00, 0x70, 0xa2, 0x11, 0x05, 0x1a, 0x72, 0xbd, 0x02, 0x00, 0x70, 0xa2, 0x11, 0x05, 0x0c, 0x08, 0x73, 0x18, 0x00, 0x00, 0x06, 0xfe, 0x06, 0x13, 0x00, 0x00, 0x06, 0x73, 0x3b, 0x00, 0x00, 0x0a, 0x28, 0x07, 0x00, 0x00, 0x2b, 0x0d, 0x07, 0x06, 0x19, 0x94, 0x33, 0x0b, 0x09, 0x08, 0x19, 0x9a, 0x28, 0x3c, 0x00, 0x00, 0x0a, 0x2b, 0x01, 0x16, 0x13, 0x04, 0x2b, 0x00, 0x11, 0x04, 0x2a }; int token0 = dynamicILInfo.GetTokenFor(typeof(int).TypeHandle); int token1 = dynamicILInfo.GetTokenFor(typeof(DynamicILInfoTests).GetMethod("MyRule", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle); int token2 = dynamicILInfo.GetTokenFor(typeof(Satisfy <int>).GetConstructor(new Type[] { typeof(System.Object), typeof(System.IntPtr) }).MethodHandle, typeof(Satisfy <int>).TypeHandle); int token3 = dynamicILInfo.GetTokenFor(typeof(Finder).GetMethod("Find").MakeGenericMethod(typeof(int)).MethodHandle); int token4 = dynamicILInfo.GetTokenFor(typeof(string).TypeHandle); int token5 = dynamicILInfo.GetTokenFor("Hello"); int token6 = dynamicILInfo.GetTokenFor("1"); int token7 = dynamicILInfo.GetTokenFor("world"); int token8 = dynamicILInfo.GetTokenFor("dynamicmethod"); int token9 = dynamicILInfo.GetTokenFor("find it already"); int token10 = dynamicILInfo.GetTokenFor(typeof(DynamicILInfoTests).GetConstructor(Type.EmptyTypes).MethodHandle); int token11 = dynamicILInfo.GetTokenFor(typeof(DynamicILInfoTests).GetMethod("MyRule", BindingFlags.NonPublic | BindingFlags.Instance).MethodHandle); int token12 = dynamicILInfo.GetTokenFor(typeof(Satisfy <string>).GetConstructor(new Type[] { typeof(System.Object), typeof(System.IntPtr) }).MethodHandle, typeof(Satisfy <string>).TypeHandle); int token13 = dynamicILInfo.GetTokenFor(typeof(Finder).GetMethod("Find").MakeGenericMethod(typeof(string)).MethodHandle); int token14 = dynamicILInfo.GetTokenFor(typeof(string).GetMethod("op_Equality").MethodHandle); PutInteger4(token0, 0x0003, code); PutInteger4(token1, 0x0027, code); PutInteger4(token2, 0x002c, code); PutInteger4(token3, 0x0031, code); PutInteger4(token4, 0x0038, code); PutInteger4(token5, 0x0042, code); PutInteger4(token6, 0x004b, code); PutInteger4(token7, 0x0054, code); PutInteger4(token8, 0x005d, code); PutInteger4(token9, 0x0066, code); PutInteger4(token10, 0x0070, code); PutInteger4(token11, 0x0076, code); PutInteger4(token12, 0x007b, code); PutInteger4(token13, 0x0080, code); PutInteger4(token14, 0x0090, code); dynamicILInfo.SetCode(code, 4); bool ret = (bool)dynamicMethod.Invoke(null, null); Assert.Equal(ret, GenericMethod()); }
public void Test_CallGM() { // GenericMethod inside GenericType DynamicMethod dynamicMethod = new DynamicMethod(nameof(CallGM), typeof(string), Type.EmptyTypes, typeof(DynamicILInfoTests), false); DynamicILInfo dynamicILInfo = dynamicMethod.GetDynamicILInfo(); SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper(); sigHelper.AddArgument(typeof(string), false); sigHelper.AddArgument(typeof(G <int>), false); sigHelper.AddArgument(typeof(G <string>), false); sigHelper.AddArgument(typeof(G <System.Type>), false); sigHelper.AddArgument(typeof(string), false); dynamicILInfo.SetLocalSignature(sigHelper.GetSignature()); byte[] code = { 0x00, 0x14, 0x0a, 0x73, 0x42, 0x00, 0x00, 0x0a, 0x0b, 0x06, 0x07, 0x1f, 0x64, 0x6f, 0x09, 0x00, 0x00, 0x2b, 0x28, 0x2b, 0x00, 0x00, 0x0a, 0x0a, 0x06, 0x07, 0x72, 0x5f, 0x03, 0x00, 0x70, 0x6f, 0x0a, 0x00, 0x00, 0x2b, 0x28, 0x2b, 0x00, 0x00, 0x0a, 0x0a, 0x73, 0x44, 0x00, 0x00, 0x0a, 0x0c, 0x06, 0x08, 0x1f, 0x64, 0x6f, 0x0b, 0x00, 0x00, 0x2b, 0x28, 0x2b, 0x00, 0x00, 0x0a, 0x0a, 0x06, 0x08, 0x72, 0x95, 0x02, 0x00, 0x70, 0x6f, 0x0c, 0x00, 0x00, 0x2b, 0x28, 0x2b, 0x00, 0x00, 0x0a, 0x0a, 0x73, 0x46, 0x00, 0x00, 0x0a, 0x0d, 0x06, 0x09, 0x1f, 0x64, 0x6a, 0x6f, 0x0d, 0x00, 0x00, 0x2b, 0x28, 0x2b, 0x00, 0x00, 0x0a, 0x0a, 0x06, 0x09, 0x73, 0x2c, 0x00, 0x00, 0x0a, 0x6f, 0x0e, 0x00, 0x00, 0x2b, 0x28, 0x2b, 0x00, 0x00, 0x0a, 0x0a, 0x06, 0x13, 0x04, 0x2b, 0x00, 0x11, 0x04, 0x2a }; int token0 = dynamicILInfo.GetTokenFor(typeof(G <int>).GetConstructor(Type.EmptyTypes).MethodHandle, typeof(G <int>).TypeHandle); int token1 = dynamicILInfo.GetTokenFor(typeof(G <int>).GetMethod("M").MakeGenericMethod(typeof(int)).MethodHandle, typeof(G <int>).TypeHandle); int token2 = dynamicILInfo.GetTokenFor(typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }).MethodHandle); int token3 = dynamicILInfo.GetTokenFor("hello"); int token4 = dynamicILInfo.GetTokenFor(typeof(G <int>).GetMethod("M").MakeGenericMethod(typeof(string)).MethodHandle, typeof(G <int>).TypeHandle); int token5 = dynamicILInfo.GetTokenFor(typeof(G <string>).GetConstructor(Type.EmptyTypes).MethodHandle, typeof(G <string>).TypeHandle); int token6 = dynamicILInfo.GetTokenFor(typeof(G <string>).GetMethod("M").MakeGenericMethod(typeof(int)).MethodHandle, typeof(G <string>).TypeHandle); int token7 = dynamicILInfo.GetTokenFor("world"); int token8 = dynamicILInfo.GetTokenFor(typeof(G <string>).GetMethod("M").MakeGenericMethod(typeof(string)).MethodHandle, typeof(G <string>).TypeHandle); int token9 = dynamicILInfo.GetTokenFor(typeof(G <System.Type>).GetConstructor(Type.EmptyTypes).MethodHandle, typeof(G <System.Type>).TypeHandle); int token10 = dynamicILInfo.GetTokenFor(typeof(G <System.Type>).GetMethod("M").MakeGenericMethod(typeof(long)).MethodHandle, typeof(G <System.Type>).TypeHandle); int token11 = dynamicILInfo.GetTokenFor(typeof(System.Object).GetConstructor(Type.EmptyTypes).MethodHandle); int token12 = dynamicILInfo.GetTokenFor(typeof(G <System.Type>).GetMethod("M").MakeGenericMethod(typeof(System.Object)).MethodHandle, typeof(G <System.Type>).TypeHandle); PutInteger4(token0, 0x0004, code); PutInteger4(token1, 0x000e, code); PutInteger4(token2, 0x0013, code); PutInteger4(token3, 0x001b, code); PutInteger4(token4, 0x0020, code); PutInteger4(token2, 0x0025, code); PutInteger4(token5, 0x002b, code); PutInteger4(token6, 0x0035, code); PutInteger4(token2, 0x003a, code); PutInteger4(token7, 0x0042, code); PutInteger4(token8, 0x0047, code); PutInteger4(token2, 0x004c, code); PutInteger4(token9, 0x0052, code); PutInteger4(token10, 0x005d, code); PutInteger4(token2, 0x0062, code); PutInteger4(token11, 0x006a, code); PutInteger4(token12, 0x006f, code); PutInteger4(token2, 0x0074, code); dynamicILInfo.SetCode(code, 3); string ret = (string)dynamicMethod.Invoke(null, null); Assert.Equal(ret, CallGM()); }
internal static void Initialize(RuntimeFieldHandle field, byte opKey) { FieldInfo fieldInfo = FieldInfo.GetFieldFromHandle(field); byte[] sig = fieldInfo.Module.ResolveSignature(fieldInfo.MetadataToken); int len = sig.Length; int key = fieldInfo.GetOptionalCustomModifiers()[0].MetadataToken; key += (fieldInfo.Name[Mutation.KeyI0] ^ sig[--len]) << Mutation.KeyI4; key += (fieldInfo.Name[Mutation.KeyI1] ^ sig[--len]) << Mutation.KeyI5; key += (fieldInfo.Name[Mutation.KeyI2] ^ sig[--len]) << Mutation.KeyI6; len--; key += (fieldInfo.Name[Mutation.KeyI3] ^ sig[--len]) << Mutation.KeyI7; int token = Mutation.Placeholder(key); token *= fieldInfo.GetCustomAttributes(false)[0].GetHashCode(); MethodBase method = fieldInfo.Module.ResolveMethod(token); Type delegateType = fieldInfo.FieldType; if (method.IsStatic) { fieldInfo.SetValue(null, Delegate.CreateDelegate(delegateType, (MethodInfo)method)); } else { DynamicMethod dm = null; Type[] argTypes = null; foreach (MethodInfo invoke in fieldInfo.FieldType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)) { if (invoke.DeclaringType == delegateType) { ParameterInfo[] paramTypes = invoke.GetParameters(); argTypes = new Type[paramTypes.Length]; for (int i = 0; i < argTypes.Length; i++) { argTypes[i] = paramTypes[i].ParameterType; } Type declType = method.DeclaringType; dm = new DynamicMethod("", invoke.ReturnType, argTypes, (declType.IsInterface || declType.IsArray) ? delegateType : declType, true); break; } } DynamicILInfo info = dm.GetDynamicILInfo(); info.SetLocalSignature(new byte[] { 0x7, 0x0 }); var code = new byte[(2 + 5) * argTypes.Length + 6]; int index = 0; var mParams = method.GetParameters(); int mIndex = method.IsConstructor ? 0 : -1; for (int i = 0; i < argTypes.Length; i++) { code[index++] = 0x0e; code[index++] = (byte)i; var mType = mIndex == -1 ? method.DeclaringType : mParams[mIndex].ParameterType; if (mType.IsClass && !(mType.IsPointer || mType.IsByRef)) { var cToken = info.GetTokenFor(mType.TypeHandle); code[index++] = 0x74; code[index++] = (byte)cToken; code[index++] = (byte)(cToken >> 8); code[index++] = (byte)(cToken >> 16); code[index++] = (byte)(cToken >> 24); } else { index += 5; } mIndex++; } code[index++] = (byte)((byte)fieldInfo.Name[Mutation.KeyI8] ^ opKey); int dmToken = info.GetTokenFor(method.MethodHandle); code[index++] = (byte)dmToken; code[index++] = (byte)(dmToken >> 8); code[index++] = (byte)(dmToken >> 16); code[index++] = (byte)(dmToken >> 24); code[index] = 0x2a; info.SetCode(code, argTypes.Length + 1); fieldInfo.SetValue(null, dm.CreateDelegate(delegateType)); } }