Another question related to the question above. In the simpler cases,
when I ask what type a ParameterDefinition,
FieldReference,VariableDefinition it is, I cast the operand of the
instruction containing 'ldloc.X' (where X is 's' or some number) as
VariableReference or any other type. However, I have observed that
when the instruction is ldloc.X where X is a number (and not s), the
operand is a null, and so the casting returns a null. How do I find
the type for those case?
For example, my code is similar to this:
for (int i = 0; i < _objects.Count; i++)
{
AClass ac = (AClass)_objects[i];
if(ac.IsA(some condition))
{
RClass p = ac.Method2<RClass>(true);
// other code
}
else
{
//else code
}
}
I am checking if object ac (which is calling Method2) is of type
RClass or not.
The corresponding set of instructions for the call to Method2.
{IL_0032: ldloc.2}
{IL_0033: ldc.i4.1}
{IL_0034: callvirt T
MyClass::Method2<Namespace1.RClass>(System.Boolean)}
How do I find the type of object loaded in IL_0032 (as it's operand is
always null and hence cannot be casted into a VariableReference or
another type).
Thanks,
On Jul 28, 5:03 pm, deedee <[email protected]> wrote:
> Yes, that helps a lot!
>
> Thanks.
>
> On Jul 28, 1:22 pm, Alex <[email protected]> wrote:
>
> > Hi,
>
> > You'd need to do some control flow analysis and figure out what kinds
> > of values could be in local variables and on the stack as the this
> > reference when the method is called. For the most simple cases, you
> > can simply ask what type a ParameterDefinition, FieldReference,
> > VariableDefinition etc is, but for anything complex like conditionals,
> > you'd have to do deeper analysis, e.g.:
>
> > class Program
> > {
> > class A
> > {
> > public virtual void Do() {}
> > }
>
> > class B : A
> > {
> > public override void Do() {}
> > }
>
> > static void Main(string[] args)
> > {
> > var obj = args == null ? new A() : new B();
> > obj.Do();
> > }
>
> > }
>
> > Will turn into:
>
> > .locals init (class Program/A V_0)
> > IL_0000: nop
> > IL_0001: ldarg.0
> > IL_0002: brfalse.s IL_000b
>
> > IL_0004: newobj instance void Program/B::.ctor()
> > IL_0009: br.s IL_0010
>
> > IL_000b: newobj instance void Program/A::.ctor()
> > IL_0010: stloc.0
> > IL_0011: ldloc.0
> > IL_0012: callvirt instance void Program/A::Do()
> > IL_0017: nop
> > IL_0018: ret
>
> > Here, you'd have to analyze the possible code paths to IL_0012 and
> > figure out what would be on the stack in each path.
>
> > (Hope I explained this somewhat decently; I'm sleep-deprived!)
>
> > Regards,
> > Alex
>
> > On Thu, Jul 28, 2011 at 8:25 PM, deedee <[email protected]> wrote:
> > > I need to know the type of an object, that calls a method.
> > > For example.
>
> > > public void MethodName1()
> > > {
> > > XClass obj1 = abc;
> > > // some code here
>
> > > obj1.Method2(true);
>
> > > }
>
> > > Method2(bool) is in a different class, which is being inherited by
> > > multiple classes. So I need to find the type of object that calls this
> > > method.
>
> > > I want the output to be "XClass" when I need to find the type of the
> > > object that calls Method2(bool). Is there a way I can do that? Right
> > > now the instructions just shows ldloc.x (where x is some index no.). I
> > > am aware that operands can be cast as MethodReference and
> > > FieldReferences and many other types depending on the case, but what
> > > shall I do here?
>
> > > Thanks!
>
> > > --
> > > --
> > > mono-cecil
--
--
mono-cecil