public void GetDynamicMethod() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(string), Type.EmptyTypes, typeof(DynamicILInfoTest), false); DynamicILInfo il = dm.GetDynamicILInfo(); Assert.AreEqual(dm, il.DynamicMethod); }
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_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)); }
/// <summary> /// Compiles a DynamicMethodState and returns a delegate. /// </summary> /// <typeparam name="R">The return type of the expression</typeparam> /// <typeparam name="C">The type of the function class</typeparam> /// <param name="methodState">The serialized version of a method on the functionClass</param> /// <returns>ExecuteExpression<R, C> - a delegate that calls the compiled expression</returns> public ExecuteExpression <R, C> CreateExpressionDelegate <R, C>(DynamicMethodState methodState) { //create a dynamic method var dynamicMethod = new DynamicMethod("_" + Guid.NewGuid().ToString("N"), typeof(R), new[] { typeof(C) }, typeof(C)); //get the IL writer for it DynamicILInfo dynamicInfo = dynamicMethod.GetDynamicILInfo(); //set the properties gathered from the compiled expression dynamicMethod.InitLocals = methodState.InitLocals; //set local variables SignatureHelper locals = SignatureHelper.GetLocalVarSigHelper(); foreach (int localIndex in methodState.LocalVariables.Keys) { LocalVariable localVar = methodState.LocalVariables[localIndex]; locals.AddArgument(Type.GetTypeFromHandle(localVar.LocalType), localVar.IsPinned); } dynamicInfo.SetLocalSignature(locals.GetSignature()); //resolve any metadata tokens var tokenResolver = new IlTokenResolver(methodState.TokenOffset.Fields, methodState.TokenOffset.Methods, methodState.TokenOffset.Types, methodState.TokenOffset.LiteralStrings); methodState.CodeBytes = tokenResolver.ResolveCodeTokens(methodState.CodeBytes, dynamicInfo); //set the IL code for the dynamic method dynamicInfo.SetCode(methodState.CodeBytes, methodState.MaxStackSize); //create a delegate for fast execution var expressionDelegate = (ExecuteExpression <R, C>)dynamicMethod.CreateDelegate(typeof(ExecuteExpression <R, C>)); return(expressionDelegate); }
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()); }
public void GetDynamicILInfo_Unique() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(string), Type.EmptyTypes, typeof(DynamicILInfoTest), false); DynamicILInfo il = dm.GetDynamicILInfo(); DynamicILInfo il2 = dm.GetDynamicILInfo(); Assert.IsTrue(Object.ReferenceEquals(il, il2)); }
public unsafe void SetX_NullInput_ThrowsArgumentNullException(bool skipVisibility) { DynamicMethod method = GetDynamicMethod(skipVisibility); DynamicILInfo dynamicILInfo = method.GetDynamicILInfo(); Assert.Throws <ArgumentNullException>(() => dynamicILInfo.SetCode(null, 1, 8)); Assert.Throws <ArgumentNullException>(() => dynamicILInfo.SetExceptions(null, 1)); Assert.Throws <ArgumentNullException>(() => dynamicILInfo.SetLocalSignature(null, 1)); }
private static void SetCode(MethodBase method, MethodBody body, DynamicILInfo ilInfo) { var code = body.GetILAsByteArray(); var reader = new ILReader.ILReader(method); var visitor = new IlInfoGetTokenVisitor(ilInfo, code); reader.Accept(visitor); ilInfo.SetCode(code, body.MaxStackSize); }
public void GetDynamicILInfo_NotSameNotNull(bool skipVisibility) { DynamicMethod method = GetDynamicMethod(skipVisibility); DynamicILInfo dynamicILInfo = method.GetDynamicILInfo(); Assert.NotNull(dynamicILInfo); Assert.Equal(dynamicILInfo, method.GetDynamicILInfo()); Assert.Equal(method, dynamicILInfo.DynamicMethod); }
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); }
private static void SetLocalSignature(MethodBody body, DynamicILInfo ilInfo) { SignatureHelper sig = SignatureHelper.GetLocalVarSigHelper(); foreach (LocalVariableInfo lvi in body.LocalVariables) { sig.AddArgument(lvi.LocalType, lvi.IsPinned); } ilInfo.SetLocalSignature(sig.GetSignature()); }
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()); }
/// <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); }
/// <summary> /// Creates a new instance of <see cref="DynamicMethodTokenProvider"/>. /// </summary> /// <param name="dynamicILInfo">The <see cref="DynamicILInfo"/> instance for the dynamic method /// for which code is being emitted.</param> /// <param name="trackMethodStackChanges">If this is set to true, computes stack change /// information for external methods for computing the maxstack value of the emitted /// method body. If this is false, all method calls are assumed to pop nothing and push /// a return value for the purpose of computing maxstack. Note that computing stack /// change information requires reflection calls that may have a performance cost.</param> public DynamicMethodTokenProvider(DynamicILInfo dynamicILInfo, bool trackMethodStackChanges = false) { m_dynamicILInfo = null !; setDynamicILInfo(dynamicILInfo); m_typeHandleGenerator = type => getHandle(type); if (trackMethodStackChanges) { m_methodStackChangeInfo = new Dictionary <EntityHandle, MethodStackChangeInfo>(); } }
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()); }
/// <summary> /// Binds this method body to a method dynamically generated with the DynamicMethod /// API. /// </summary> /// <param name="dynamicILInfo">The <see cref="DynamicILInfo"/> for the dynamic method.</param> public void bindToDynamicILInfo(DynamicILInfo dynamicILInfo) { dynamicILInfo.SetCode(m_methodBody, m_maxStack); // DynamicILInfo requires a valid local signature, so use the empty signature // if there are no locals. dynamicILInfo.SetLocalSignature((m_localSignature.Length != 0) ? m_localSignature : s_emptyLocalSig); if (m_ehSection.Length != 0) { dynamicILInfo.SetExceptions(m_ehSection); } }
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 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() { 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_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_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_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_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); }
public unsafe void SetX_NegativeInputSize_ThrowsArgumentOutOfRangeException(bool skipVisibility) { DynamicMethod method = GetDynamicMethod(skipVisibility); DynamicILInfo dynamicILInfo = method.GetDynamicILInfo(); var bytes = new byte[] { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; Assert.Throws <ArgumentOutOfRangeException>(() => { fixed(byte *bytesPtr = bytes) { dynamicILInfo.SetCode(bytesPtr, -1, 8); } }); Assert.Throws <ArgumentOutOfRangeException>(() => { fixed(byte *bytesPtr = bytes) { dynamicILInfo.SetExceptions(bytesPtr, -1); } }); Assert.Throws <ArgumentOutOfRangeException>(() => { fixed(byte *bytesPtr = bytes) { dynamicILInfo.SetLocalSignature(bytesPtr, -1); } }); }
public ExecuteExpression <T> CreateExpressionDelegate <T>(DynamicMethodState methodState, object functionClass) { ExecuteExpression <T> expressionDelegate; Stopwatch stopWatch = new Stopwatch(); Trace.WriteLine("Dynamic dll creation - " + stopWatch.ElapsedMilliseconds.ToString()); stopWatch = new Stopwatch(); stopWatch.Start(); //create DynamicMethod dynamicMethod = new DynamicMethod("", typeof(T), new Type[] { functionClass.GetType() }, functionClass.GetType()); DynamicILInfo dynamicInfo = dynamicMethod.GetDynamicILInfo(); dynamicMethod.InitLocals = methodState.InitLocals; SignatureHelper locals = SignatureHelper.GetLocalVarSigHelper(); foreach (int localIndex in methodState.LocalVariables.Keys) { LocalVariable localVar = methodState.LocalVariables[localIndex]; locals.AddArgument(localVar.LocalType, localVar.IsPinned); } dynamicInfo.SetLocalSignature(locals.GetSignature()); IlTokenResolver tokenResolver = new IlTokenResolver(methodState.TokenOffset.Fields, methodState.TokenOffset.Methods, methodState.TokenOffset.Members, methodState.TokenOffset.Types, methodState.TokenOffset.LiteralStrings); methodState.CodeBytes = tokenResolver.ResolveCodeTokens(methodState.CodeBytes, dynamicInfo); dynamicInfo.SetCode(methodState.CodeBytes, methodState.MaxStackSize); expressionDelegate = (ExecuteExpression <T>)dynamicMethod.CreateDelegate(typeof(ExecuteExpression <T>), functionClass); stopWatch.Stop(); Trace.WriteLine("Dynamic Method Creation - " + stopWatch.ElapsedMilliseconds.ToString()); return(expressionDelegate); }
/// <summary> /// Sets the <see cref="DynamicILInfo"/> instance for the dynamic method for which code /// is being emitted. /// </summary> /// <param name="dynamicILInfo">A <see cref="DynamicILInfo"/> instance.</param> public void setDynamicILInfo(DynamicILInfo dynamicILInfo) { if (dynamicILInfo == null) { throw new ArgumentNullException(nameof(dynamicILInfo)); } if (dynamicILInfo == m_dynamicILInfo) { return; } m_dynamicILInfo = dynamicILInfo; m_tokenCache.clear(); if (m_methodStackChangeInfo != null) { m_methodStackChangeInfo.Clear(); } }
public MethodBodyOnDynamicILInfo(DynamicMethod dynamicMethod, DynamicILInfo dynamicILInfo, bool resolveTokens) : base(GetMethodSignature(dynamicILInfo), resolveTokens) { scope = new DynamicILInfoWrapper(dynamicILInfo).m_scope; using (var dynamicResolver = new DynamicResolver(dynamicMethod, dynamicILInfo)) { int stackSize; int initLocals; int EHCount; var code = dynamicResolver.GetCodeInfo(out stackSize, out initLocals, out EHCount); MaxStack = stackSize; InitLocals = initLocals != 0; SetLocalSignature(dynamicResolver.m_localSignature); ILCodeReader.Read(code, ResolveToken, resolveTokens, this); ExceptionsInfoReader.Read(dynamicResolver.GetRawEHInfo(), ResolveToken, resolveTokens, this); } }
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()); }
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)); }
public IlInfoGetTokenVisitor(DynamicILInfo ilinfo, byte[] code) { _ilInfo = ilinfo; _code = code; }