Regardless of the Cecil part of things, the github issue is pretty clear: calli doesn't support generic arguments, I'm afraid this is not going to work.
Jb On Mon, May 14, 2018 at 8:21 AM float trunks <[email protected]> wrote: > I'm trying to inject a calli instruction into a generic method whose > CallSite parameters should be defined as generic. > The static method that is called with calli is in fact not generic but its > function pointer is stored in a generic struct that acts as a > lightweight function pointer wrapper. > The generic struct is supposed to work like a delegate as in its generic > parameters should define the types of arguments used to calli the function > pointer. > > Maybe someone can tell me if and how this is possible. > This isssue here: https://github.com/dotnet/coreclr/issues/14524 > suggests that it should be possible in a managed context but I'm getting > the same: > > BadImageFormatException: Bad element type in SizeOf > > on the calli instruction. > Here is the IL for the generic method : > > .method public hidebysig static > > void CallFastAction<T> ( > > valuetype Target.FastAction`1<!!T> fastAction, > > !!T data > > ) cil managed > > { > > // Method begins at RVA 0x20a8 > > // Code size 17 (0x11) > > .maxstack 2 > > .locals init ( > > [0] native int, > > [1] class [mscorlib]System.Type > > ) > > > > IL_0000: nop > > IL_0001: ldarg.0 > > IL_0002: ldfld native int valuetype Target.FastAction`1<!!T>:: > functionPtr > > IL_0007: stloc.0 > > IL_0008: ldarg.1 > > IL_0009: ldloc.0 > > IL_000a: calli System.Void(T) > > IL_000f: pop > > IL_0010: ret > > } // end of method FastExtensions::CallFastAction > > The System.Void(T) part doesn't look right to me but I can't figure out > how to inject the proper generic syntax. > The pop instruction is a testing artifact, it shouldn't alter the outcome > afaik. > Cecil code for reference: > > var il = method.Body.GetILProcessor(); > > var funcPtrFieldDef = actionType.Fields > .First(field => field.Name == "functionPtr"); > var funcPtrFieldRef = module.ImportReference(funcPtrFieldDef); > > //MakeGenericType() makes no difference here. > var methodRef = module.ImportReference(method); > var typeRef = module.ImportReference(methodRef.GenericParameters[0], > methodRef); > typeRef.MakeGenericType(); > > var callsite = new CallSite(module.TypeSystem.Void); > callsite.Parameters.Add(new ParameterDefinition(typeRef)); > > callsite.CallingConvention = MethodCallingConvention.Default; > > while (method.Body.Instructions.Count > 4) // > 4 > il.Remove(method.Body.Instructions.Last()); > > il.Emit(OpCodes.Ldarg_1); > il.Emit(OpCodes.Ldloc_0); > il.Emit(OpCodes.Calli, callsite); > il.Emit(OpCodes.Pop); > il.Emit(OpCodes.Ret); > > where method is the generic static method's MethodDefinition, actionType > is the generic struct definition and functionPtr is a function pointer to a > non generic static method. > > Thank you in advance to anyone who can help me with this. > > > -- > -- > -- > mono-cecil > --- > You received this message because you are subscribed to the Google Groups > "mono-cecil" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- -- -- mono-cecil --- You received this message because you are subscribed to the Google Groups "mono-cecil" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
