Пример #1
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex instanceof Assignment && $vertex->isIdempotent() && 1 >= $this->countUsages($vertex->getResult(), $graph)) {
         Helper::remove($vertex, $graph);
         return true;
     }
     return false;
 }
Пример #2
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex->getName() === 'BooleanNot') {
         if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getValue()->getType()->isUnknown()) {
             $vertex->getResult()->setType(new Type(Type::TYPE_BOOLEAN));
             return true;
         }
     }
     return false;
 }
Пример #3
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex instanceof Vertex\FunctionCall) {
         if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getSignature()->getReturn()->isUnknown()) {
             $vertex->getResult()->setType($vertex->getSignature()->getReturn());
             return true;
         }
     }
     return false;
 }
Пример #4
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex instanceof Vertex\Phi) {
         $types = [];
         foreach ($vertex->getValues() as $value) {
             $types[] = (string) $value->getType();
         }
         $types = array_unique($types);
         if ($vertex->getResult()->getType()->isUnknown()) {
             $type = null;
             $setAll = false;
             if (count($types) === 1 && $types[0] !== 'unknown') {
                 $type = Type::normalizeType($types[0]);
             } elseif (count($types) === 2 && in_array('long', $types) && in_array('numeric', $types)) {
                 $type = new Type(Type::TYPE_LONG);
                 $setAll = true;
             } elseif (count($types) === 2 && in_array('double', $types) && in_array('numeric', $types)) {
                 $type = new Type(Type::TYPE_DOUBLE);
                 $setAll = true;
             } elseif (count($types) === 2 && in_array('bool', $types) && in_array('numeric', $types)) {
                 $type = new Type(Type::TYPE_BOOLEAN);
             }
             if ($type) {
                 $vertex->getResult()->setType($type);
                 if ($setAll) {
                     foreach ($vertex->getValues() as $value) {
                         $value->setType($type);
                     }
                 }
                 return true;
             }
         }
         if (count($vertex->getValues()) === 1) {
             // remove phi node
             list($val) = iterator_to_array($vertex->getValues());
             $result = $vertex->getResult();
             foreach ($graph->vertices() as $vtx) {
                 $vtx->replaceVariable($result, $val);
                 if ($vtx instanceof Assignment && $vtx->getResult() === $result) {
                     $vtx->setResult($val);
                 }
             }
             Helper::remove($vertex, $graph);
             return true;
         }
     }
     return false;
 }
Пример #5
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex->getName() === 'Assign') {
         if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getValue()->getType()->isUnknown()) {
             $vertex->getResult()->setType($vertex->getValue()->getType());
             return true;
         }
     }
     return false;
 }
Пример #6
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex->getName() === 'BitwiseNot') {
         if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getValue()->getType()->isUnknown()) {
             if ($vertex->getValue()->getType()->getType() === Type::TYPE_STRING) {
                 $vertex->getResult()->setType(new Type(Type::TYPE_STRING));
             } else {
                 $vertex->getResult()->setType(new Type(Type::TYPE_LONG));
             }
             return true;
         }
     }
     return false;
 }
Пример #7
0
 public function getVarStub(Vertex $vertex, \StdClass $state)
 {
     $output = '';
     $varStub = '';
     foreach ($vertex->getVariables() as $var) {
         if (!isset($state->scope[$var])) {
             $state->scope[$var] = ++$state->varidx;
             if ($var instanceof Constant) {
                 $value = $var->getValue();
                 if ('string' == (string) $var->getType()) {
                     $value = base64_encode($value);
                 }
                 $varStub .= 'const $' . $state->scope[$var] . ' ' . $var->getType() . ' ' . $value . "\n";
             } elseif ($vertex instanceof Vertex\Function_) {
                 $varStub .= 'param $' . $state->scope[$var] . ' ' . $var->getType() . "\n";
             } else {
                 $varStub .= 'var $' . $state->scope[$var] . ' ' . $var->getType() . "\n";
             }
         }
         $output .= ' $' . $state->scope[$var];
     }
     return [$output, $varStub];
 }
