Пример #1
0
void ExpressionList::outputCPPUniqLitKeyArrayInit(
  CodeGenerator &cg, AnalysisResultPtr ar, int64 max,
  bool arrayElements /* = true */, unsigned int start /* = 0 */) {
  if (arrayElements) ASSERT(m_arrayElements);
  unsigned int n =  m_exps.size();
  cg_printf("array_create%d(%lu, ", n - start, max);
  for (unsigned int i = start; i < n; i++) {
    if (ExpressionPtr exp = m_exps[i]) {
      ExpressionPtr name;
      ExpressionPtr value = exp;
      if (arrayElements) {
        ArrayPairExpressionPtr ap =
          dynamic_pointer_cast<ArrayPairExpression>(m_exps[i]);
        name = ap->getName();
        value = ap->getValue();
      }
      if (name) {
        name->outputCPP(cg, ar);
      } else {
        cg_printf("%d", i - start);
      }
      cg_printf(", ");
      value->outputCPP(cg, ar);
      if (i < n-1) {
        cg_printf(", ");
      } else {
        cg_printf(")");
      }
    }
  }
}
Пример #2
0
void FunctionScope::outputCPPArguments(ExpressionListPtr params,
                                       CodeGenerator &cg,
                                       AnalysisResultPtr ar, int extraArg,
                                       bool variableArgument,
                                       int extraArgArrayId /* = -1 */) {
  int paramCount = params ? params->getOutputCount() : 0;
  ASSERT(extraArg <= paramCount);
  int iMax = paramCount - extraArg;
  bool extra = false;

  if (variableArgument) {
    if (paramCount == 0) {
      cg.printf("0");
    } else {
      cg.printf("%d, ", paramCount);
    }
  }
  int firstExtra = 0;
  for (int i = 0; i < paramCount; i++) {
    ExpressionPtr param = (*params)[i];
    cg.setItemIndex(i);
    if (i > 0) cg.printf(extra ? "." : ", ");
    if (!extra && (i == iMax || extraArg < 0)) {
      if (extraArgArrayId != -1) {
        if (cg.getOutput() == CodeGenerator::SystemCPP) {
          cg.printf("SystemScalarArrays::%s[%d]",
                    Option::SystemScalarArrayName, extraArgArrayId);
        } else {
          cg.printf("ScalarArrays::%s[%d]",
                    Option::ScalarArrayName, extraArgArrayId);
        }
        break;
      }
      extra = true;
      // Parameter arrays are always vectors.
      cg.printf("Array(ArrayInit(%d, true).", paramCount - i);
      firstExtra = i;
    }
    if (extra) {
      bool needRef = param->hasContext(Expression::RefValue) &&
                     !param->hasContext(Expression::NoRefWrapper) &&
                     param->isRefable();
      cg.printf("set%s(%d, ", needRef ? "Ref" : "", i - firstExtra);
      if (needRef) {
        // The parameter itself shouldn't be wrapped with ref() any more.
        param->setContext(Expression::NoRefWrapper);
      }
      param->outputCPP(cg, ar);
      cg.printf(")");
    } else {
      param->outputCPP(cg, ar);
    }
  }
  if (extra) {
    cg.printf(".create())");
  }
}
Пример #3
0
void StaticStatement::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  BlockScopePtr scope = getScope();
  if (scope->inPseudoMain()) {
    if (m_exp->getCount() > 1) cg_indentBegin("{\n");
    for (int i = 0; i < m_exp->getCount(); i++) {
      ExpressionPtr exp = (*m_exp)[i];
      if (exp->is(Expression::KindOfAssignmentExpression)) {
        exp->outputCPP(cg, ar);
        cg_printf(";\n");
      } else {
        ASSERT(false);
      }
    }
    if (m_exp->getCount() > 1) cg_indentEnd("}\n");
    return;
  }

  VariableTablePtr variables = scope->getVariables();
  if (m_exp->getCount() > 1) cg_indentBegin("{\n");
  for (int i = 0; i < m_exp->getCount(); i++) {
    ExpressionPtr exp = (*m_exp)[i];
    if (exp->is(Expression::KindOfAssignmentExpression)) {
      AssignmentExpressionPtr assignment_exp =
        dynamic_pointer_cast<AssignmentExpression>(exp);
      ExpressionPtr variable = assignment_exp->getVariable();
      SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable);
      assert(var->hasContext(Expression::Declaration));
      const std::string &name = var->getName();

      if (variables->needLocalCopy(name)) {
        ASSERT(var->hasAssignableCPPVariable());
        cg_printf("%s.assignRef(%s%s);\n",
                  var->getAssignableCPPVariable(ar).c_str(),
                  Option::StaticVariablePrefix, name.c_str());
      }

      cg_indentBegin("if (!%s%s%s) {\n", Option::InitPrefix,
                     Option::StaticVariablePrefix, name.c_str());
      exp->outputCPP(cg, ar);
      cg_printf(";\n");
      cg_printf("%s%s%s = true;\n", Option::InitPrefix,
                Option::StaticVariablePrefix, name.c_str());
      cg_indentEnd("}\n");
    } else {
      ASSERT(false);
    }
  }
  if (m_exp->getCount() > 1) cg_indentEnd("}\n");
}
static void wrapValue(CodeGenerator &cg, AnalysisResultPtr ar,
                      ExpressionPtr exp, bool ref, bool array, bool varnr) {
  bool close = false;
  if (ref) {
    cg_printf("ref(");
    close = true;
  } else if (array && !exp->hasCPPTemp() &&
             !exp->isTemporary() && !exp->isScalar() &&
             exp->getActualType() && !exp->getActualType()->isPrimitive() &&
             exp->getActualType()->getKindOf() != Type::KindOfString) {
    cg_printf("wrap_variant(");
    close = true;
  } else if (varnr && exp->getCPPType()->isExactType()) {
    bool isScalar = exp->isScalar();
    if (!isScalar || !Option::UseScalarVariant) {
      cg_printf("VarNR(");
      close = true;
    } else if (isScalar) {
      ASSERT(!cg.hasScalarVariant());
      cg.setScalarVariant();
    }
  }
  exp->outputCPP(cg, ar);
  cg.clearScalarVariant();
  if (close) cg_printf(")");
}
void GlobalStatement::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  BlockScopePtr scope = getScope();
  if (m_exp->getCount() > 1) cg_indentBegin("{\n");
  for (int i = 0; i < m_exp->getCount(); i++) {
    ExpressionPtr exp = (*m_exp)[i];
    if (exp->is(Expression::KindOfSimpleVariable)) {
      SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(exp);
      const string &name = var->getName();
      VariableTablePtr variables = scope->getVariables();
      if (variables->needLocalCopy(name)) {
        cg_printf("%s%s = ref(g->%s);\n",
                  Option::VariablePrefix, name.c_str(),
                  variables->getGlobalVariableName(cg, ar, name).c_str());
      }
    } else if (exp->is(Expression::KindOfDynamicVariable)) {
      DynamicVariablePtr var = dynamic_pointer_cast<DynamicVariable>(exp);
      ExpressionPtr exp = var->getSubExpression();
      exp->outputCPPBegin(cg, ar);
      int id = cg.createNewLocalId(shared_from_this());
      cg_printf("CStrRef dgv_%d((", id);
      exp->outputCPP(cg, ar);
      cg_printf("));\n");
      cg_printf("variables->get(dgv_%d) = ref(g->get(dgv_%d));\n", id, id);
      exp->outputCPPEnd(cg, ar);
    } else {
      assert(false);
    }
  }
  if (m_exp->getCount() > 1) cg_indentEnd("}\n");
}
Пример #6
0
void QOpExpression::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  if (!m_cppValue.empty()) {
    cg_printf("%s", m_cppValue.c_str());
  } else {
    ExpressionPtr expYes = m_expYes ? m_expYes : m_condition;
    bool wrapped = !isUnused();
    if (wrapped) {
      cg_printf("(");
    }
    wrapBoolean(cg, ar, m_condition);
    if (isUnused()) {
      cg_printf(" ? ");
      outputUnneededExpr(cg, ar, expYes);
      cg_printf(" : ");
      outputUnneededExpr(cg, ar, m_expNo);
    } else {
      TypePtr typeYes = expYes->getActualType();
      TypePtr typeNo = m_expNo->getActualType();
      const char *castType =
        typeYes && typeNo && Type::SameType(typeYes, typeNo) &&
        !typeYes->is(Type::KindOfVariant) &&
        expYes->isLiteralString() == m_expNo->isLiteralString()
        ? "" : "(Variant)";

      cg_printf(" ? (%s(", castType);
      expYes->outputCPP(cg, ar);
      cg_printf(")) : (%s(", castType);
      m_expNo->outputCPP(cg, ar);
      cg_printf("))");
    }
    if (wrapped) {
      cg_printf(")");
    }
  }
}
void ClosureExpression::outputCPPImpl(CodeGenerator &cg,
                                      AnalysisResultPtr ar) {
  cg_printf("%sClosure((NEWOBJ(%sClosure)())->create(\"%s\", ",
            Option::SmartPtrPrefix, Option::ClassPrefix,
            m_func->getOriginalName().c_str());

  if (m_vars && m_vars->getCount()) {
    cg_printf("Array(ArrayInit(%d, false, true)", m_vars->getCount());
    for (int i = 0; i < m_vars->getCount(); i++) {
      ParameterExpressionPtr param =
        dynamic_pointer_cast<ParameterExpression>((*m_vars)[i]);
      ExpressionPtr value = (*m_values)[i];

      cg_printf(".set%s(\"%s\", ",
                param->isRef() ? "Ref" : "", param->getName().c_str());
      value->outputCPP(cg, ar);
      cg_printf(")");
    }
    cg_printf(".create())");
  } else {
    cg_printf("Array()");
  }

  cg_printf("))");
}
Пример #8
0
void ExpressionList::outputCPPUniqLitKeyArrayInit(
  CodeGenerator &cg, AnalysisResultPtr ar, bool litstrKeys, int64 num,
  bool arrayElements /* = true */, unsigned int start /* = 0 */) {
  if (arrayElements) ASSERT(m_arrayElements);
  unsigned int n =  m_exps.size();
  cg_printf("array_createv%c(%lld, ", litstrKeys ? 's' : 'i', num);
  assert(n - start == num);
  for (unsigned int i = start; i < n; i++) {
    ExpressionPtr exp = m_exps[i];
    assert(exp);
    ExpressionPtr name;
    ExpressionPtr value = exp;
    if (arrayElements) {
      ArrayPairExpressionPtr ap =
        dynamic_pointer_cast<ArrayPairExpression>(m_exps[i]);
      name = ap->getName();
      value = ap->getValue();
    }
    if (name) {
      assert(litstrKeys);
      cg_printf("toSPOD(");
      name->outputCPP(cg, ar);
      cg_printf("), ");
    }
    cg_printf("toVPOD(");
    if (value->isScalar()) {
      assert(!cg.hasScalarVariant());
      cg.setScalarVariant();
      if (!Option::UseScalarVariant) cg_printf("VarNR(");
      value->outputCPP(cg, ar);
      if (!Option::UseScalarVariant) cg_printf(")");
      cg.clearScalarVariant();
    } else {
      bool wrap = Expression::CheckVarNR(value, Type::Variant);
      if (wrap) cg_printf("VarNR(");
      value->outputCPP(cg, ar);
      if (wrap) cg_printf(")");
    }
    cg_printf(")");
    if (i < n-1) {
      cg_printf(", ");
    } else {
      cg_printf(")");
    }
  }
}
Пример #9
0
void ConstantTable::outputCPP(CodeGenerator &cg, AnalysisResultPtr ar) {
  bool decl = true;
  if (cg.getContext() == CodeGenerator::CppConstantsDecl) {
    decl = false;
  }

  bool printed = false;
  for (StringToSymbolMap::iterator iter = m_symbolMap.begin(),
         end = m_symbolMap.end(); iter != end; ++iter) {
    Symbol *sym = &iter->second;
    if (!sym->declarationSet() || sym->isDynamic()) continue;
    if (sym->isSystem() && cg.getOutput() != CodeGenerator::SystemCPP) continue;
    const string &name = sym->getName();
    ConstructPtr value = sym->getValue();
    printed = true;

    cg_printf(decl ? "extern const " : "const ");
    TypePtr type = sym->getFinalType();
    bool isString = type->is(Type::KindOfString);
    if (isString) {
      cg_printf("StaticString");
    } else {
      type->outputCPPDecl(cg, ar);
    }
    if (decl) {
      cg_printf(" %s%s", Option::ConstantPrefix,
                cg.formatLabel(name).c_str());
    } else {
      cg_printf(" %s%s", Option::ConstantPrefix,
                cg.formatLabel(name).c_str());
      cg_printf(isString ? "(" : " = ");
      if (value) {
        ExpressionPtr exp = dynamic_pointer_cast<Expression>(value);
        ASSERT(!exp->getExpectedType());
        ScalarExpressionPtr scalarExp =
          dynamic_pointer_cast<ScalarExpression>(exp);
        if (isString && scalarExp) {
          cg_printf("LITSTR_INIT(%s)",
                    scalarExp->getCPPLiteralString(cg).c_str());
        } else {
          exp->outputCPP(cg, ar);
        }
      } else {
        cg_printf("\"%s\"", cg.escapeLabel(name).c_str());
      }
      if (isString) {
        cg_printf(")");
      }
    }
    cg_printf(";\n");
  }
  if (printed) {
    cg_printf("\n");
  }
}
void ListAssignment::outputCPPAssignment(CodeGenerator &cg,
    AnalysisResultPtr ar, const string &arrTmp) {
  if (!m_variables) return;

  for (int i = m_variables->getCount() - 1; i >= 0; --i) {
    ExpressionPtr exp = (*m_variables)[i];
    if (exp) {
      if (exp->is(Expression::KindOfListAssignment)) {
        ListAssignmentPtr sublist = dynamic_pointer_cast<ListAssignment>(exp);
        string subTmp = genCPPTemp(cg, ar);
        cg_printf("Variant %s((ref(%s[%d])));\n", subTmp.c_str(),
                  arrTmp.c_str(), i);
        sublist->outputCPPAssignment(cg, ar, subTmp);
      } else {
        bool done = false;
        if (exp->is(Expression::KindOfArrayElementExpression)) {
          ArrayElementExpressionPtr arrExp =
            dynamic_pointer_cast<ArrayElementExpression>(exp);
          if (!arrExp->isSuperGlobal() && !arrExp->isDynamicGlobal()) {
            arrExp->getVariable()->outputCPP(cg, ar);
            if (arrExp->getOffset()) {
              cg_printf(".set(");
              arrExp->getOffset()->outputCPP(cg, ar);
              cg_printf(", ");
            } else {
              cg_printf(".append(");
            }
            cg_printf("%s[%d]);\n", arrTmp.c_str(), i);
            done = true;
          }
        } else if (exp->is(Expression::KindOfObjectPropertyExpression)) {
          ObjectPropertyExpressionPtr var(
            dynamic_pointer_cast<ObjectPropertyExpression>(exp));
          if (!var->isValid()) {
            var->outputCPPObject(cg, ar);
            cg_printf("o_set(");
            var->outputCPPProperty(cg, ar);
            cg_printf(", %s[%d], %s);\n",
                      arrTmp.c_str(), i,
                      getClassScope() ? "s_class_name" : "empty_string");
            done = true;
          }
        }
        if (!done) {
          exp->outputCPP(cg, ar);
          if (arrTmp == "null") {
            cg_printf(" = null;\n");
          } else {
            cg_printf(" = %s[%d];\n", arrTmp.c_str(), i);
          }
        }
      }
    }
  }
}
Пример #11
0
void FunctionScope::outputCPPEffectiveArguments(ExpressionListPtr params,
                                                CodeGenerator &cg,
                                                AnalysisResultPtr ar) {
  int paramCount = params ? params->getCount() : 0;
  for (int i = 0; i < paramCount; i++) {
    ExpressionPtr param = (*params)[i];
    if (param->hasEffect()) {
      param->outputCPP(cg, ar);
      cg.printf(", ");
    }
  }
}
Пример #12
0
void QOpExpression::wrapBoolean(CodeGenerator &cg,
                                AnalysisResultPtr ar,
                                ExpressionPtr exp) {
  TypePtr t(exp->getType());
  ASSERT(t);
  bool wrap = false;
  if (!t->is(Type::KindOfBoolean)) {
    wrap = true;
    cg_printf("toBoolean(");
  }
  exp->outputCPP(cg, ar);
  if (wrap) cg_printf(")");
}
Пример #13
0
void EncapsListExpression::outputCPPImpl(CodeGenerator &cg,
                                         AnalysisResultPtr ar) {
  if (m_type == '`') cg_printf("f_shell_exec(");

  if (m_exps) {
    for (int i = 0; i < m_exps->getCount(); i++) {
      ExpressionPtr exp = (*m_exps)[i];
      if (i > 0) cg_printf(" + ");
      if (exp->is(Expression::KindOfScalarExpression)) {
        cg_printf("toString(");
        exp->outputCPP(cg, ar);
        cg_printf(")");
      } else {
        exp->outputCPP(cg, ar);
      }
    }
  } else {
    cg_printf("\"\"");
  }

  if (m_type == '`') cg_printf(")");
}
static void outputStringExpr(CodeGenerator &cg, AnalysisResultPtr ar,
                             ExpressionPtr exp, bool asLitStr) {
  if (asLitStr && exp->isLiteralString()) {
    const std::string &s = exp->getLiteralString();
    std::string enc = string_cplus_escape(s.c_str(), s.size());
    cg_printf("\"%s\", %d", enc.c_str(), (int)s.size());
    return;
  }

  TypePtr et(exp->getExpectedType());
  exp->setExpectedType(Type::String);
  exp->outputCPP(cg, ar);
  exp->setExpectedType(et);
}
static void wrapValue(CodeGenerator &cg, AnalysisResultPtr ar,
                      ExpressionPtr exp, bool ref, bool array) {
  bool close = false;
  if (ref) {
    cg_printf("ref(");
    close = true;
  } else if (array && !exp->hasCPPTemp() &&
             !exp->isTemporary() && !exp->isScalar() &&
             exp->getActualType() && !exp->getActualType()->isPrimitive() &&
             exp->getActualType()->getKindOf() != Type::KindOfString) {
    cg_printf("wrap_variant(");
    close = true;
  }
  exp->outputCPP(cg, ar);
  if (close) cg_printf(")");
}
Пример #16
0
void ListAssignment::outputCPPAssignment(CodeGenerator &cg,
    AnalysisResultPtr ar, const string &arrTmp) {
  if (!m_variables) return;

  for (int i = m_variables->getCount() - 1; i >= 0; --i) {
    ExpressionPtr exp = (*m_variables)[i];
    if (exp) {
      if (exp->is(Expression::KindOfListAssignment)) {
        ListAssignmentPtr sublist = dynamic_pointer_cast<ListAssignment>(exp);
        string subTmp = genCPPTemp(cg, ar);
        cg.printf("Variant %s((ref(%s.rvalAt(%d))));\n", subTmp.c_str(),
                  arrTmp.c_str(), i);
        sublist->outputCPPAssignment(cg, ar, subTmp);
      } else {
        bool done = false;
        if (exp->is(Expression::KindOfArrayElementExpression)) {
          ArrayElementExpressionPtr arrExp =
            dynamic_pointer_cast<ArrayElementExpression>(exp);
          if (!arrExp->isSuperGlobal() && !arrExp->isDynamicGlobal()) {
            arrExp->getVariable()->outputCPP(cg, ar);
            if (arrExp->getOffset()) {
              cg.printf(".set(");
              arrExp->getOffset()->outputCPP(cg, ar);
              cg.printf(", ");
            } else {
              cg.printf(".append(");
            }
            cg.printf("%s.rvalAt(%d));\n", arrTmp.c_str(), i);
            done = true;
          }
        }
        if (!done) {
          exp->outputCPP(cg, ar);
          if (arrTmp == "null") {
            cg.printf(" = null;\n");
          } else {
            cg.printf(" = %s.rvalAt(%d);\n", arrTmp.c_str(), i);
          }
        }
      }
    }
  }
}
Пример #17
0
void ConstantTable::outputCPP(CodeGenerator &cg, AnalysisResultPtr ar) {
  bool decl = true;
  if (cg.getContext() == CodeGenerator::CppConstantsDecl) {
    decl = false;
  }

  bool printed = false;
  for (StringToConstructPtrMap::const_iterator iter = m_declarations.begin();
       iter != m_declarations.end(); ++iter) {
    const string &name = iter->first;
    if (isSystem(name) && cg.getOutput() != CodeGenerator::SystemCPP) continue;

    ConstructPtr value = getValue(name);
    if (isDynamic(name)) continue;
    printed = true;

    cg.printf(decl ? "extern const " : "const ");
    TypePtr type = getFinalType(name);
    if (type->is(Type::KindOfString)) {
      cg.printf("StaticString");
    } else {
      type->outputCPPDecl(cg, ar);
    }
    const char *nameStr = name.c_str();
    if (decl) {
      cg.printf(" %s%s", Option::ConstantPrefix, nameStr);
    } else {
      cg.printf(" %s%s = ", Option::ConstantPrefix, nameStr);
      if (value) {
        ExpressionPtr exp = dynamic_pointer_cast<Expression>(value);
        ASSERT(!exp->getExpectedType());
        exp->outputCPP(cg, ar);
      } else {
        cg.printf("\"%s\"", nameStr);
      }
    }
    cg.printf(";\n");
  }
  if (printed) {
    cg.printf("\n");
  }
}
static void outputStringExpr(CodeGenerator &cg, AnalysisResultPtr ar,
                             ExpressionPtr exp, bool asLitStr) {
  if (asLitStr && exp->isLiteralString()) {
    const std::string &s = exp->getLiteralString();
    char *enc = string_cplus_escape(s.c_str(), s.size());
    cg_printf("\"%s\", %d", enc, s.size());
    free(enc);
    return;
  }

  bool close = false;
  if ((exp->hasContext(Expression::LValue) &&
       (!exp->getActualType()->is(Type::KindOfString) ||
        (exp->getImplementedType() &&
         !exp->getImplementedType()->is(Type::KindOfString))))
      ||
      !exp->getType()->is(Type::KindOfString)) {
    cg_printf("toString(");
    close = true;
  }
  exp->outputCPP(cg, ar);
  if (close) cg_printf(")");
}
bool AssignmentExpression::SpecialAssignment(CodeGenerator &cg,
                                             AnalysisResultPtr ar,
                                             ExpressionPtr lval,
                                             ExpressionPtr rval,
                                             const char *rvalStr, bool ref) {
  if (lval->is(KindOfArrayElementExpression)) {
    ArrayElementExpressionPtr exp =
      dynamic_pointer_cast<ArrayElementExpression>(lval);
    if (!exp->isSuperGlobal() && !exp->isDynamicGlobal()) {
      exp->getVariable()->outputCPP(cg, ar);
      if (exp->getOffset()) {
        cg_printf(".set(");
        exp->getOffset()->outputCPP(cg, ar);
        cg_printf(", (");
      } else {
        cg_printf(".append((");
      }
      if (rval) {
        wrapValue(cg, ar, rval, ref,
                  (exp->getVariable()->is(KindOfArrayElementExpression) ||
                   exp->getVariable()->is(KindOfObjectPropertyExpression)) &&
                  (exp->getVariable()->getContainedEffects() &&
                   (CreateEffect|AccessorEffect)));
      } else {
        cg_printf(ref ? "ref(%s)" : "%s", rvalStr);
      }
      cg_printf(")");
      ExpressionPtr off = exp->getOffset();
      if (off) {
        ScalarExpressionPtr sc =
          dynamic_pointer_cast<ScalarExpression>(off);
        if (sc) {
          if (sc->isLiteralString()) {
            String s(sc->getLiteralString());
            int64 n;
            if (!s.get()->isStrictlyInteger(n)) {
              cg_printf(", true"); // skip toKey() at run time
            }
          }
        }
      }
      cg_printf(")");
      return true;
    }
  } else if (lval->is(KindOfObjectPropertyExpression)) {
    ObjectPropertyExpressionPtr var(
      dynamic_pointer_cast<ObjectPropertyExpression>(lval));
    if (!var->isValid()) {
      bool nonPrivate = var->isNonPrivate(ar);
      var->outputCPPObject(cg, ar);
      if (nonPrivate) {
        cg_printf("o_setPublic(");
      } else {
        cg_printf("o_set(");
      }
      var->outputCPPProperty(cg, ar);
      cg_printf(", %s", ref ? "ref(" : "");
      if (rval) {
        rval->outputCPP(cg, ar);
      } else {
        cg_printf(ref ? "ref(%s)" : "%s", rvalStr);
      }
      if (nonPrivate) {
        cg_printf("%s)", ref ? ")" : "");
      }
      else {
        cg_printf("%s%s)",
                  ref ? ")" : "",
                  lval->originalClassName(cg, true).c_str());
      }
      return true;
    }
  }
  return false;
}
Пример #20
0
void FunctionScope::outputCPPArguments(ExpressionListPtr params,
                                       CodeGenerator &cg,
                                       AnalysisResultPtr ar, int extraArg,
                                       bool variableArgument,
                                       int extraArgArrayId /* = -1 */,
                                       int extraArgArrayHash /* = -1 */,
                                       int extraArgArrayIndex /* = -1 */) {

  int paramCount = params ? params->getOutputCount() : 0;
  ASSERT(extraArg <= paramCount);
  int iMax = paramCount - extraArg;
  bool extra = false;

  if (variableArgument) {
    if (paramCount == 0) {
      cg_printf("0");
    } else {
      cg_printf("%d, ", paramCount);
    }
  }
  int firstExtra = 0;
  for (int i = 0; i < paramCount; i++) {
    ExpressionPtr param = (*params)[i];
    cg.setItemIndex(i);
    if (i > 0) cg_printf(extra ? "." : ", ");
    if (!extra && (i == iMax || extraArg < 0)) {
      if (extraArgArrayId != -1) {
        assert(extraArgArrayHash != -1 && extraArgArrayIndex != -1);
        ar->outputCPPScalarArrayId(cg, extraArgArrayId, extraArgArrayHash,
                                   extraArgArrayIndex);
        break;
      }
      extra = true;
      // Parameter arrays are always vectors.
      if (Option::GenArrayCreate &&
          cg.getOutput() != CodeGenerator::SystemCPP) {
        if (!params->hasNonArrayCreateValue(false, i)) {
          ar->m_arrayIntegerKeySizes.insert(paramCount - i);
          cg_printf("Array(");
          params->outputCPPUniqLitKeyArrayInit(cg, ar, paramCount - i,
                                               false, i);
          cg_printf(")");
          return;
        }
      }
      firstExtra = i;
      cg_printf("Array(ArrayInit(%d, true).", paramCount - i);
    }
    if (extra) {
      bool needRef = param->hasContext(Expression::RefValue) &&
                     !param->hasContext(Expression::NoRefWrapper) &&
                     param->isRefable();
      cg_printf("set%s(", needRef ? "Ref" : "");
      if (needRef) {
        // The parameter itself shouldn't be wrapped with ref() any more.
        param->setContext(Expression::NoRefWrapper);
      }
      param->outputCPP(cg, ar);
      cg_printf(")");
    } else {
      param->outputCPP(cg, ar);
    }
  }
  if (extra) {
    cg_printf(".create())");
  }
}
Пример #21
0
void ClassVariable::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {

  // bail out early if possible
  switch (cg.getContext()) {
  case CodeGenerator::CppConstructor:
  case CodeGenerator::CppInitializer:
    if (m_modifiers->isStatic()) return;
    break;
  default:
    return;
  }

  ClassScopePtr scope = getClassScope();
  bool derivFromRedec = scope->derivesFromRedeclaring() &&
    !m_modifiers->isPrivate();

  for (int i = 0; i < m_declaration->getCount(); i++) {
    ExpressionPtr exp = (*m_declaration)[i];
    SimpleVariablePtr var;
    TypePtr type;
    Symbol *sym;
    ExpressionPtr value;

    bool initInCtor = false;
    bool initInInit = false;
    getCtorAndInitInfo(exp, initInCtor, initInInit, var, type, sym, value);

    bool isAssign = exp->is(Expression::KindOfAssignmentExpression);
    bool isValueNull = isAssign ? value->isLiteralNull() : false;

    switch (cg.getContext()) {
    case CodeGenerator::CppConstructor:
      if (initInCtor) {
        if (!cg.hasInitListFirstElem()) {
          cg.setInitListFirstElem();
        } else {
          cg_printf(", ");
        }
        if (isAssign) {
          if (isValueNull) {
            cg_printf("%s%s(Variant::nullInit)",
                      Option::PropertyPrefix,
                      var->getName().c_str());
          } else {
            ASSERT(value);
            ASSERT(value->is(Expression::KindOfScalarExpression));
            cg_printf("%s%s(",
                      Option::PropertyPrefix,
                      var->getName().c_str());
            value->outputCPP(cg, ar);
            cg_printf(")");
          }
        } else {
          if (type->is(Type::KindOfVariant)) {
            cg_printf("%s%s(Variant::nullInit)",
                      Option::PropertyPrefix,
                      var->getName().c_str());
          } else {
            const char *initializer = type->getCPPInitializer();
            ASSERT(initializer);
            cg_printf("%s%s(%s)",
                      Option::PropertyPrefix,
                      var->getName().c_str(),
                      initializer);
          }
        }
      }
      break;
    case CodeGenerator::CppInitializer:
      if (initInInit) {
        if (isAssign) {
          value->outputCPPBegin(cg, ar);
          if (derivFromRedec) {
            cg_printf("%sset(", Option::ObjectPrefix);
            cg_printString(var->getName(), ar, shared_from_this());
            cg_printf(", ");
            value->outputCPP(cg, ar);
            cg_printf(")");
          } else if (isValueNull) {
            cg_printf("setNull(%s%s)", Option::PropertyPrefix,
                      var->getName().c_str());
          } else {
            cg_printf("%s%s = ", Option::PropertyPrefix, var->getName().c_str());
            value->outputCPP(cg, ar);
          }
          cg_printf(";\n");
          value->outputCPPEnd(cg, ar);
        } else {
          if (derivFromRedec) {
            cg_printf("%sset(", Option::ObjectPrefix);
            cg_printString(var->getName(), ar, shared_from_this());
            cg_printf(", null_variant);\n");
          } else {
            if (type->is(Type::KindOfVariant)) {
              cg_printf("setNull(%s%s);\n", Option::PropertyPrefix,
                        var->getName().c_str());
            } else {
              const char *initializer = type->getCPPInitializer();
              ASSERT(initializer);
              cg_printf("%s%s = %s;\n", Option::PropertyPrefix,
                        var->getName().c_str(), initializer);
            }
          }
        }
      }
      break;
    default:
      break;
    }
  }
}
Пример #22
0
void BinaryOpExpression::outputCPPImpl(CodeGenerator &cg,
                                       AnalysisResultPtr ar) {

    if (isOpEqual() && outputCPPImplOpEqual(cg, ar)) return;

    bool wrapped = true;
    switch (m_op) {
    case T_CONCAT_EQUAL:
        if (const char *prefix = stringBufferPrefix(cg, ar, m_exp1)) {
            SimpleVariablePtr sv = static_pointer_cast<SimpleVariable>(m_exp1);
            ExpressionPtrVec ev;
            bool hasVoid = false;
            getConcatList(ev, m_exp2, hasVoid);
            cg_printf("%s", stringBufferName(Option::TempPrefix, prefix,
                                             sv->getName().c_str()).c_str());
            outputStringBufExprs(ev, cg, ar);
            return;
        }
        cg_printf("concat_assign");
        break;
    case '.':
    {
        ExpressionPtr self = static_pointer_cast<Expression>(shared_from_this());
        ExpressionPtrVec ev;
        bool hasVoid = false;
        int num = getConcatList(ev, self, hasVoid);
        assert(!hasVoid);
        if (num <= MAX_CONCAT_ARGS) {
            assert(num >= 2);
            if (num == 2) {
                cg_printf("concat(");
            } else {
                if (num > MAX_CONCAT_ARGS) ar->m_concatLengths.insert(num);
                cg_printf("concat%d(", num);
            }
            for (size_t i = 0; i < ev.size(); i++) {
                ExpressionPtr exp = ev[i];
                if (i) cg_printf(", ");
                outputStringExpr(cg, ar, exp, false);
            }
            cg_printf(")");
        } else {
            cg_printf("StringBuffer()");
            outputStringBufExprs(ev, cg, ar);
            cg_printf(".detach()");
        }
    }
    return;
    case T_LOGICAL_XOR:
        cg_printf("logical_xor");
        break;
    case '|':
        cg_printf("bitwise_or");
        break;
    case '&':
        cg_printf("bitwise_and");
        break;
    case '^':
        cg_printf("bitwise_xor");
        break;
    case T_IS_IDENTICAL:
        cg_printf("same");
        break;
    case T_IS_NOT_IDENTICAL:
        cg_printf("!same");
        break;
    case T_IS_EQUAL:
        cg_printf("equal");
        break;
    case T_IS_NOT_EQUAL:
        cg_printf("!equal");
        break;
    case '<':
        cg_printf("less");
        break;
    case T_IS_SMALLER_OR_EQUAL:
        cg_printf("not_more");
        break;
    case '>':
        cg_printf("more");
        break;
    case T_IS_GREATER_OR_EQUAL:
        cg_printf("not_less");
        break;
    case '/':
        cg_printf("divide");
        break;
    case '%':
        cg_printf("modulo");
        break;
    case T_INSTANCEOF:
        cg_printf("instanceOf");
        break;
    default:
        wrapped = !isUnused();
        break;
    }

    if (wrapped) cg_printf("(");

    ExpressionPtr first = m_exp1;
    ExpressionPtr second = m_exp2;

    // we could implement these functions natively on String and Array classes
    switch (m_op) {
    case '+':
    case '-':
    case '*':
    case '/':
        if (!first->outputCPPArithArg(cg, ar, m_op == '+')) {
            TypePtr argType = first->hasCPPTemp() ?
                              first->getType() : first->getActualType();
            bool flag = castIfNeeded(getActualType(), argType, cg, ar, getScope());
            first->outputCPP(cg, ar);
            if (flag) {
                cg_printf(")");
            }
        }
        break;
    case T_SL:
    case T_SR:
        ASSERT(first->getType()->is(Type::KindOfInt64));
        first->outputCPP(cg, ar);
        break;
    default:
        first->outputCPP(cg, ar);
        break;
    }

    switch (m_op) {
    case T_PLUS_EQUAL:
        cg_printf(" += ");
        break;
    case T_MINUS_EQUAL:
        cg_printf(" -= ");
        break;
    case T_MUL_EQUAL:
        cg_printf(" *= ");
        break;
    case T_DIV_EQUAL:
        cg_printf(" /= ");
        break;
    case T_MOD_EQUAL:
        cg_printf(" %%= ");
        break;
    case T_AND_EQUAL:
        cg_printf(" &= ");
        break;
    case T_OR_EQUAL:
        cg_printf(" |= ");
        break;
    case T_XOR_EQUAL:
        cg_printf(" ^= ");
        break;
    case T_SL_EQUAL:
        cg_printf(" <<= ");
        break;
    case T_SR_EQUAL:
        cg_printf(" >>= ");
        break;
    case T_BOOLEAN_OR:
        cg_printf(" || ");
        break;
    case T_BOOLEAN_AND:
        cg_printf(" && ");
        break;
    case T_LOGICAL_OR:
        cg_printf(" || ");
        break;
    case T_LOGICAL_AND:
        cg_printf(" && ");
        break;
    default:
        switch (m_op) {
        case '+':
            cg_printf(" + ");
            break;
        case '-':
            cg_printf(" - ");
            break;
        case '*':
            cg_printf(" * ");
            break;
        case T_SL:
            cg_printf(" << ");
            break;
        case T_SR:
            cg_printf(" >> ");
            break;
        default:
            cg_printf(", ");
            break;
        }
        break;
    }

    switch (m_op) {
    case '+':
    case '-':
    case '*':
    case '/':
        if (!second->outputCPPArithArg(cg, ar, m_op == '+')) {
            TypePtr argType = second->hasCPPTemp() ?
                              second->getType() : second->getActualType();
            bool flag = castIfNeeded(getActualType(), argType, cg, ar, getScope());
            second->outputCPP(cg, ar);
            if (flag) {
                cg_printf(")");
            }
        }
        break;
    case T_INSTANCEOF:
    {
        if (second->isScalar()) {
            ScalarExpressionPtr scalar =
                dynamic_pointer_cast<ScalarExpression>(second);
            bool notQuoted = scalar && !scalar->isQuoted();
            std::string s = second->getLiteralString();
            if (s == "static" && notQuoted) {
                cg_printf("FrameInjection::GetStaticClassName(fi.getThreadInfo())");
            } else if (s != "") {
                if (s == "self" && notQuoted) {
                    ClassScopeRawPtr cls = getOriginalClass();
                    if (cls) {
                        s = cls->getOriginalName();
                    }
                } else if (s == "parent" && notQuoted) {
                    ClassScopeRawPtr cls = getOriginalClass();
                    if (cls && !cls->getParent().empty()) {
                        s = cls->getParent();
                    }
                }
                cg_printString(s, ar, shared_from_this());
            } else {
                second->outputCPP(cg, ar);
            }
        } else {
            second->outputCPP(cg, ar);
        }
        break;
    }
    case T_PLUS_EQUAL:
    case T_MINUS_EQUAL:
    case T_MUL_EQUAL:
    {
        TypePtr t1 = first->getCPPType();
        TypePtr t2 = second->getType();
        if (t1 && !t1->is(Type::KindOfArray) &&
                t2 && Type::IsCastNeeded(ar, t2, t1)) {
            t1->outputCPPCast(cg, ar, getScope());
            cg_printf("(");
            second->outputCPP(cg, ar);
            cg_printf(")");
        } else {
            second->outputCPP(cg, ar);
        }
        break;
    }
    case T_BOOLEAN_OR:
    case T_BOOLEAN_AND:
    case T_LOGICAL_AND:
    case T_LOGICAL_OR:
        if (isUnused()) {
            cg_printf("(");
            if (second->outputCPPUnneeded(cg, ar)) {
                cg_printf(",");
            }
            cg_printf("false)");
        } else {
            second->outputCPP(cg, ar);
        }
        break;
    default:
        second->outputCPP(cg, ar);
    }

    if (wrapped) cg_printf(")");
}
Пример #23
0
void ClassVariable::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  ClassScopePtr scope = ar->getClassScope();
  bool derivFromRedec = scope->derivesFromRedeclaring() &&
    !m_modifiers->isPrivate();
  for (int i = 0; i < m_declaration->getCount(); i++) {
    ExpressionPtr exp = (*m_declaration)[i];

    SimpleVariablePtr var;
    TypePtr type;

    switch (cg.getContext()) {
    case CodeGenerator::CppConstructor:
      if (m_modifiers->isStatic()) continue;

      if (exp->is(Expression::KindOfAssignmentExpression)) {
        AssignmentExpressionPtr assignment =
          dynamic_pointer_cast<AssignmentExpression>(exp);

        var = dynamic_pointer_cast<SimpleVariable>(assignment->getVariable());
        ExpressionPtr value = assignment->getValue();
        value->outputCPPBegin(cg, ar);
        if (derivFromRedec) {
          cg_printf("%sset(\"%s\",-1, ", Option::ObjectPrefix,
                    var->getName().c_str());
          value->outputCPP(cg, ar);
          cg_printf(")");
        } else {
          cg_printf("%s%s = ", Option::PropertyPrefix, var->getName().c_str());
          value->outputCPP(cg, ar);
        }
        cg_printf(";\n");
        value->outputCPPEnd(cg, ar);
      } else {
        var = dynamic_pointer_cast<SimpleVariable>(exp);
        if (derivFromRedec) {
          cg_printf("%sset(\"%s\",-1, null);\n", Option::ObjectPrefix,
                    var->getName().c_str());
        } else  {
          type = scope->getVariables()->getFinalType(var->getName());
          const char *initializer = type->getCPPInitializer();
          if (initializer) {
            cg_printf("%s%s = %s;\n", Option::PropertyPrefix,
                      var->getName().c_str(), initializer);
          }
        }
      }
      break;

    case CodeGenerator::CppStaticInitializer:
      {
        if (!m_modifiers->isStatic()) continue;

        VariableTablePtr variables = scope->getVariables();
        if (exp->is(Expression::KindOfAssignmentExpression)) {
          AssignmentExpressionPtr assignment =
            dynamic_pointer_cast<AssignmentExpression>(exp);

          var = dynamic_pointer_cast<SimpleVariable>
            (assignment->getVariable());
          ExpressionPtr value = assignment->getValue();
          if (value->containsDynamicConstant(ar)) continue;
          cg_printf("g->%s%s%s%s = ",
                    Option::StaticPropertyPrefix, scope->getId(cg).c_str(),
                    Option::IdPrefix.c_str(), var->getName().c_str());

          value->outputCPP(cg, ar);
        } else {
          var = dynamic_pointer_cast<SimpleVariable>(exp);
          type = scope->getVariables()->getFinalType(var->getName());
          const char *initializer = type->getCPPInitializer();
          if (initializer) {
            cg_printf("g->%s%s%s%s = %s",
                      Option::StaticPropertyPrefix, scope->getId(cg).c_str(),
                      Option::IdPrefix.c_str(), var->getName().c_str(),
                      initializer);
          }
        }
        cg_printf(";\n");
      }
      break;
    case CodeGenerator::CppLazyStaticInitializer:
      {
        if (!m_modifiers->isStatic()) continue;
        if (!exp->is(Expression::KindOfAssignmentExpression)) continue;
        VariableTablePtr variables = scope->getVariables();
        AssignmentExpressionPtr assignment =
          dynamic_pointer_cast<AssignmentExpression>(exp);
        var = dynamic_pointer_cast<SimpleVariable>(assignment->getVariable());
        ExpressionPtr value = assignment->getValue();
        if (!value->containsDynamicConstant(ar)) continue;
        value->outputCPPBegin(cg, ar);
        cg_printf("g->%s%s%s%s = ",
                  Option::StaticPropertyPrefix, scope->getId(cg).c_str(),
                  Option::IdPrefix.c_str(), var->getName().c_str());
        value->outputCPP(cg, ar);
        cg_printf(";\n");
        value->outputCPPEnd(cg, ar);
      }
      break;
    default:
      break;
    }
  }
}
void BinaryOpExpression::outputCPPImpl(CodeGenerator &cg,
                                       AnalysisResultPtr ar) {

  if (isOpEqual() && outputCPPImplOpEqual(cg, ar)) return;

  bool wrapped = true;
  switch (m_op) {
  case T_CONCAT_EQUAL:
    if (const char *prefix = stringBufferPrefix(cg, ar, m_exp1)) {
      SimpleVariablePtr sv = static_pointer_cast<SimpleVariable>(m_exp1);
      ExpressionPtrVec ev;
      bool hasVoid = false;
      getConcatList(ev, m_exp2, hasVoid);
      cg_printf("%s", stringBufferName(Option::TempPrefix, prefix,
                                       sv->getName().c_str()).c_str());
      outputStringBufExprs(ev, cg, ar);
      return;
    }
    cg_printf("concat_assign");
    break;
  case '.':
    {
      ExpressionPtr self = static_pointer_cast<Expression>(shared_from_this());
      ExpressionPtrVec ev;
      bool hasVoid = false;
      int num = getConcatList(ev, self, hasVoid);
      assert(!hasVoid);
      if ((num <= MAX_CONCAT_ARGS ||
           (Option::GenConcat &&
            cg.getOutput() != CodeGenerator::SystemCPP))) {
        assert(num >= 2);
        if (num == 2) {
          cg_printf("concat(");
        } else {
          if (num > MAX_CONCAT_ARGS) ar->m_concatLengths.insert(num);
          cg_printf("concat%d(", num);
        }
        for (size_t i = 0; i < ev.size(); i++) {
          ExpressionPtr exp = ev[i];
          if (i) cg_printf(", ");
          outputStringExpr(cg, ar, exp, false);
        }
        cg_printf(")");
      } else {
        cg_printf("StringBuffer()");
        outputStringBufExprs(ev, cg, ar);
        cg_printf(".detach()");
      }
    }
    return;
  case T_LOGICAL_XOR:         cg_printf("logical_xor");   break;
  case '|':                   cg_printf("bitwise_or");    break;
  case '&':                   cg_printf("bitwise_and");   break;
  case '^':                   cg_printf("bitwise_xor");   break;
  case T_IS_IDENTICAL:        cg_printf("same");          break;
  case T_IS_NOT_IDENTICAL:    cg_printf("!same");         break;
  case T_IS_EQUAL:            cg_printf("equal");         break;
  case T_IS_NOT_EQUAL:        cg_printf("!equal");        break;
  case '<':                   cg_printf("less");          break;
  case T_IS_SMALLER_OR_EQUAL: cg_printf("not_more");      break;
  case '>':                   cg_printf("more");          break;
  case T_IS_GREATER_OR_EQUAL: cg_printf("not_less");      break;
  case '/':                   cg_printf("divide");        break;
  case '%':                   cg_printf("modulo");        break;
  case T_INSTANCEOF:          cg_printf("instanceOf");    break;
  default:
    wrapped = !isUnused();
    break;
  }

  if (wrapped) cg_printf("(");

  ExpressionPtr first = m_exp1;
  ExpressionPtr second = m_exp2;

  // we could implement these functions natively on String and Array classes
  switch (m_op) {
  case '+':
  case '-':
  case '*':
  case '/': {
    TypePtr actualType = first->getActualType();

    if (actualType &&
        (actualType->is(Type::KindOfString) ||
         (m_op != '+' && actualType->is(Type::KindOfArray)))) {
      cg_printf("(Variant)(");
      first->outputCPP(cg, ar);
      cg_printf(")");
    } else {
      bool flag = castIfNeeded(getActualType(), actualType, cg, ar, getScope());
      first->outputCPP(cg, ar);
      if (flag) {
        cg_printf(")");
      }
    }
    break;
  }
  case T_SL:
  case T_SR:
    cg_printf("toInt64(");
    first->outputCPP(cg, ar);
    cg_printf(")");
    break;
  default:
    first->outputCPP(cg, ar);
    break;
  }

  switch (m_op) {
  case T_PLUS_EQUAL:          cg_printf(" += ");   break;
  case T_MINUS_EQUAL:         cg_printf(" -= ");   break;
  case T_MUL_EQUAL:           cg_printf(" *= ");   break;
  case T_DIV_EQUAL:           cg_printf(" /= ");   break;
  case T_MOD_EQUAL:           cg_printf(" %%= ");  break;
  case T_AND_EQUAL:           cg_printf(" &= ");   break;
  case T_OR_EQUAL:            cg_printf(" |= ");   break;
  case T_XOR_EQUAL:           cg_printf(" ^= ");   break;
  case T_SL_EQUAL:            cg_printf(" <<= ");  break;
  case T_SR_EQUAL:            cg_printf(" >>= ");  break;
  case T_BOOLEAN_OR:          cg_printf(" || ");   break;
  case T_BOOLEAN_AND:         cg_printf(" && ");   break;
  case T_LOGICAL_OR:          cg_printf(" || ");   break;
  case T_LOGICAL_AND:         cg_printf(" && ");   break;
  default:
    switch (m_op) {
    case '+':                   cg_printf(" + ");    break;
    case '-':                   cg_printf(" - ");    break;
    case '*':                   cg_printf(" * ");    break;
    case T_SL:                  cg_printf(" << ");   break;
    case T_SR:                  cg_printf(" >> ");   break;
    default:
      cg_printf(", ");
      break;
    }
    break;
  }

  switch (m_op) {
  case '+':
  case '-':
  case '*':
  case '/': {
    TypePtr actualType = second->getActualType();

    if (actualType &&
        (actualType->is(Type::KindOfString) ||
         (m_op != '+' && actualType->is(Type::KindOfArray)))) {
      cg_printf("(Variant)(");
      second->outputCPP(cg, ar);
      cg_printf(")");
    } else {
      bool flag = castIfNeeded(getActualType(), actualType, cg, ar, getScope());
      second->outputCPP(cg, ar);
      if (flag) {
        cg_printf(")");
      }
    }
    break;
  }
  case T_INSTANCEOF:
    {
      if (second->isScalar()) {
        std::string s = second->getLiteralString();
        std::string sLower = Util::toLower(s);
        if (sLower != "") {
          cg_printString(sLower, ar, shared_from_this());
        } else {
          second->outputCPP(cg, ar);
        }
      } else {
        second->outputCPP(cg, ar);
      }
      break;
    }
  case T_PLUS_EQUAL:
  case T_MINUS_EQUAL:
  case T_MUL_EQUAL:
    {
      TypePtr t1 = first->getCPPType();
      TypePtr t2 = second->getType();
      if (t1 && !t1->is(Type::KindOfArray) &&
          t2 && Type::IsCastNeeded(ar, t2, t1)) {
        t1->outputCPPCast(cg, ar, getScope());
        cg_printf("(");
        second->outputCPP(cg, ar);
        cg_printf(")");
      } else {
        second->outputCPP(cg, ar);
      }
      break;
    }
  case T_BOOLEAN_OR:
  case T_BOOLEAN_AND:
  case T_LOGICAL_AND:
  case T_LOGICAL_OR:
    if (isUnused()) {
      cg_printf("(");
      if (second->outputCPPUnneeded(cg, ar)) {
        cg_printf(",");
      }
      cg_printf("false)");
    } else {
      second->outputCPP(cg, ar);
    }
    break;
  default:
    second->outputCPP(cg, ar);
  }

  if (wrapped) cg_printf(")");
}
bool UnaryOpExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                     int state) {

  if (m_op == T_ISSET && m_exp && m_exp->is(Expression::KindOfExpressionList)) {
    ExpressionListPtr exps = dynamic_pointer_cast<ExpressionList>(m_exp);
    int count = exps->getCount();
    if (count > 1) {
      bool fix_e1 = (*exps)[0]->preOutputCPP(cg, ar, 0);
      bool inExpression = ar->inExpression();
      ar->setInExpression(false);
      bool fix_en = false;
      for (int i = 1; i < count; i++) {
        if ((*exps)[i]->preOutputCPP(cg, ar, 0)) {
          fix_en = true;
          break;
        }
      }
      ar->setInExpression(inExpression);
      if (inExpression && fix_en) {
        ar->wrapExpressionBegin(cg);
        std::string tmp = genCPPTemp(cg, ar);
        cg_printf("bool %s = (", tmp.c_str());
        (*exps)[0]->outputCPPExistTest(cg, ar, m_op);
        cg_printf(");\n");
        for (int i = 1; i < count; i++) {
          cg_indentBegin("if (%s) {\n", tmp.c_str());
          ExpressionPtr e = (*exps)[i];
          e->preOutputCPP(cg, ar, 0);
          cg_printf("%s = (", tmp.c_str());
          e->outputCPPExistTest(cg, ar, m_op);
          cg_printf(");\n");
        }
        for (int i = 1; i < count; i++) {
          cg_indentEnd("}\n");
        }
        m_cppTemp = tmp;
      } else if (state & FixOrder) {
        preOutputStash(cg, ar, state);
        fix_e1 = true;
      }
      return fix_e1 || fix_en;
    }
  }

  if (m_op == '@') {
    if (isUnused()) m_exp->setUnused(true);
    bool inExpression = ar->inExpression();
    bool doit = state & FixOrder;
    if (!doit) {
      ar->setInExpression(false);
      if (m_exp->preOutputCPP(cg, ar, state)) {
        doit = true;
      }
      ar->setInExpression(inExpression);
    }
    if (doit && inExpression) {
      cg_printf("%s%d.enable();\n", Option::SilencerPrefix, m_silencer);
      m_exp->preOutputCPP(cg, ar, 0);
      int s = m_silencer;
      m_silencer = -1;
      this->preOutputStash(cg, ar, state | FixOrder);
      m_silencer = s;
      cg_printf("%s%d.disable();\n", Option::SilencerPrefix, m_silencer);
    }
    return doit;
  } else if (m_op == T_PRINT && m_exp && !m_exp->hasEffect()) {
    ExpressionPtrVec ev;
    bool hasVoid = false;
    if (BinaryOpExpression::getConcatList(ev, m_exp, hasVoid) > 1 ||
        hasVoid ) {

      if (!ar->inExpression()) return true;
      ar->wrapExpressionBegin(cg);
      for (int i = 0, s = ev.size(); i < s; i++) {
        ExpressionPtr e = ev[i];
        e->preOutputCPP(cg, ar, 0);
        cg_printf("print(");
        e->outputCPP(cg, ar);
        cg_printf(");\n");
      }
      m_cppTemp = "1";
      return true;
    }
  }

  return Expression::preOutputCPP(cg, ar, state);
}
Пример #26
0
void ClassConstant::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  bool lazyInit = cg.getContext() == CodeGenerator::CppLazyStaticInitializer;
  if (cg.getContext() != CodeGenerator::CppClassConstantsDecl &&
      cg.getContext() != CodeGenerator::CppClassConstantsImpl &&
      !lazyInit) {
    return;
  }

  ClassScopePtr scope = getClassScope();
  for (int i = 0; i < m_exp->getCount(); i++) {
    AssignmentExpressionPtr exp =
      dynamic_pointer_cast<AssignmentExpression>((*m_exp)[i]);
    ConstantExpressionPtr var =
      dynamic_pointer_cast<ConstantExpression>(exp->getVariable());
    TypePtr type = scope->getConstants()->getFinalType(var->getName());
    ExpressionPtr value = exp->getValue();
    if (!scope->getConstants()->isDynamic(var->getName()) == lazyInit) {
        continue;
    }
    switch (cg.getContext()) {
    case CodeGenerator::CppClassConstantsDecl:
      cg_printf("extern const ");
      if (type->is(Type::KindOfString)) {
        cg_printf("StaticString");
      } else {
        type->outputCPPDecl(cg, ar, getScope());
      }
      cg_printf(" %s%s_%s;\n", Option::ClassConstantPrefix,
                scope->getId(cg).c_str(),
                var->getName().c_str());
      break;
    case CodeGenerator::CppClassConstantsImpl: {
      cg_printf("const ");
      bool isString = type->is(Type::KindOfString);
      if (isString) {
        cg_printf("StaticString");
      } else {
        type->outputCPPDecl(cg, ar, getScope());
      }
      value->outputCPPBegin(cg, ar);
      cg_printf(" %s%s_%s", Option::ClassConstantPrefix,
                scope->getId(cg).c_str(),
                var->getName().c_str());
      cg_printf(isString ? "(" : " = ");
      ScalarExpressionPtr scalarExp =
        dynamic_pointer_cast<ScalarExpression>(value);
      if (isString && scalarExp) {
        cg_printf("LITSTR_INIT(%s)",
                  scalarExp->getCPPLiteralString(cg).c_str());
      } else {
        value->outputCPP(cg, ar);
      }
      cg_printf(isString ? ");\n" : ";\n");
      value->outputCPPEnd(cg, ar);
      break;
    }
    case CodeGenerator::CppLazyStaticInitializer:
      value->outputCPPBegin(cg, ar);
      cg_printf("g->%s%s_%s = ", Option::ClassConstantPrefix,
                scope->getId(cg).c_str(),
                var->getName().c_str());
      value->outputCPP(cg, ar);
      cg_printf(";\n");
      value->outputCPPEnd(cg, ar);
      break;
    default:
      ASSERT(false);
    }
  }
}
Пример #27
0
void ClassConstant::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  if (cg.getContext() != CodeGenerator::CppClassConstantsDecl &&
      cg.getContext() != CodeGenerator::CppClassConstantsImpl) {
    return;
  }

  ClassScopePtr scope = getClassScope();
  for (int i = 0; i < m_exp->getCount(); i++) {
    AssignmentExpressionPtr exp =
      dynamic_pointer_cast<AssignmentExpression>((*m_exp)[i]);
    ConstantExpressionPtr var =
      dynamic_pointer_cast<ConstantExpression>(exp->getVariable());
    TypePtr type = scope->getConstants()->getFinalType(var->getName());
    ExpressionPtr value = exp->getValue();
    if (scope->getConstants()->isDynamic(var->getName())) {
        continue;
    }
    switch (cg.getContext()) {
    case CodeGenerator::CppClassConstantsDecl:
      cg_printf("extern const ");
      if (type->is(Type::KindOfString)) {
        cg_printf("StaticString");
      } else {
        type->outputCPPDecl(cg, ar, getScope());
      }
      cg_printf(" %s%s%s%s;\n",
                Option::ClassConstantPrefix, scope->getId().c_str(),
                Option::IdPrefix.c_str(), var->getName().c_str());
      break;
    case CodeGenerator::CppClassConstantsImpl: {
      bool isString = type->is(Type::KindOfString);
      bool isVariant = Type::IsMappedToVariant(type);
      ScalarExpressionPtr scalarExp =
        dynamic_pointer_cast<ScalarExpression>(value);
      bool stringForVariant = false;
      if (isVariant && scalarExp &&
          scalarExp->getActualType() &&
          scalarExp->getActualType()->is(Type::KindOfString)) {
        cg_printf("static const StaticString %s%s%s%s%sv(LITSTR_INIT(%s));\n",
                  Option::ClassConstantPrefix, scope->getId().c_str(),
                  Option::IdPrefix.c_str(), var->getName().c_str(),
                  Option::IdPrefix.c_str(),
                  scalarExp->getCPPLiteralString().c_str());
        stringForVariant = true;
      }
      cg_printf("const ");
      if (isString) {
        cg_printf("StaticString");
      } else {
        type->outputCPPDecl(cg, ar, getScope());
      }
      value->outputCPPBegin(cg, ar);
      cg_printf(" %s%s%s%s",
                Option::ClassConstantPrefix, scope->getId().c_str(),
                Option::IdPrefix.c_str(), var->getName().c_str());
      cg_printf(isString ? "(" : " = ");
      if (stringForVariant) {
        cg_printf("%s%s%s%s%sv",
                  Option::ClassConstantPrefix, scope->getId().c_str(),
                  Option::IdPrefix.c_str(), var->getName().c_str(),
                  Option::IdPrefix.c_str());
      } else if (isString && scalarExp) {
        cg_printf("LITSTR_INIT(%s)",
                  scalarExp->getCPPLiteralString().c_str());
      } else {
        value->outputCPP(cg, ar);
      }
      cg_printf(isString ? ");\n" : ";\n");
      value->outputCPPEnd(cg, ar);
      break;
    }
    default:
      assert(false);
    }
  }
}
Пример #28
0
void SimpleFunctionCall::outputCPPImpl(CodeGenerator &cg,
                                       AnalysisResultPtr ar) {
  bool linemap = outputLineMap(cg, ar, true);

  if (!m_lambda.empty()) {
    cg.printf("\"%s\"", m_lambda.c_str());
    if (linemap) cg.printf(")");
    return;
  }

  if (m_className.empty()) {
    if (m_type == DefineFunction && m_params && m_params->getCount() >= 2) {
      ScalarExpressionPtr name =
        dynamic_pointer_cast<ScalarExpression>((*m_params)[0]);
      string varName;
      if (name) {
        varName = name->getIdentifier();
        ExpressionPtr value = (*m_params)[1];
        if (varName.empty()) {
          cg.printf("throw_fatal(\"bad define\")");
        } else if (m_dynamicConstant) {
          cg.printf("g->declareConstant(\"%s\", g->%s%s, ",
                    varName.c_str(), Option::ConstantPrefix,
                    varName.c_str());
          value->outputCPP(cg, ar);
          cg.printf(")");
        } else {
          bool needAssignment = true;
          bool isSystem = ar->getConstants()->isSystem(varName);
          if (isSystem ||
              ((!ar->isConstantRedeclared(varName)) && value->isScalar())) {
            needAssignment = false;
          }
          if (needAssignment) {
            cg.printf("%s%s = ", Option::ConstantPrefix, varName.c_str());
            value->outputCPP(cg, ar);
          }
        }
      } else {
        cg.printf("throw_fatal(\"bad define\")");
      }
      if (linemap) cg.printf(")");
      return;
    }
    if (m_name == "func_num_args") {
      cg.printf("num_args");
      if (linemap) cg.printf(")");
      return;
    }

    switch (m_type) {
    case VariableArgumentFunction:
      {
        FunctionScopePtr func =
          dynamic_pointer_cast<FunctionScope>(ar->getScope());
        if (func) {
          cg.printf("%s(", m_name.c_str());
          func->outputCPPParamsCall(cg, ar, true);
          if (m_params) {
            cg.printf(",");
            m_params->outputCPP(cg, ar);
          }
          cg.printf(")");
          if (linemap) cg.printf(")");
          return;
        }
      }
      break;
    case FunctionExistsFunction:
    case ClassExistsFunction:
    case InterfaceExistsFunction:
      {
        bool literalString = false;
        string symbol;
        if (m_params && m_params->getCount() == 1) {
          ExpressionPtr value = (*m_params)[0];
          if (value->isScalar()) {
            ScalarExpressionPtr name =
              dynamic_pointer_cast<ScalarExpression>(value);
            if (name && name->isLiteralString()) {
              literalString = true;
              symbol = name->getLiteralString();
            }
          }
        }
        if (literalString) {
          switch (m_type) {
          case FunctionExistsFunction:
            {
              const std::string &lname = Util::toLower(symbol);
              bool dynInvoke = Option::DynamicInvokeFunctions.find(lname) !=
                Option::DynamicInvokeFunctions.end();
              if (!dynInvoke) {
                FunctionScopePtr func = ar->findFunction(lname);
                if (func) {
                  if (!func->isDynamic()) {
                    if (func->isRedeclaring()) {
                      const char *name = func->getName().c_str();
                      cg.printf("(%s->%s%s != invoke_failed_%s)",
                                cg.getGlobals(ar), Option::InvokePrefix,
                                name, name);
                      break;
                    }
                    cg.printf("true");
                    break;
                  }
                } else {
                  cg.printf("false");
                  break;
                }
              }
              cg.printf("f_function_exists(\"%s\")", lname.c_str());
            }
            break;
          case ClassExistsFunction:
            {
              ClassScopePtr cls = ar->findClass(Util::toLower(symbol));
              if (cls && !cls->isInterface()) {
                const char *name = cls->getName().c_str();
                cg.printf("f_class_exists(\"%s\")", name);
              } else {
                cg.printf("false");
              }
            }
            break;
          case InterfaceExistsFunction:
            {
              ClassScopePtr cls = ar->findClass(Util::toLower(symbol));
              if (cls && cls->isInterface()) {
                const char *name = cls->getName().c_str();
                cg.printf("f_interface_exists(\"%s\")", name);
              } else {
                cg.printf("false");
              }
            }
            break;
          default:
            break;
          }
          if (linemap) cg.printf(")");
          return;
        }
      }
      break;
    case GetDefinedVarsFunction:
      cg.printf("get_defined_vars(variables)");
      if (linemap) cg.printf(")");
      return;
    default:
      break;
    }
  }

  outputCPPParamOrderControlled(cg, ar);
  if (linemap) cg.printf(")");
}