示例#1
0
	ExpressionPtr buildPtrOperation(BasicGenerator::Operator op, const ExpressionPtr& ptrExpr) {
		assert_true(isReference(ptrExpr) && isPointer(core::analysis::getReferencedType(ptrExpr->getType())))
			<< "Trying to build a unary pointer operation with non-ref<ptr>.";
		IRBuilder builder(ptrExpr->getNodeManager());
		auto& pExt = ptrExpr->getNodeManager().getLangExtension<PointerExtension>();
		switch(op) {
		case BasicGenerator::Operator::PostInc: return builder.callExpr(pExt.getPtrPostInc(), ptrExpr);
		case BasicGenerator::Operator::PostDec: return builder.callExpr(pExt.getPtrPostDec(), ptrExpr);
		case BasicGenerator::Operator::PreInc: return builder.callExpr(pExt.getPtrPreInc(), ptrExpr);
		case BasicGenerator::Operator::PreDec: return builder.callExpr(pExt.getPtrPreDec(), ptrExpr);
		default: break;
		}

		assert_fail() << "Unsupported unary pointer operation " << op;
		return ExpressionPtr();
	}
示例#2
0
文件: file_scope.cpp 项目: enov/hhvm
void makeFatalMeth(FileScope& file,
                   AnalysisResultConstPtr ar,
                   const std::string& msg,
                   int line,
                   Meth meth) {
  auto labelScope = std::make_shared<LabelScope>();
  auto r = Location::Range(line, 0, line, 0);
  BlockScopePtr scope;
  auto args = std::make_shared<ExpressionList>(scope, r);
  args->addElement(Expression::MakeScalarExpression(ar, scope, r, msg));
  auto e =
    std::make_shared<SimpleFunctionCall>(scope, r, "throw_fatal", false, args,
                                         ExpressionPtr());
  meth(e);
  auto exp = std::make_shared<ExpStatement>(scope, labelScope, r, e);
  auto stmts = std::make_shared<StatementList>(scope, labelScope, r);
  stmts->addElement(exp);

  FunctionScopePtr fs = file.setTree(ar, stmts);
  fs->setOuterScope(file.shared_from_this());
  fs->getStmt()->resetScope(fs);
  exp->copyLocationTo(fs->getStmt());
  file.setOuterScope(const_cast<AnalysisResult*>(ar.get())->shared_from_this());
}
示例#3
0
文件: file_scope.cpp 项目: enov/hhvm
ExpressionPtr FileScope::getEffectiveImpl(AnalysisResultConstPtr ar) const {
  if (m_tree) return m_tree->getEffectiveImpl(ar);
  return ExpressionPtr();
}
示例#4
0
	ExpressionPtr buildPtrOperation(BasicGenerator::Operator op, const ExpressionPtr& lhs, const ExpressionPtr& rhs) {
		auto& basic = lhs->getNodeManager().getLangBasic();
		auto& pExt = lhs->getNodeManager().getLangExtension<PointerExtension>();
		IRBuilder builder(lhs->getNodeManager());

		auto assertPtr = [&](const ExpressionPtr& exp) {
			assert_pred1(isPointer, exp) << "Trying to build a ptr operation from non-ptr:"
				<< "\n lhs: " << *lhs << "\n  - of type: " << *lhs->getType() 
				<< "\n rhs: " << *rhs << "\n  - of type: " << *rhs->getType()
				<< "\n op: " << op;
		};
		auto assertInt = [&](const ExpressionPtr& exp) {
			assert_pred1(basic.isInt, exp->getType()) << "Trying to build a ptr add/sub with non-int"
				<< "\n lhs: " << *lhs << "\n  - of type: " << *lhs->getType() 
				<< "\n rhs: " << *rhs << "\n  - of type: " << *rhs->getType()
				<< "\n op: " << op;
		};
		auto buildInt8Cast = [&](const ExpressionPtr& exp) {
			if(!core::types::isSubTypeOf(exp->getType(), basic.getInt8())) {
				return builder.numericCast(exp, basic.getInt8());
			}
			return exp;
		};

		// arithmetic operations
		switch(op) {
		case BasicGenerator::Operator::Add: {
			if(!isPointer(lhs)) {
				assertPtr(rhs);
				assertInt(lhs);
				return builder.callExpr(pExt.getPtrAdd(), rhs, buildInt8Cast(lhs));
			}
			assertPtr(lhs);
			assertInt(rhs);
			return builder.callExpr(pExt.getPtrAdd(), lhs, buildInt8Cast(rhs));
		}
		case BasicGenerator::Operator::Sub: { // minus is only supported with ptr on the lhs
			assertPtr(lhs);
			if(!isPointer(rhs)) {
				assertInt(rhs);
				return builder.callExpr(pExt.getPtrSub(), lhs, buildInt8Cast(rhs));
			} else {
				return builder.callExpr(pExt.getPtrDiff(), lhs, rhs);
			}
		}
		default: break;
		}

		// comparison operations
		assertPtr(lhs);
		assertPtr(rhs);
		switch(op) {
		case BasicGenerator::Operator::Eq: return builder.callExpr(pExt.getPtrEqual(), lhs, rhs);
		case BasicGenerator::Operator::Ne: return builder.callExpr(pExt.getPtrNotEqual(), lhs, rhs);
		case BasicGenerator::Operator::Le: return builder.callExpr(pExt.getPtrLessEqual(), lhs, rhs);
		case BasicGenerator::Operator::Lt: return builder.callExpr(pExt.getPtrLessThan(), lhs, rhs);
		case BasicGenerator::Operator::Ge: return builder.callExpr(pExt.getPtrGreaterEqual(), lhs, rhs);
		case BasicGenerator::Operator::Gt: return builder.callExpr(pExt.getPtrGreaterThan(), lhs, rhs);
		default: break;
		}

		assert_fail() << "Unsupported binary pointer operation " << op;
		return ExpressionPtr();
	}
