Пример #1
0
bool BinaryOpExpression::outputCPPImplOpEqual(CodeGenerator &cg,
                                              AnalysisResultPtr ar) {
  if (!m_exp1->is(Expression::KindOfArrayElementExpression)) return false;
  ArrayElementExpressionPtr exp =
    dynamic_pointer_cast<ArrayElementExpression>(m_exp1);
  if (exp->isSuperGlobal() || exp->isDynamicGlobal()) return false;
  bool linemap = outputLineMap(cg, ar);

  // turning $a['elem'] Op= $b into $a.setOpEqual('elem', $b);
  exp->getVariable()->outputCPP(cg, ar);
  if (exp->getOffset()) {
    cg_printf(".setOpEqual(%d, ", m_op);
    exp->getOffset()->outputCPP(cg, ar);
    cg_printf(", (");
  } else {
    cg_printf(".appendOpEqual(%d, (", m_op);
  }
  m_exp2->outputCPP(cg, ar);
  cg_printf(")");
  ExpressionPtr off = exp->getOffset();
  if (off) {
    ScalarExpressionPtr sc = dynamic_pointer_cast<ScalarExpression>(off);
    if (sc) {
      int64 hash = sc->getHash();
      if (hash >= 0) {
        cg_printf(", 0x%016llXLL", hash);
      } else {
        cg_printf(", -1");
      }
      if (sc->isLiteralString()) {
        String s(sc->getLiteralString());
        int64 n;
        if (!s.get()->isStrictlyInteger(n)) {
          cg_printf(", true"); // skip toKey() at run time
        }
      }
    }
  }
  cg_printf(")");

  if (linemap) cg_printf(")");
  return true;
}
void ArrayElementExpression::outputCPPUnset(CodeGenerator &cg,
                                            AnalysisResultPtr ar) {
  if (isSuperGlobal()) {
    Expression::outputCPPUnset(cg, ar);
  } else {
    m_variable->outputCPP(cg, ar);
    cg.printf(".weakRemove(");
    m_offset->outputCPP(cg, ar);
    ScalarExpressionPtr sc =
      dynamic_pointer_cast<ScalarExpression>(m_offset);
    if (sc) {
      int64 hash = sc->getHash();
      if (hash >= 0) {
        cg.printf(", 0x%016llXLL", hash);
      }
    }
    cg.printf(");\n");
  }
}
void ArrayElementExpression::outputCPPExistTest(CodeGenerator &cg,
                                                AnalysisResultPtr ar, int op) {
  switch (op) {
  case T_ISSET:  cg_printf("isset("); break;
  case T_EMPTY:  cg_printf("empty("); break;
  default: ASSERT(false);
  }

  if (m_global) {
    if (!m_globalName.empty()) {
      VariableTablePtr variables = ar->getScope()->getVariables();
      string name = variables->getGlobalVariableName(cg, ar, m_globalName);
      cg_printf("g->%s", name.c_str());
    } else {
      cg_printf("get_variable_table()->get(");
      m_offset->outputCPP(cg, ar);
      cg_printf(")");
    }
  } else {
    m_variable->outputCPP(cg, ar);
    cg_printf(", ");
    m_offset->outputCPP(cg, ar);
    ScalarExpressionPtr sc =
      dynamic_pointer_cast<ScalarExpression>(m_offset);
    if (sc) {
      int64 hash = sc->getHash();
      if (hash >= 0) {
        cg_printf(", 0x%016llXLL", hash);
      }
      if (sc->isLiteralString()) {
        String s(sc->getLiteralString());
        int64 n;
        if (!s.get()->isStrictlyInteger(n)) {
          cg_printf(", true"); // skip toKey() at run time
        }
      }
    }
  }
  cg_printf(")");
}
void ArrayElementExpression::outputCPPUnset(CodeGenerator &cg,
                                            AnalysisResultPtr ar) {
  if (isSuperGlobal()) {
    Expression::outputCPPUnset(cg, ar);
  } else {
    TypePtr expected = m_variable->getExpectedType();
    TypePtr implemented = m_variable->getImplementedType();
    bool wrap = false;
    if (TypePtr t = m_variable->getActualType()) {
      if (t->is(Type::KindOfObject)) {
        if (!m_variable->getImplementedType() ||
            !m_variable->getImplementedType()->is(Type::KindOfVariant)) {
          cg_printf("((Variant)(");
          wrap = true;
        }
        m_variable->setImplementedType(TypePtr());
        m_variable->setExpectedType(TypePtr());
      }
    }
    m_variable->outputCPP(cg, ar);
    if (wrap) cg_printf("))");
    m_variable->setExpectedType(expected);
    m_variable->setImplementedType(implemented);
    cg_printf(".weakRemove(");
    m_offset->outputCPP(cg, ar);
    ScalarExpressionPtr sc =
      dynamic_pointer_cast<ScalarExpression>(m_offset);
    if (sc) {
      int64 hash = sc->getHash();
      if (hash >= 0) {
        cg_printf(", 0x%016llXLL", hash);
      }
    }
    cg_printf(")");
  }
}
void ArrayElementExpression::outputCPPImpl(CodeGenerator &cg,
                                           AnalysisResultPtr ar) {
  if (m_global) {
    if (!m_globalName.empty()) {
      VariableTablePtr variables = ar->getScope()->getVariables();
      string name = variables->getGlobalVariableName(cg, ar, m_globalName);
      cg_printf("g->%s", name.c_str());
    } else {
      cg_printf("get_variable_table()->get(");
      m_offset->outputCPP(cg, ar);
      cg_printf(")");
    }
  } else {
    TypePtr type = m_variable->getActualType();
    if (hasContext(UnsetContext)) {
      cg_printf("unsetLval(");
      m_variable->outputCPP(cg, ar);
      cg_printf(", ");
    } else {
      if (m_variable->is(Expression::KindOfScalarExpression) ||
          (type && (type->isInteger() ||
                    type->is(Type::KindOfDouble) ||
                    type->is(Type::KindOfObject) ||
                    type->is(Type::KindOfBoolean)))) {
        cg_printf(type && type->is(Type::KindOfString) ? "((String)" :
                  "((Variant)");
        m_variable->outputCPP(cg, ar);
        cg_printf(")");
      } else {
        m_variable->outputCPP(cg, ar);
      }
    }
    if (m_offset) {
      bool lvalAt = false;
      bool rvalAt = false;
      if (hasContext(UnsetContext)) {
        // do nothing
      } else if (m_context & InvokeArgument) {
        cg_printf(".refvalAt(");
      } else if (m_context & (LValue|RefValue)) {
        cg_printf(".lvalAt(");
        lvalAt = true;
      } else {
        cg_printf(".rvalAt(");
        rvalAt = true;
      }
      m_offset->outputCPP(cg, ar);
      if (!type || !type->is(Type::KindOfString)) {
        bool prehashed = false;
        ScalarExpressionPtr sc =
          dynamic_pointer_cast<ScalarExpression>(m_offset);
        if (sc) {
          int64 hash = sc->getHash();
          if (hash >= 0) {
            cg_printf(", 0x%016llXLL", hash);
            prehashed = true;
          }
        }
        if (!prehashed) {
          cg_printf(", -1");
        }
        if (rvalAt) {
          if (!hasContext(ExistContext)) {
            cg_printf(", true"); // raise undefined index error
          } else {
            cg_printf(", false");
          }
        } else if (lvalAt) {
          if (hasContext(ObjectContext)) {
            // object target might not trigger an array copy
            cg_printf(", true");
          } else {
            cg_printf(", false");
          }
        }
        if (!hasContext(UnsetContext) && sc && sc->isLiteralString()) {
          String s(sc->getLiteralString());
          int64 n;
          if (!s.get()->isStrictlyInteger(n)) {
            cg_printf(", true"); // skip toKey() at run time
          }
        }
      }
      cg_printf(")");
    } else {
      cg_printf(".lvalAt()");
    }
  }
}
Пример #6
0
void AssignmentExpression::outputCPPImpl(CodeGenerator &cg,
                                         AnalysisResultPtr ar) {
  BlockScopePtr scope = ar->getScope();
  bool ref = (m_ref && !m_value->is(Expression::KindOfNewObjectExpression));

  bool setElement = false; // turning $a['elem'] = $b into $a.set('elem', $b);
  bool type_cast = false;
  bool setNull = false;
  TypePtr m_actualType;

  if (m_variable->is(Expression::KindOfArrayElementExpression)) {
    ArrayElementExpressionPtr exp =
      dynamic_pointer_cast<ArrayElementExpression>(m_variable);
    m_actualType = m_variable->getActualType();
    if (m_actualType && m_actualType->getKindOf() == Type::KindOfVariant
        && !ref) {
      //type_cast = true;
    }
    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 (type_cast) {
        m_actualType->outputCPPCast(cg, ar);
        cg.printf("(");
      }
      if (ref && m_value->isRefable()) cg.printf("ref(");
      m_value->outputCPP(cg, ar);
      if (ref && m_value->isRefable()) cg.printf(")");
      if (type_cast) cg.printf(")");
      cg.printf(")");
      ExpressionPtr off = exp->getOffset();
      if (off) {
        ScalarExpressionPtr sc =
          dynamic_pointer_cast<ScalarExpression>(off);
        if (sc) {
          int64 hash = sc->getHash();
          if (hash >= 0) {
            cg.printf(", 0x%016llXLL", hash);
          } else {
            cg.printf(", -1");
          }
          if (sc->isLiteralString()) {
            String s(sc->getLiteralString());
            int64 n;
            if (!s.get()->isStrictlyInteger(n)) {
              cg.printf(", true"); // skip toKey() at run time
            }
          }
        }
      }
      cg.printf(")");
      setElement = true;
    }
  }
  if (m_variable->is(Expression::KindOfSimpleVariable) &&
      m_value->is(Expression::KindOfConstantExpression)) {
    ConstantExpressionPtr exp =
      dynamic_pointer_cast<ConstantExpression>(m_value);
    if (exp->isNull()) setNull = true;
  }

  if (!setElement) {
    if (setNull) {
      cg.printf("setNull(");
      m_variable->outputCPP(cg, ar);
    } else {
      cg.printf("(");
      m_variable->outputCPP(cg, ar);
      cg.printf(" = ");

      if (type_cast) {
        m_actualType->outputCPPCast(cg, ar);
        cg.printf("(");
      }
      if (ref && m_value->isRefable()) cg.printf("ref(");
      m_value->outputCPP(cg, ar);
      if (ref && m_value->isRefable()) cg.printf(")");
      if (type_cast) cg.printf(")");
    }
    cg.printf(")");
  }
}