Group to Statements

Topics: Metadata Model, PDB Reader, PE reader
Oct 6, 2011 at 7:17 PM

I am trying to iteratively mutate an Assembly and I am facing the problem of grouping instructions emitted by myself into statements.


Is there a way to group several emitted instructions into a statement by using CCI Metadata and the ILGenerator?

And is there a way to say which Il Instructions belong together, beside grouping instructions based on whether they have a source code line or not?

Oct 6, 2011 at 8:07 PM

There is no concept of "Statement" at the IL level. However, there are scopes. Have a look at ILGenerator.BeginScope and ILGenerator.EndScope.

Oct 6, 2011 at 8:39 PM

What I need is some sort of a work around all this.

ILGenerator.BeginScope and ILGenerator.EndScope seem to have no effect on the produced IL Code, or is there some sort of a special way to determine later where a scope created this way begins and ends.

Isn't there a way to produce an information like line number and column for a single instruction. Even if the information is wrong, this can help me group and distinguish my code from the already existing.

I am currently using the pdbReader.GetPrimarySourceLocationsForto help me group instructions. Might not be the best way, but it works this far.

Oct 6, 2011 at 8:44 PM

The scope information is provided by the ILocalScopeProvider object returned by ILGenerator.GetLocalScopes(). You can also set the Location property of the next IL instruction to be emitted by calling ILGenerator.MarkSequencePoint immediately before emitting the instruction.

Oct 6, 2011 at 9:35 PM

Thanks for the help, I will try both and see which better fits in my scenario.

Oct 14, 2011 at 4:49 PM

My first idea was to map the additional CIL-Operations to the white space before the mapping of the operation that is their successor. Unfortunately there seems to be a problem. Every time I call StartLine and then EndLine after the creation of the PrimarySourceLocation the line Number increases with one: Let's say line number is 10. I call StartLine and then Endline and they return 10. I call StartLine again and it returns 11.

This doesn't happen if I inherit the information from the successor operation without changing the mapping source position.

IPrimarySourceLocation psl = m_PdbReader.GetPrimarySourceLocationsFor(location.OperationsToLock.First().Location).First();
var sourceLocation = new PrimarySourceLocation(psl.PrimarySourceDocument, psl.StartIndex - psl.StartColumn, psl.StartColumn - 1);

Console.Print("Writting PSL in " + location.RacingMethod.Name + ": " +
	  "Line: (" + sourceLocation.StartLine + ", " + sourceLocation.EndLine + "); " +
	  "Column: (" + sourceLocation.StartColumn + ", " + sourceLocation.EndColumn + "); " +
	  "Index: ( " + sourceLocation.StartIndex + ", " + sourceLocation.EndIndex + " );\r\n"ConsoleView.CONSOLE);

I believe there is a bug somewhere, that is causing the increased line number.
Oct 15, 2011 at 12:17 AM

I don't quite follow what you reporting. Are you saying that a PrimarySourceLocation value is not immutable?

Could you perhaps debug into it a bit suggest a fix? Alternatively, could you provide me with a small test program that displays the erroneous behavior, so that I can debug and fix it?

Oct 15, 2011 at 12:55 AM

What I do is the following:

I am using the CodeMutation sample and am trying to insert a lock-Block (Monitor.Enter/Exit) around OperationsToLock, which is a list of Operations. I want to give the new operations a PrimarySourceLocation, which should be the empty space before the PrimarySourceLocation of the first operation inside the lock-Block.

The new PSL is sourceLocation from the code above. After I create the object and stop with the debugger at the Console.Print and go over sourceLocation.StartLine, sourceLocation.EndtLine, sourceLocation.StartLine, sourceLocation.EndLine the returned line keeps increasing: 10, 11, 12, 13, .... every time I check it and the debugger recalculates it.

My guess is that the code doesn't deal well with empty spaces and there is probably some side effect from calling the properties. The code isn't successfully resetting the search, no idea why.

Everything works just fine if I copy the Index and the length from the first locked instruction.

Oct 15, 2011 at 1:01 AM

I'm afraid the green color of the "pls.StartColumn, psl.StartColumn - 1" bit distracted me from viewing it as actual code. The StartIndex is something quite different from a StartColumn. The former is a character index from the start of the document, the latter from the start of the current line. Try "psl.StartIndex-1, psl.StartIndex".

Oct 17, 2011 at 9:07 AM

I am not able to reproduce the behavior when I use StartIndex = psl.StartIndex - 2 and the length of 1.

What I previously wrote should have worked as well, because


returns the index of the first character on the same line and

psl.StartColumn - 1

is the length of the empty space from the beginning of the line.

The behavior should be the same as the one with the (psl.StartIndex - 2, 1) but it is not.