protected override bool Step( GraphStructuredProgram <TNode> targetProgram, ResolvedMethod <TNode> targetMethod, TNode source, Statement statement, TNode target, Func <TNode> nodeCreator) { targetProgram.AddOperation(source, new Operation <TNode>(statement, target)); return(true); }
public void Transform( INodeBasedProgram <int> sourceMethod, GraphStructuredProgram <TNode> targetProgram, ResolvedMethod <TNode> targetMethod, Func <int, TNode> mapper) { int counter = -1; TNode CreateNewNode() { var newNode = mapper(counter--); targetMethod.AddOwnedNode(newNode); return(newNode); } var visited = new HashSet <int>(); var localStarts = sourceMethod.GetStarts(); var queued = new Stack <(TNode source, int target)>(); foreach (var localStart in localStarts) { queued.Push((targetMethod.Start, localStart)); } if (queued.Count == 0) { targetProgram.AddOperation(targetMethod.Start, new Operation <TNode>(myNop, targetMethod.Final)); } while (queued.Count > 0) { var(source, rawTarget) = queued.Pop(); var statement = sourceMethod.StatementAt(rawTarget); var target = mapper(rawTarget); InternalStep(targetProgram, targetMethod, source, statement, target, CreateNewNode); if (visited.Contains(rawTarget)) { continue; } if (sourceMethod.IsFinal(rawTarget)) { targetProgram.AddOperation(target, new Operation <TNode>(myReturn, targetMethod.Final)); } else { var transitions = sourceMethod.Transitions(rawTarget).ToList(); foreach (var transition in transitions) { queued.Push((target, transition)); } } visited.Add(rawTarget); } }
protected override bool Step( GraphStructuredProgram <TNode> targetProgram, ResolvedMethod <TNode> owningMethod, TNode source, Statement statement, TNode target, Func <TNode> nodeCreator) { SecondaryEntity CreateNewVariable() { var nextId = owningMethod.Variables.Keys.Max() + 1; var variable = new ResolvedLocalVariable(nextId); owningMethod.AddLocalVariable(variable); return(variable); } if (statement is InvocationStatement invocation) { var passedParameters = invocation.PassedParameters.GroupBy( pair => ReferenceResolver.Resolve(targetProgram, owningMethod, pair.Value), pair => pair.Key) .ToDictionary( pair => { Trace.Assert(pair.Key != null); return(pair.Key); }, pair => { var targets = pair.ToList(); return(targets.Count == 1 ? targets[0] : new ParameterIndicesSet( targets.Select(targetIndex => targetIndex.Value))); }); var returnedValues = invocation.ReturnedValues.ToDictionary( pair => { Trace.Assert(pair.Key != null); return(pair.Key); }, pair => (SecondaryEntity)ReferenceResolver.Resolve(targetProgram, owningMethod, pair.Value)); var normalizedPassedParameters = AddIntermediateEdgesIfNeeded( targetProgram, passedParameters, source, nodeCreator, CreateNewVariable, out var newSource); ResolvedInvocationStatement <TNode> resolvedInvocationStatement = null; if (invocation.InvocationTarget is ClassMethodTarget classMethodTarget) { var targetMethodId = targetProgram.GetOrCreateMethodId(classMethodTarget.TargetMethod); var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, classMethodTarget.TargetClass); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetMethodId); } if (invocation.InvocationTarget is LocalVariableTarget localVariableTarget) { var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, new LocalVariableReference(localVariableTarget.Index)); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetProgram.GetOrCreateMethodId("Invoke")); } if (invocation.InvocationTarget is ClassFieldTarget classFieldTarget) { var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, new ClassFieldReference(classFieldTarget.TargetClass, classFieldTarget.TargetField)); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetProgram.GetOrCreateMethodId("Invoke")); } if (invocation.InvocationTarget is ClassPropertyTarget classPropertyTarget) { var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, new ClassPropertyReference(classPropertyTarget.TargetClass, classPropertyTarget.TargetProperty)); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetProgram.GetOrCreateMethodId("Invoke")); } if (invocation.InvocationTarget is LocalFunctionTarget localFunctionTarget) { var resolvedOwner = owningMethod; var targetMethodId = targetProgram.GetOrCreateMethodId(localFunctionTarget.TargetFunction.Value); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetMethodId); } Trace.Assert(resolvedInvocationStatement != null); var operation = new Operation <TNode>(resolvedInvocationStatement, target); targetProgram.AddOperation(newSource, operation); return(false); } return(true); }