Пример #8
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex instanceof JitBinaryOp && $vertex->getA() instanceof Constant && $vertex->getB() instanceof Constant) {
         $ret = null;
         switch ($vertex->getKind()) {
             case JitBinaryOp::CONCAT:
                 $ret = $vertex->getA()->getValue() . $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::PLUS:
                 $ret = $vertex->getA()->getValue() + $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::MINUS:
                 $ret = $vertex->getA()->getValue() - $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::MUL:
                 $ret = $vertex->getA()->getValue() * $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::DIV:
                 $ret = $vertex->getA()->getValue() / $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::MOD:
                 $ret = $vertex->getA()->getValue() % $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::EQUAL:
                 $ret = $vertex->getA()->getValue() == $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::NOT_EQUAL:
                 $ret = $vertex->getA()->getValue() != $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::IDENTICAL:
                 $ret = $vertex->getA()->getValue() == $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::NOT_IDENTICAL:
                 $ret = $vertex->getA()->getValue() !== $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::GREATER:
                 $ret = $vertex->getA()->getValue() > $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::GREATER_EQUAL:
                 $ret = $vertex->getA()->getValue() >= $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::SMALLER:
                 $ret = $vertex->getA()->getValue() < $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::SMALLER_EQUAL:
                 $ret = $vertex->getA()->getValue() <= $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::BITWISE_AND:
                 $ret = $vertex->getA()->getValue() & $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::BITWISE_OR:
                 $ret = $vertex->getA()->getValue() | $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::BITWISE_XOR:
                 $ret = $vertex->getA()->getValue() ^ $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::SHIFT_LEFT:
                 $ret = $vertex->getA()->getValue() << $vertex->getB()->getValue();
                 break;
             case JitBinaryOp::SHIFT_RIGHT:
                 $ret = $vertex->getA()->getValue() >> $vertex->getB()->getValue();
                 break;
         }
         // replace binary op with assign op
         Helper::replace($vertex, new JitAssign(new Constant($ret), $vertex->getResult()), $graph);
         return true;
     }
     return false;
 }
Пример #9
0
 public function process(Vertex $vertex, Digraph $graph)
 {
     if ($vertex->getName() !== 'BinaryOp') {
         return false;
     }
     $result = $vertex->getResult();
     $rType = $result->getType();
     if ($rType->isUnknown() || $rType->getType() === Type::TYPE_NUMERIC) {
         $typePair = [$vertex->getA()->getType()->getType(), $vertex->getB()->getType()->getType()];
         $newType = Type::TYPE_UNKNOWN;
         switch ($vertex->getKind()) {
             case JitBinaryOp::PLUS:
             case JitBinaryOp::MINUS:
             case JitBinaryOp::MUL:
                 switch ($typePair) {
                     case [Type::TYPE_LONG, Type::TYPE_LONG]:
                         $newType = Type::TYPE_NUMERIC;
                         break;
                     case [Type::TYPE_DOUBLE, Type::TYPE_LONG]:
                     case [Type::TYPE_LONG, Type::TYPE_DOUBLE]:
                     case [Type::TYPE_DOUBLE, Type::TYPE_NUMERIC]:
                     case [Type::TYPE_NUMERIC, Type::TYPE_DOUBLE]:
                     case [Type::TYPE_DOUBLE, Type::TYPE_DOUBLE]:
                         $newType = Type::TYPE_DOUBLE;
                         break;
                     case [Type::TYPE_NUMERIC, Type::TYPE_NUMERIC]:
                     case [Type::TYPE_NUMERIC, Type::TYPE_LONG]:
                     case [Type::TYPE_LONG, Type::TYPE_NUMERIC]:
                         $newType = Type::TYPE_NUMERIC;
                         break;
                     default:
                         if (in_array(Type::TYPE_DOUBLE, $typePair)) {
                             $newType = Type::TYPE_DOUBLE;
                         } else {
                             $newType = Type::TYPE_NUMERIC;
                         }
                 }
                 break;
             case JitBinaryOp::DIV:
                 $newType = Type::TYPE_DOUBLE;
                 break;
             case JitBinaryOp::EQUAL:
             case JitBinaryOp::NOT_EQUAL:
             case JitBinaryOp::IDENTICAL:
             case JitBinaryOp::NOT_IDENTICAL:
             case JitBinaryOp::GREATER:
             case JitBinaryOp::GREATER_EQUAL:
             case JitBinaryOp::SMALLER:
             case JitBinaryOp::SMALLER_EQUAL:
                 $newType = Type::TYPE_BOOLEAN;
                 break;
             case JitBinaryOp::BITWISE_AND:
             case JitBinaryOp::BITWISE_OR:
             case JitBinaryOp::BITWISE_XOR:
                 if ($typePair === [Type::TYPE_STRING, Type::TYPE_STRING]) {
                     $newType = Type::TYPE_STRING;
                     break;
                 }
                 // Fallthrough intentional
             // Fallthrough intentional
             case JitBinaryOp::SHIFT_LEFT:
             case JitBinaryOp::SHIFT_RIGHT:
                 $newType = Type::TYPE_LONG;
                 break;
         }
         if ($newType !== Type::TYPE_UNKNOWN && $newType !== $rType->getType()) {
             $result->setType(new Type($newType));
             return true;
         }
     }
     return false;
 }