public static PSMElement GetSignificantAncestorOrSelf(PSMElement element, NodeMarker additionalSignificantNodeMarker) { PSMTreeIterator helper = new PSMTreeIterator(element); while (!((helper.CurrentNode is PSMClass && ((PSMClass)helper.CurrentNode).HasElementLabel) || helper.CurrentNode is PSMContentContainer || (additionalSignificantNodeMarker != null && additionalSignificantNodeMarker(helper.CurrentNode))) && helper.CanGoToParent()) { helper.GoToParent(); } if ((helper.CurrentNode is PSMClass && ((PSMClass)helper.CurrentNode).HasElementLabel) || helper.CurrentNode is PSMContentContainer || (additionalSignificantNodeMarker != null && additionalSignificantNodeMarker(helper.CurrentNode))) { return(helper.CurrentNode); } //else if (!helper.CanGoToParent()) // return helper.CurrentNode; else { return(null); } }
/// <summary> /// Setups all basic blocks (fills in the required information). /// </summary> /// <param name="nodeMarker">The current node marker.</param> /// <param name="current">The current block.</param> /// <param name="instructionIdx">The starting instruction index.</param> private void SetupBasicBlocks( NodeMarker nodeMarker, Block current, int instructionIdx) { if (!current.BasicBlock.Mark(nodeMarker)) { return; } var disassembledMethod = CodeGenerator.DisassembledMethod; current.InstructionOffset = instructionIdx; var stackCounter = current.StackCounter; for (int e = disassembledMethod.Count; instructionIdx < e; ++instructionIdx) { var instruction = disassembledMethod[instructionIdx]; // Handle implicit cases: jumps to blocks without a jump instruction if (blockMapping.TryGetValue(instruction.Offset, out Block other) && current != other) { // Wire current and new block AddSuccessor(current, other); other.StackCounter = stackCounter; SetupBasicBlocks(nodeMarker, other, instructionIdx); break; } else { // Update the current block stackCounter += (instruction.PushCount - instruction.PopCount); current.InstructionCount += 1; if (instruction.IsTerminator) { if (instruction.Argument is ILInstructionBranchTargets targets) { // Create appropriate temp targets var targetOffsets = targets.GetTargetOffsets(); if (targetOffsets.Length > 1) { foreach (var target in targetOffsets) { SetupBasicBlock(nodeMarker, current, stackCounter, target); } } else { SetupBasicBlock(nodeMarker, current, stackCounter, targetOffsets[0]); } } break; } } } }
private void SetupBasicBlock( NodeMarker nodeMarker, Block current, int stackCounter, int target) { var targetBlock = blockMapping[target]; AddSuccessor(current, targetBlock); targetBlock.StackCounter = stackCounter; var targetIdx = offsetMapping[target]; SetupBasicBlocks(nodeMarker, targetBlock, targetIdx); }
/// <summary> /// Returns true iff the reference marker is less or equal to the /// current marker value. /// </summary> /// <param name="referenceMarker">The reference marker.</param> /// <returns> /// True, iff the reference marker is less or equal to /// the current marker value. /// </returns> public bool IsMarked(NodeMarker referenceMarker) => Resolve().IsMarked(referenceMarker);
/// <summary> /// Marks the current node with the new marker value. /// </summary> /// <param name="newMarker">The new value to apply.</param> /// <returns> /// True, iff the old marker was not equal to the new marker /// (the node was not marked with the new marker value). /// </returns> public bool Mark(NodeMarker newMarker) => Resolve().Mark(newMarker);
public PSMElement GetSignificantAncestorOrSelf(NodeMarker additionalSignificantNodeMarker) { return(GetSignificantAncestorOrSelf(CurrentNode, additionalSignificantNodeMarker)); }
public static IEnumerable <PSMElement> SignificantAncestors(PSMElement element, NodeMarker nodeMarker) { List <PSMElement> result = new List <PSMElement>(); PSMTreeIterator it = new PSMTreeIterator(element); while (it.CanGoToParent()) { it.GoToParent(); PSMElement significantAncestorOrSelf = it.GetSignificantAncestorOrSelf(nodeMarker); result.AddIfNotContained(significantAncestorOrSelf); } return(result); }