public double PIValue = Math.PI; (with or without static)
is not detected as a field read or write?
I need to get PIValue is written and Math.PI is read.
Note that I used opCode == OpCodes.Stfld || opCode == OpCodes.Stsfld to detect written and opCode == OpCodes.Ldfld || opCode == OpCodes.Ldsfld || opCode == OpCodes.Ldsflda to detect field write.
if (operand.GetType() ==
typeof(FieldDefinition))
{
FieldDefinition fd =
(FieldDefinition)operand;
if (opCode == OpCodes.Stfld || opCode ==
OpCodes.Stsfld)
{
readOrWritten = " (is
written)";
}
if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldsfld || opCode ==
OpCodes.Ldsflda)
{
readOrWritten = " (is
read)";
}
Console.WriteLine("\t\t[field(currAsm)_used] " + fd.Name + " (" + opCode + ") "
+
readOrWritten);
}
if (operand.GetType() ==
typeof(FieldReference))
{
FieldReference fr =
(FieldReference)operand;
if (opCode == OpCodes.Stfld || opCode ==
OpCodes.Stsfld)
{
readOrWritten = " (is
written)";
}
if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldsfld || opCode ==
OpCodes.Ldsflda)
{
readOrWritten = " (is
read)";
}
Thanks,
LY
public double PIValue = Math.PI; (with or without static)
is not detected as a field read or write?
I need to get PIValue is written and Math.PI is read.
Note that I used opCode == OpCodes.Stfld || opCode == OpCodes.Stsfld to detect written and opCode == OpCodes.Ldfld || opCode == OpCodes.Ldsfld || opCode == OpCodes.Ldsflda to detect read.
On 1/8/10, Wee Li Yen <weel...@hotmail.com> wrote:
> public double PIValue = Math.PI; (with or without static)
If you had bothered to look at the definition of Math.PI you would
know. It's defined as follows:
public const double PI = 3.14159265358979323846;
Meaning the compiler will inline its value whenever it's used.
--
Jb Evain <j...@nurv.fr>
Again, if you had bothered to investigate a little bit you would know.
PI is defined as a constant, so the compiler will inline its value
everywhere it's used
var pi = Math.PI is compiled as:
ldc.r8 3.1415926535897931
stloc pi
So if you want to detect where PI is used, you have to check for the
`ldc.r8 Math.PI` pattern.
--
Jb Evain <j...@nurv.fr>
I print out all the instructions from VisitInstruction (BaseCodeVisitor) in
this way:
OpCode opCode = instr.OpCode;
object operand = instr.Operand;
Console.Write("###" + opCode + " " + ((operand != null)?
operand.ToString() : "") + "###");
Console.WriteLine();
But I don't see ldc.r8 Math.PI...
Do you know why? Thanks...
--------------------------------------------------
From: "Jb Evain" <j...@nurv.fr>
Sent: Friday, January 08, 2010 5:58 PM
To: <mono-...@googlegroups.com>
Subject: Re: [mono-cecil] Field read and write
> 2010/1/8 Li Yen Wee <weel...@hotmail.com>:
> --
> --
> mono-cecil
--
--
mono-cecil
ldc.r8 takes a value. What am saying is that you can assume that if
you encounter a ldc.r8 which has a double operand containing the value
of Math.PI, you can assume that it's what you're looking for.
--
Jb Evain <j...@nurv.fr>
Doing this (below) in VisitInstruction should have be fine right?
OpCode opCode = instr.OpCode;
object operand = instr.Operand;
Console.Write("###" + opCode + " " + ((operand != null)? operand.ToString()
: "") + "###");
Console.WriteLine();
--------------------------------------------------
From: "Jb Evain" <j...@nurv.fr>
Sent: Monday, January 11, 2010 12:07 AM
To: <mono-...@googlegroups.com>
Subject: Re: [mono-cecil] Field read and write
> On Sun, Jan 10, 2010 at 1:57 PM, Wee Li Yen <weel...@hotmail.com> wrote:
> --
> --
> mono-cecil
--
--
mono-cecil
I know what u mean now. What u mentioned below "var pi = Math.PI" is a local
variable declaration. I would be able to see the following if I used it as a
variable declaration, but what I meant is I want a field declaration.
> ldc.r8 3.1415926535897931
> stloc pi
Field declaration eg: "public double pi = Math.PI;"
But I can only detect this field when I assign this value to the field in a
method.
If I put it as a field declaration or assign this value to the field in a
ctr, I won't be able to see the above instr.
Is there anyway I can see it even if I put it as a field declaration or
overwrite the field in a ctr?
Hope to hear a reply from you, thanks.
Li Yen
--------------------------------------------------
From: "Jb Evain" <j...@nurv.fr>
Sent: Friday, January 08, 2010 5:58 PM
To: <mono-...@googlegroups.com>
Subject: Re: [mono-cecil] Field read and write
> 2010/1/8 Li Yen Wee <weel...@hotmail.com>:
> --
> --
> mono-cecil
On Fri, Jan 15, 2010 at 11:33 AM, Wee Li Yen <weel...@hotmail.com> wrote:
> Field declaration eg: "public double pi = Math.PI;"
>
> But I can only detect this field when I assign this value to the field in a
> method.
> If I put it as a field declaration or assign this value to the field in a
> ctr, I won't be able to see the above instr.
You will, it will be assigned in the constructor of the type. You'll
see something like:
ldc.r8 3.14....
stfld pi
--
Jb Evain <j...@nurv.fr>
Sorry for the very late reply, as I was busy with other projects...
I didn't see what u mentioned below when it is assigned in the constructor,
only see it in methods.
Can u double confirm it by testing it out?
Then I realised it may be because I didn't visit constructors... But even
when I visit constructor n try to print out from the VisitConstructor, there
is no difference in the output. Since ctor is actually a mtd, shldn't it
work even I don't visit constructor?
public virtual void VisitConstructorCollection
(ConstructorCollection ctors)
{
foreach (MethodDefinition item in ctors)
{
Console.WriteLine("in ctor of ctors"); //I direct all my
Console.WriteLine() to a file.
item.Accept(this);
}
}
public virtual void VisitConstructor(MethodDefinition ctor)
{
if (ctor.Body != null)
{
Console.WriteLine("in ctor");
ASTCodeVisitor astHelperVisitor = new ASTCodeVisitor();
astHelperVisitor.CurrMethod = ctor.DeclaringType.FullName +
"." + ctor.Name;
ctor.Body.Accept(astHelperVisitor);
}
}
Below is the program I created separately to test this:
The output shows instructions can detect pi2 being assigned in the method
MethodA but not pi1 in the constructor Test.
namespace TestTest
{
class Test
{
public static double pi1;
public static double pi2;
public Test()
{
pi1 = Math.PI;
}
public virtual void MethodA()
{
pi2 = Math.PI;
}
static void Main(string[] args)
{
}
}
}
Here is the output (btn "###" are the instructions detected):
----------------------[assembly] TestTest, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null----------------------
[type_decl] Test
[extends_fr] Object
[method_decl] MethodA
[modifiers] public virtual
###nop ###
###ldc.r8 3.14159265358979###
###stsfld System.Double TestTest.Test::pi2###
[field(currAsm)_used] pi2 (stsfld) (is written)
###ret ###
[return] Void
[method_decl] Main
[modifiers] private static
###nop ###
###ret ###
[return] Void
[parameter] args
[type] String[]
[field_decl] pi1
[modifiers] public static
[type] Double
[field_decl] pi2
[modifiers] public static
[type] Double
Thanks,
LY
--------------------------------------------------
From: "Jb Evain" <j...@nurv.fr>
Sent: Friday, January 15, 2010 8:32 PM
To: <mono-...@googlegroups.com>
Subject: Re: [mono-cecil] Field read and write
> Hey,
> --
> --
> mono-cecil
I know why alr! Careless mistake on my part. My VisitConstructorCollection
and VisitConstructor shld be 'override' not 'virtual'! Cos I copied the
method signature from the docs n forgot to change...
Oh yes! Now those field read n write in declaration, in ctors, and in
methods all can be detected! So initially the problem occurred cos I didn't
visit constructor collection.
Btw, I think VisitConstructor is sort of redundant, since VisitConstructor
accepts a MethodDefintion, so VisitMethodDefinition can do the job of the
VisitConstructor. Cos I managed to print out "in ctor of ctors" but not "in
ctor"...
Thanks,
Li Yen =)
--------------------------------------------------
From: "Wee Li Yen" <weel...@hotmail.com>
Sent: Friday, January 22, 2010 9:49 PM
> --
> --
> mono-cecil
>