protected function joinInputs(GraphNode $node) { if ($this->cfg->getEntryPoint() === $node) { $node->setAttribute(self::ATTR_FLOW_STATE_IN, $this->createEntryLattice()); return; } $predNodes = $this->cfg->getDirectedPredNodes($node); if (!$predNodes) { return; } $values = array(); foreach ($predNodes as $predNode) { $succNodes = $this->cfg->getDirectedSuccNodes($predNode); $index = array_search($node, $succNodes, true); $outStates = $predNode->getAttribute(self::ATTR_FLOW_STATE_OUT); $values[] = $outStates[$index]; } if (!$values) { return; } $newInState = call_user_func($this->joinOp, $values); $node->setAttribute(self::ATTR_FLOW_STATE_IN, $newInState); }
private function prioritizeFromEntryNode(GraphNode $entry) { $worklist = array(); $worklist[] = array($entry, $entry->getAstNode()->getAttribute('position', 0)); while (!empty($worklist)) { list($current, ) = array_shift($worklist); /** @var $current GraphNode */ if (null !== $current->getAttribute('priority')) { continue; } $current->setAttribute('priority', ++$this->priorityCounter); foreach ($current->getOutEdges() as $edge) { /** @var $edge GraphEdge */ $destNode = $edge->getDest(); // Implicit return is always the last node. if ($this->graph->isImplicitReturn($destNode)) { $position = $this->astPositionCounter + 1; } else { $position = $destNode->getAstNode()->getAttribute('position'); if (null === $position) { throw new \RuntimeException(NodeUtil::getStringRepr($destNode->getAstNode()) . ' has no position.'); } } $worklist[] = array($destNode, $position); } usort($worklist, function ($a, $b) { return $a[1] - $b[1]; }); } }
protected function flow(GraphNode $node) { if ($this->isForward()) { $outBefore = $node->getAttribute(self::ATTR_FLOW_STATE_OUT); $outAfter = $this->flowThrough($node->getAstNode(), $node->getAttribute(self::ATTR_FLOW_STATE_IN)); $node->setAttribute(self::ATTR_FLOW_STATE_OUT, $outAfter); return false === $outBefore->equals($outAfter); } $inBefore = $node->getAttribute(self::ATTR_FLOW_STATE_IN); $inAfter = $this->flowThrough($node->getAstNode(), $node->getAttribute(self::ATTR_FLOW_STATE_OUT)); $node->setAttribute(self::ATTR_FLOW_STATE_IN, $inAfter); return false === $inBefore->equals($inAfter); }
private function verifyOutHas(GraphNode $node, Variable $var, $constant) { $fState = $node->getAttribute(DataFlowAnalysis::ATTR_FLOW_STATE_OUT); if (null === $constant) { $this->assertFalse(isset($fState->constMap[$var])); } else { $this->assertTrue(isset($fState->constMap[$var])); $this->assertSame($constant, $fState->constMap[$var]); } }
public function isConnected(GraphNode $a, GraphNode $b, $edgeType) { foreach ($a->getOutEdges() as $edge) { if ($edge->getType() !== $edgeType) { continue; } if ($edge->getDest() === $b) { return true; } } return false; }