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.

Reply via email to