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.

Reply via email to