示例#5
0
ExpressionPtr UnaryOpExpression::preOptimize(AnalysisResultConstPtr ar) {
  Variant value;
  Variant result;

  if (m_exp && ar->getPhase() >= AnalysisResult::FirstPreOptimize) {
    if (m_op == T_UNSET) {
      if (m_exp->isScalar() ||
          (m_exp->is(KindOfExpressionList) &&
           static_pointer_cast<ExpressionList>(m_exp)->getCount() == 0)) {
        recomputeEffects();
        return CONSTANT("null");
      }
      return ExpressionPtr();
    }
  }

  if (m_op == T_ISSET && m_exp->is(KindOfExpressionList) &&
      static_pointer_cast<ExpressionList>(m_exp)->getListKind() ==
      ExpressionList::ListKindParam) {
    auto el = static_pointer_cast<ExpressionList>(m_exp);
    result = true;
    int i = 0, n = el->getCount();
    for (; i < n; i++) {
      ExpressionPtr e((*el)[i]);
      if (!e || !e->isScalar() || !e->getScalarValue(value)) break;
      if (value.isNull()) {
        result = false;
      }
    }
    if (i == n) {
      return replaceValue(makeScalarExpression(ar, result));
    }
  } else if (m_op != T_ARRAY &&
             m_exp &&
             m_exp->isScalar() &&
             m_exp->getScalarValue(value) &&
             preCompute(value, result)) {
    return replaceValue(makeScalarExpression(ar, result));
  } else if (m_op == T_BOOL_CAST) {
    switch (m_exp->getKindOf()) {
      default: break;
      case KindOfBinaryOpExpression: {
        int op = static_pointer_cast<BinaryOpExpression>(m_exp)->getOp();
        switch (op) {
          case T_LOGICAL_OR:
          case T_BOOLEAN_OR:
          case T_LOGICAL_AND:
          case T_BOOLEAN_AND:
          case T_LOGICAL_XOR:
          case T_INSTANCEOF:
          case '<':
          case T_IS_SMALLER_OR_EQUAL:
          case '>':
          case T_IS_GREATER_OR_EQUAL:
          case T_SPACESHIP:
          case T_IS_IDENTICAL:
          case T_IS_NOT_IDENTICAL:
          case T_IS_EQUAL:
          case T_IS_NOT_EQUAL:
            return m_exp;
        }
        break;
      }
      case KindOfUnaryOpExpression: {
        int op = static_pointer_cast<UnaryOpExpression>(m_exp)->getOp();
        switch (op) {
          case T_BOOL_CAST:
          case '!':
          case T_ISSET:
          case T_EMPTY:
          case T_PRINT:
            return m_exp;
        }
        break;
      }
    }
  }
  return ExpressionPtr();
}