Exemplo n.º 1
0
void FunctionScope::RecordFunctionInfo(std::string fname,
                                       FunctionScopePtr func) {
    VariableTablePtr variables = func->getVariables();
    if (Option::WholeProgram) {
        Lock lock(s_refParamInfoLock);
        FunctionInfoPtr &info = s_refParamInfo[fname];
        if (!info) {
            info = std::make_shared<FunctionInfo>();
        }
        if (func->isStatic()) {
            info->setMaybeStatic();
        }
        if (func->isRefReturn()) {
            info->setMaybeRefReturn();
        }
        if (func->isReferenceVariableArgument()) {
            info->setRefVarArg(func->getMaxParamCount());
        }
        for (int i = 0; i < func->getMaxParamCount(); i++) {
            if (func->isRefParam(i)) info->setRefParam(i);
        }
    }
    auto limit = func->getDeclParamCount();
    for (int i = 0; i < limit; i++) {
        variables->addParam(func->getParamName(i),
                            AnalysisResultPtr(), ConstructPtr());
    }
}
Exemplo n.º 2
0
void MethodStatement::outputCPPArgInjections(CodeGenerator &cg,
                                             AnalysisResultPtr ar,
                                             const char *name,
                                             ClassScopePtr cls,
                                             FunctionScopePtr funcScope) {
  if (cg.getOutput() != CodeGenerator::SystemCPP) {
    if (m_params) {
      int n = m_params->getCount();
      cg_printf("INTERCEPT_INJECTION(\"%s\", ", name);
      if (Option::GenArrayCreate && !hasRefParam()) {
        ar->m_arrayIntegerKeySizes.insert(n);
        outputParamArrayCreate(cg, true);
        cg_printf(", %s);\n", funcScope->isRefReturn() ? "ref(r)" : "r");
      } else {
        cg_printf("(Array(ArrayInit(%d, true)", n);
        for (int i = 0; i < n; i++) {
          ParameterExpressionPtr param =
            dynamic_pointer_cast<ParameterExpression>((*m_params)[i]);
          const string &paramName = param->getName();
          cg_printf(".set%s(%d, %s%s)", param->isRef() ? "Ref" : "",
                    i, Option::VariablePrefix, paramName.c_str());
        }
        cg_printf(".create())), %s);\n",
                  funcScope->isRefReturn() ? "ref(r)" : "r");
      }
    } else {
      cg_printf("INTERCEPT_INJECTION(\"%s\", null_array, %s);\n",
                name, funcScope->isRefReturn() ? "ref(r)" : "r");
    }
  }

  if (Option::GenRTTIProfileData && m_params) {
    for (int i = 0; i < m_params->getCount(); i++) {
      ParameterExpressionPtr param =
        dynamic_pointer_cast<ParameterExpression>((*m_params)[i]);
      if (param->hasRTTI()) {
        const string &paramName = param->getName();
        int id = ar->getParamRTTIEntryId(cls, funcScope, paramName);
        if (id != -1) {
          cg_printf("RTTI_INJECTION(%s%s, %d);\n",
                    Option::VariablePrefix, paramName.c_str(), id);
        }
      }
    }
  }
}
Exemplo n.º 3
0
void ReturnStatement::analyzeProgram(AnalysisResultPtr ar) {
  if (m_exp) {
    FunctionScopePtr funcScope = getFunctionScope();
    if (funcScope) {
      if (funcScope->isRefReturn()) {
        m_exp->setContext(Expression::RefValue);
      }
    }
    m_exp->analyzeProgram(ar);
  }
}
void ReturnStatement::analyzeProgram(AnalysisResultPtr ar) {
  if (m_exp) {
    FunctionScopePtr funcScope = getFunctionScope();
    if (funcScope) {
      if (funcScope->isRefReturn()) {
        m_exp->setContext(Expression::RefValue);
      }
    }
    m_exp->analyzeProgram(ar);
  }
  if (ar->getPhase() == AnalysisResult::AnalyzeFinal) {
    if (m_exp) {
      TypePtr retType = m_exp->getCPPType();
      bool needsCheck = !retType->isPrimitive();
      if (m_exp->is(Expression::KindOfSimpleFunctionCall) ||
          m_exp->is(Expression::KindOfDynamicFunctionCall) ||
          m_exp->is(Expression::KindOfObjectMethodExpression)) {
        // return a value from another function call
        needsCheck = false;
      }
      ExpressionPtr tmp = m_exp;
      while (tmp &&
             (tmp->is(Expression::KindOfObjectPropertyExpression) ||
              tmp->is(Expression::KindOfArrayElementExpression))) {
        if (ObjectPropertyExpressionPtr opExp =
            dynamic_pointer_cast<ObjectPropertyExpression>(tmp)) {
          tmp = opExp->getObject();
        } else {
          ArrayElementExpressionPtr aeExp =
            dynamic_pointer_cast<ArrayElementExpression>(tmp);
          ASSERT(aeExp);
          tmp = aeExp->getVariable();
        }
      }
      if (SimpleVariablePtr svExp = dynamic_pointer_cast<SimpleVariable>(tmp)) {
        if (svExp->isThis()) {
          // returning something from $this
          needsCheck = false;
        } else {
          Symbol *sym = svExp->getSymbol();
          if (sym && sym->isParameter() && !sym->isLvalParam()) {
            // returning something from non-lval parameter
            needsCheck = false;
          }
        }
      }
      if (needsCheck) {
        FunctionScopePtr funcScope = getFunctionScope();
        if (funcScope) funcScope->setNeedsCheckMem();
      }
    }
  }
}
static bool checkCopyElision(FunctionScopePtr func, ExpressionPtr exp) {
  if (!exp->getType()->is(Type::KindOfVariant) || func->isRefReturn()) {
    return false;
  }

  TypePtr imp = exp->getImplementedType();
  if (!imp) imp = exp->getActualType();
  if (!imp || !imp->is(Type::KindOfVariant)) return false;

  if (func->getNRVOFix() && exp->is(Expression::KindOfSimpleVariable)) {
    return true;
  }

  if (FunctionCallPtr fc = dynamic_pointer_cast<FunctionCall>(exp)) {
    FunctionScopePtr fs = fc->getFuncScope();
    if (!fs || fs->isRefReturn()) {
      return true;
    }
  }

  return false;
}