turner
turner
CC#
Created by turner on 1/14/2024 in #help
Dictionary cant find via ContainsKey but it does exist
i guess ill just use the wanky workaround, its not performance critical so its ok
10 replies
CC#
Created by turner on 1/14/2024 in #help
Dictionary cant find via ContainsKey but it does exist
ah yea, well sadly its not 5 lines but here it is: this is where the lookup gets populated
void ComputeJumpsToInstructions(CilInstructionCollection instructions)
{
foreach (var instruction in instructions)
{
if (instruction.IsBranch())
{
if (instruction.OpCode == CilOpCodes.Switch)
{
var dstList = instruction.Operand as List<ICilLabel>;

foreach (var dst in dstList.Cast<CilInstructionLabel>())
{
if (jumpsToInstruction.ContainsKey(dst.Instruction))
{
jumpsToInstruction[dst.Instruction]++;
}
else
{
jumpsToInstruction[dst.Instruction] = 1;
}
}
}
else
{
var dst = instruction.Operand as CilInstructionLabel;

if (jumpsToInstruction.ContainsKey(dst.Instruction))
{
jumpsToInstruction[dst.Instruction]++;
}
else
{
jumpsToInstruction[dst.Instruction] = 1;
}
}
}
}
}
void ComputeJumpsToInstructions(CilInstructionCollection instructions)
{
foreach (var instruction in instructions)
{
if (instruction.IsBranch())
{
if (instruction.OpCode == CilOpCodes.Switch)
{
var dstList = instruction.Operand as List<ICilLabel>;

foreach (var dst in dstList.Cast<CilInstructionLabel>())
{
if (jumpsToInstruction.ContainsKey(dst.Instruction))
{
jumpsToInstruction[dst.Instruction]++;
}
else
{
jumpsToInstruction[dst.Instruction] = 1;
}
}
}
else
{
var dst = instruction.Operand as CilInstructionLabel;

if (jumpsToInstruction.ContainsKey(dst.Instruction))
{
jumpsToInstruction[dst.Instruction]++;
}
else
{
jumpsToInstruction[dst.Instruction] = 1;
}
}
}
}
}
and this is where it is being read
Block MergeBlocksInternal(Block main, Block merged, List<Block> blocks, HashSet<Block> mergedBlocks)
{
mergedBlocks.Add(main);

if (merged == null) // end of block chain
return main;

if (mergedBlocks.Contains(merged))
return main;

var jumpInstruction = main.instructions.Last();

if (jumpInstruction.OpCode == CilOpCodes.Br)
{
var dst = jumpInstruction.Operand as CilInstructionLabel;
var dstInstruction = dst.Instruction;

// vvvvvvvvvvvvv this is where it throws vvvvvvvvvvvvvv
//if (jumpsToInstruction[dstInstruction] != 1) // this for some reason it doenst work?? it should!
if (jumpsToInstruction.First(x => x.Key == dstInstruction).Value != 1) // this is a workaround
{
return main;
}

var destinationBlock = instruction2block[dstInstruction];

if (dstInstruction != destinationBlock.instructions.First()) // only merge blocks if they link with each other (jumps in the middle of a block does not count)
return main;

main.destinationBlock = destinationBlock.destinationBlock;
}

main.instructions.RemoveAt(main.instructions.Count - 1);
main.instructions.AddRange(merged.instructions);

mergedBlocks.Add(merged);

return MergeBlocksInternal(main, main.destinationBlock, blocks, mergedBlocks);
}
Block MergeBlocksInternal(Block main, Block merged, List<Block> blocks, HashSet<Block> mergedBlocks)
{
mergedBlocks.Add(main);

if (merged == null) // end of block chain
return main;

if (mergedBlocks.Contains(merged))
return main;

var jumpInstruction = main.instructions.Last();

if (jumpInstruction.OpCode == CilOpCodes.Br)
{
var dst = jumpInstruction.Operand as CilInstructionLabel;
var dstInstruction = dst.Instruction;

// vvvvvvvvvvvvv this is where it throws vvvvvvvvvvvvvv
//if (jumpsToInstruction[dstInstruction] != 1) // this for some reason it doenst work?? it should!
if (jumpsToInstruction.First(x => x.Key == dstInstruction).Value != 1) // this is a workaround
{
return main;
}

var destinationBlock = instruction2block[dstInstruction];

if (dstInstruction != destinationBlock.instructions.First()) // only merge blocks if they link with each other (jumps in the middle of a block does not count)
return main;

main.destinationBlock = destinationBlock.destinationBlock;
}

main.instructions.RemoveAt(main.instructions.Count - 1);
main.instructions.AddRange(merged.instructions);

mergedBlocks.Add(merged);

return MergeBlocksInternal(main, main.destinationBlock, blocks, mergedBlocks);
}
The call of the 2nd function is quite complex so i cant really put it here, but at the core its basically itterating a List with CilInstruction items
10 replies
CC#
Created by turner on 1/14/2024 in #help
Dictionary cant find via ContainsKey but it does exist
sure, what else is there to share? I think i shared everything Just to clarify if i do:
jumpsToInstruction.ElementAt(13).Key.GetHashCode() == dstInstruction.GetHashCode()
jumpsToInstruction.ElementAt(13).Key.Equals(dstInstruction)
jumpsToInstruction.ElementAt(13).Key.GetHashCode() == dstInstruction.GetHashCode()
jumpsToInstruction.ElementAt(13).Key.Equals(dstInstruction)
They will both return true, so from what i understand this means that the methods are correctly overridden
10 replies
CC#
Created by turner on 1/14/2024 in #help
Dictionary cant find via ContainsKey but it does exist
This is the dictionary in question:
Dictionary<CilInstruction, int> jumpsToInstruction = new Dictionary<CilInstruction, int>();
Dictionary<CilInstruction, int> jumpsToInstruction = new Dictionary<CilInstruction, int>();
the CilInstruction type is from the library AsmResolver which does have its own Equals and GetHashCode which when i manually check produces the correct results and the dict should find it based on that
10 replies