Example #1
0
void WhileStatement::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  int labelId = cg.createNewId(ar);
  cg.pushBreakScope(labelId);
  cg.indentBegin("{\n");

  bool e_order = m_condition->preOutputCPP(cg, ar, 0);

  cg.printf("while (");
  if (e_order) {
    cg.printf("true");
  } else {
    m_condition->outputCPP(cg, ar);
  }
  cg.indentBegin(") {\n");
  if (e_order) {
    m_condition->outputCPPBegin(cg, ar);
    cg.printf("if (!(");
    m_condition->outputCPP(cg, ar);
    cg.printf(")) break;\n");
    m_condition->outputCPPEnd(cg, ar);
  }
  cg.printf("LOOP_COUNTER_CHECK(%d);\n", labelId);
  if (m_stmt) {
    m_stmt->outputCPP(cg, ar);
  }
  if (cg.findLabelId("continue", labelId)) {
    cg.printf("continue%d:;\n", labelId, labelId);
  }
  cg.indentEnd("}\n");
  if (cg.findLabelId("break", labelId)) {
    cg.printf("break%d:;\n", labelId);
  }
  cg.indentEnd("}\n");
  cg.popBreakScope();
}
int IfBranchStatement::outputCPPIfBranch(CodeGenerator &cg,
                                         AnalysisResultPtr ar) {
  int varId = -1;
  if (m_condition) {
    if (m_condition->preOutputCPP(cg, ar, 0)) {
      cg.indentBegin("{\n");
      varId = cg.createNewId(ar);
      m_condition->getType()->outputCPPDecl(cg, ar);
      cg.printf(" %s%d;\n", Option::TempPrefix, varId);

      m_condition->outputCPPBegin(cg, ar);
      cg.printf("%s%d = (", Option::TempPrefix, varId);
      m_condition->outputCPP(cg, ar);
      cg.printf(");\n");
      m_condition->outputCPPEnd(cg, ar);
    }

    cg.printf("if (");
    if (varId >= 0) {
      cg.printf("%s%d", Option::TempPrefix, varId);
    } else {
      m_condition->outputCPP(cg, ar);
    }
    cg.printf(") ");
  }
  if (m_stmt) {
    cg.indentBegin("{\n");
    m_stmt->outputCPP(cg, ar);
    cg.indentEnd("}\n");
  } else {
    cg.printf("{}\n");
  }
  return varId >= 0 ? 1 : 0;
}
Example #3
0
void DoStatement::outputCPP(CodeGenerator &cg, AnalysisResultPtr ar) {
  cg.indentBegin("{\n");
  int labelId = cg.createNewId(ar);
  cg.pushBreakScope(labelId);

  cg.indentBegin("do {\n");
  cg.printf("LOOP_COUNTER_CHECK(%d);\n", labelId);
  if (m_stmt) {
    m_stmt->outputCPP(cg, ar);
  }
  if (cg.findLabelId("continue", labelId)) {
    cg.printf("continue%d:;\n", labelId);
  }
  cg.indentEnd("} while (");
  m_condition->outputCPP(cg, ar);
  cg.printf(");\n");
  if (cg.findLabelId("break", labelId)) {
    cg.printf("break%d:;\n", labelId);
  }
  cg.indentEnd("}\n");
  cg.popBreakScope();
}
bool FunctionCall::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                int state) {
  if (isUnused() ||
      m_className.empty() ||
      m_origClassName == "self" ||
      m_origClassName == "parent") {
    return Expression::preOutputCPP(cg, ar, state);
  }

  if (!ar->inExpression()) {
    return true;
  }
  Expression::preOutputCPP(cg, ar, state & ~FixOrder);
  ar->wrapExpressionBegin(cg);
  if (m_classScope) {
    string className = m_classScope->getId(cg);
    cg_printf("FrameInjection::SetStaticClassName(info, "
              "%s%s::s_class_name);\n",
              Option::ClassPrefix, className.c_str());
  } else {
    m_clsNameTemp = cg.createNewId(shared_from_this());
    cg_printf("CStrRef clsName%d(", m_clsNameTemp);
    cg_printString(m_origClassName, ar, shared_from_this());
    cg_printf(");\n");
    cg_printf("FrameInjection::SetStaticClassName(info, clsName%d);\n",
              m_clsNameTemp);
  }
  m_noStatic = true;
  preOutputStash(cg, ar, FixOrder);
  m_noStatic = false;
  cg_printf("FrameInjection::ResetStaticClassName(info);\n");

  if (!(state & FixOrder)) {
    cg_printf("id(%s);\n", cppTemp().c_str());
  }

  return true;
}
bool NewObjectExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                       int state) {
  string &cname = (m_origName == "self" || m_origName == "parent") ?
    m_name : m_origName;
  if (m_name.empty() || m_redeclared || !m_validClass || m_dynamic) {
    // Short circuit out if inExpression() returns false
    if (!ar->inExpression()) return true;

    if (m_nameExp) m_nameExp->preOutputCPP(cg, ar, state);
    ar->wrapExpressionBegin(cg);
    m_ciTemp = cg.createNewId(ar);
    m_objectTemp = cg.createNewId(ar);
    cg_printf("Object obj%d(", m_objectTemp);
    if (m_redeclared) {
      bool outsideClass = !ar->checkClassPresent(m_origName);
      ClassScopePtr cls = ar->resolveClass(m_name);
      ASSERT(cls);
      if (outsideClass) {
        cls->outputVolatileCheckBegin(cg, ar, cname);
      }
      cg_printf("g->%s%s->createOnly()", Option::ClassStaticsObjectPrefix,
                m_name.c_str());
      if (outsideClass) {
        cls->outputVolatileCheckEnd(cg);
      }
    } else {
      cg_printf("create_object_only(");
      if (!cname.empty()) {
        cg_printf("\"%s\"", cname.c_str());
      } else if (m_nameExp->is(Expression::KindOfSimpleVariable)) {
        m_nameExp->outputCPP(cg, ar);
      } else {
        cg_printf("(");
        m_nameExp->outputCPP(cg, ar);
        cg_printf(")");
      }
      cg_printf(")");
    }
    cg_printf(");\n");
    cg_printf("MethodCallPackage mcp%d;\n", m_ciTemp,
        m_objectTemp);
    cg_printf("mcp%d.construct(obj%d);\n", m_ciTemp, m_objectTemp);
    cg_printf("const CallInfo *cit%d = mcp%d.ci;\n", m_ciTemp, m_ciTemp);

    if (m_params && m_params->getCount() > 0) {
      ar->pushCallInfo(m_ciTemp);
      m_params->preOutputCPP(cg, ar, state);
      ar->popCallInfo();
    }
    cg_printf("(cit%d->getMeth())(mcp%d, ", m_ciTemp, m_ciTemp);
    if (m_params && m_params->getOutputCount()) {
      ar->pushCallInfo(m_ciTemp);
      FunctionScope::outputCPPArguments(m_params, cg, ar, -1, false);
      ar->popCallInfo();
    } else {
      cg_printf("Array()");
    }
    cg_printf(");\n");

    if (state & FixOrder) {
      ar->pushCallInfo(m_ciTemp);
      preOutputStash(cg, ar, state);
      ar->popCallInfo();
    }

    if (hasCPPTemp() && !(state & FixOrder)) {
      cg_printf("id(%s);\n", cppTemp().c_str());
    }
    return true;
  } else {
    bool tempRcvr = true;

    bool paramEffect = false;
    if (m_params && m_params->getCount() > 0) {
      for (int i = m_params->getCount(); i--; ) {
        if (!(*m_params)[i]->isScalar()) {
          paramEffect = true;
          break;
        }
      }
    }

    if (!paramEffect) {
      tempRcvr = false;
    }

    if (tempRcvr && ar->inExpression()) {
      bool outsideClass = !ar->checkClassPresent(m_origName);
      ClassScopePtr cls = ar->resolveClass(m_name);
      ASSERT(cls);
      ar->wrapExpressionBegin(cg);
      m_receiverTemp = genCPPTemp(cg, ar);
      cg_printf("%s%s %s = ", Option::SmartPtrPrefix, cls->getId(cg).c_str(),
          m_receiverTemp.c_str());
      if (outsideClass) {
        cls->outputVolatileCheckBegin(cg, ar, cname);
      }
      cg_printf("NEWOBJ(%s%s)()", Option::ClassPrefix, cls->getId(cg).c_str());
      if (outsideClass) {
        cls->outputVolatileCheckEnd(cg);
      }
      cg_printf(";\n");
    }

    bool tempParams = FunctionCall::preOutputCPP(cg, ar, state);
    return tempRcvr || tempParams;
  }
}
bool ObjectMethodExpression::preOutputCPP(CodeGenerator &cg,
    AnalysisResultPtr ar, int state) {
  if (!m_name.empty() && m_valid && m_object->getType()->isSpecificObject()) {
    return FunctionCall::preOutputCPP(cg, ar, state);
  }
  // Short circuit out if inExpression() returns false
  if (!ar->inExpression()) return true;
  m_ciTemp = cg.createNewId(shared_from_this());

  ar->wrapExpressionBegin(cg);
  bool isThis = m_object->isThis();
  if (!isThis) {
    m_object->preOutputCPP(cg, ar, state);
  }
  if (m_name.empty()) {
    m_nameExp->preOutputCPP(cg, ar, state);
  }
  const MethodSlot *ms = NULL;
  if (!m_name.empty()) {
    ConstructPtr self = shared_from_this();
    ms = ar->getOrAddMethodSlot(m_name, self);
  }
  cg_printf("MethodCallPackage mcp%d;\n", m_ciTemp);
  if (ms) {
    cg_printf("mcp%d.methodCallWithIndex((", m_ciTemp);
  } else {
    cg_printf("mcp%d.methodCall((", m_ciTemp);
  }
  if (isThis) {
    cg_printf("GET_THIS()");
  } else {
    outputCPPObject(cg, ar);
  }
  cg_printf("), ");
  if (!m_name.empty()) {
    uint64 hash = hash_string_i(m_name.c_str());
    cg_printString(m_origName, ar, shared_from_this());
    if (ms) {
      cg_printf(", %s", ms->runObjParam().c_str());
    }
    cg_printf(", 0x%016llXLL);\n", hash);
  } else {
    m_nameExp->outputCPP(cg, ar);
    cg_printf(", -1);\n");
  }
  cg_printf("const CallInfo *cit%d  __attribute__((__unused__)) ="
      " mcp%d.ci;\n", m_ciTemp, m_ciTemp);

  if (m_params && m_params->getCount() > 0) {
    ar->pushCallInfo(m_ciTemp);
    m_params->preOutputCPP(cg, ar, state);
    ar->popCallInfo();
  }

  if (state & FixOrder) {
    ar->pushCallInfo(m_ciTemp);
    preOutputStash(cg, ar, state);
    ar->popCallInfo();
  }
  if (hasCPPTemp() && !(state & FixOrder)) {
    cg_printf("id(%s);\n", cppTemp().c_str());
  }
  return true;
}
bool DynamicFunctionCall::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                       int state) {
    bool nonStatic = !m_class && m_className.empty();
    if (!nonStatic && !m_class && !m_validClass && !m_redeclared)
        return FunctionCall::preOutputCPP(cg, ar, state);
    // Short circuit out if inExpression() returns false
    if (!ar->inExpression()) return true;

    if (m_class) {
        m_class->preOutputCPP(cg, ar, state);
    }

    m_nameExp->preOutputCPP(cg, ar, state);

    ar->wrapExpressionBegin(cg);
    m_ciTemp = cg.createNewId(shared_from_this());
    bool lsb = false;
    ClassScopePtr cls;
    if (m_validClass) {
        cls = ar->findClass(m_className);
    }

    if (!m_classScope && !m_className.empty() && m_cppTemp.empty() &&
            m_origClassName != "self" && m_origClassName != "parent" &&
            m_origClassName != "static") {
        // Create a temporary to hold the class name, in case it is not a
        // StaticString.
        m_clsNameTemp = cg.createNewId(shared_from_this());
        cg_printf("CStrRef clsName%d(", m_clsNameTemp);
        cg_printString(m_origClassName, ar, shared_from_this());
        cg_printf(");\n");
    }

    if (nonStatic) {
        cg_printf("const CallInfo *cit%d;\n", m_ciTemp);
        cg_printf("void *vt%d;\n", m_ciTemp);
        cg_printf("get_call_info_or_fail(cit%d, vt%d, ", m_ciTemp, m_ciTemp);
    } else {
        cg_printf("MethodCallPackage mcp%d;\n", m_ciTemp);
        if (m_class) {
            if (m_class->is(KindOfScalarExpression)) {
                ASSERT(strcasecmp(dynamic_pointer_cast<ScalarExpression>(m_class)->
                                  getString().c_str(), "static") == 0);
                cg_printf("mcp%d.staticMethodCall(", m_ciTemp);
                cg_printf("\"static\"");
                lsb = true;
            } else {
                cg_printf("mcp%d.dynamicNamedCall(", m_ciTemp);
                m_class->outputCPP(cg, ar);
            }
            cg_printf(", ");
        } else if (m_validClass) {
            cg_printf("mcp%d.staticMethodCall(\"%s\", ", m_ciTemp,
                      cls->getId(cg).c_str());
        } else {
            cg_printf("mcp%d.staticMethodCall(\"%s\", ", m_ciTemp,
                      m_className.c_str());
        }
    }

    if (m_nameExp->is(Expression::KindOfSimpleVariable)) {
        m_nameExp->outputCPP(cg, ar);
    } else {
        cg_printf("(");
        m_nameExp->outputCPP(cg, ar);
        cg_printf(")");
    }

    if (!nonStatic) {
        cg_printf(");\n");
        if (lsb) cg_printf("mcp%d.lateStaticBind(info);\n");
        cg_printf("const CallInfo *&cit%d = mcp%d.ci;\n", m_ciTemp, m_ciTemp);
        if (m_validClass) {
            cg_printf("%s%s::%sget_call_info(mcp%d",
                      Option::ClassPrefix, cls->getId(cg).c_str(),
                      Option::ObjectStaticPrefix, m_ciTemp, m_className.c_str());
        } else if (m_redeclared) {
            cg_printf("g->%s%s->%sget_call_info(mcp%d",
                      Option::ClassStaticsObjectPrefix, m_className.c_str(),
                      Option::ObjectStaticPrefix, m_ciTemp, m_className.c_str());
        }
    }
    if (nonStatic || !m_class) {
        cg_printf(");\n");
    }
    if (m_params && m_params->getCount() > 0) {
        ar->pushCallInfo(m_ciTemp);
        m_params->preOutputCPP(cg, ar, state);
        ar->popCallInfo();
    }

    ar->pushCallInfo(m_ciTemp);
    preOutputStash(cg, ar, state);
    ar->popCallInfo();
    if (!(state & FixOrder)) {
        cg_printf("id(%s);\n", cppTemp().c_str());
    }
    return true;
}
Example #8
0
void ForEachStatement::outputCPP(CodeGenerator &cg, AnalysisResultPtr ar) {
  cg.indentBegin("{\n");
  int labelId = cg.createNewId(ar);
  cg.pushBreakScope(labelId);

  int mapId = cg.createNewId(ar);
  bool passTemp;
  bool isArray = false;

  if (m_ref) {
    passTemp = true;
    cg.printf("Variant %s%d = ref(", Option::MapPrefix, mapId);
    m_array->outputCPPImpl(cg, ar);
    cg.printf(");\n");
    cg.printf("%s%d.escalate();\n", Option::MapPrefix, mapId);
  } else if (!m_array->is(Expression::KindOfSimpleVariable) ||
             m_array->isThis()) {
    passTemp = true;
    cg.printf("Variant %s%d = ", Option::MapPrefix, mapId);
    TypePtr expectedType = m_array->getExpectedType();
    // Clear m_expectedType to avoid type cast (toArray).
    m_array->setExpectedType(TypePtr());
    m_array->outputCPP(cg, ar);
    m_array->setExpectedType(expectedType);
    cg.printf(";\n");
  } else {
    passTemp = false;
  }

  int iterId = cg.createNewId(ar);
  cg.printf("for (");
  if (m_ref) {
    cg.printf("MutableArrayIterPtr %s%d = %s%d.begin(",
              Option::IterPrefix, iterId, Option::MapPrefix, mapId);
    if (m_name) {
      cg.printf("&");
      m_name->outputCPP(cg, ar);
    } else {
      cg.printf("NULL");
    }
    cg.printf(", ");
    m_value->outputCPP(cg, ar);
    cg.printf("); %s%d->advance();", Option::IterPrefix, iterId);
  } else {
    if (passTemp) {
      cg.printf("ArrayIterPtr %s%d = %s%d.begin(",
                Option::IterPrefix, iterId,
                Option::MapPrefix, mapId);
      ClassScopePtr cls = ar->getClassScope();
      if (cls) {
        cg.printf("\"%s\"", cls->getName().c_str());
      }
      cg.printf("); ");
      cg.printf("!%s%d->end(); %s%d->next()",
                Option::IterPrefix, iterId,
                Option::IterPrefix, iterId);
    } else {
      TypePtr actualType = m_array->getActualType();
      if (actualType && actualType->is(Type::KindOfArray)) {
        isArray = true;
        cg.printf("ArrayIter %s%d = ", Option::IterPrefix, iterId);
      } else {
        cg.printf("ArrayIterPtr %s%d = ", Option::IterPrefix, iterId);
      }
      TypePtr expectedType = m_array->getExpectedType();
      // Clear m_expectedType to avoid type cast (toArray).
      m_array->setExpectedType(TypePtr());
      m_array->outputCPP(cg, ar);
      m_array->setExpectedType(expectedType);
      cg.printf(".begin(");
      ClassScopePtr cls = ar->getClassScope();
      if (cls) {
        cg.printf("\"%s\"", cls->getName().c_str());
      }
      cg.printf("); ");
      if (isArray) {
        cg.printf("!%s%d.end(); ", Option::IterPrefix, iterId);
        cg.printf("++%s%d", Option::IterPrefix, iterId);
      } else {
        cg.printf("!%s%d->end(); ", Option::IterPrefix, iterId);
        cg.printf("%s%d->next()", Option::IterPrefix, iterId);
      }
    }
  }
  cg.indentBegin(") {\n");
  cg.printf("LOOP_COUNTER_CHECK(%d);\n", labelId);

  if (!m_ref) {
    m_value->outputCPP(cg, ar);
    cg.printf(isArray ? " = %s%d.second();\n" : " = %s%d->second();\n",
              Option::IterPrefix, iterId);
    if (m_name) {
      m_name->outputCPP(cg, ar);
      cg.printf(isArray ? " = %s%d.first();\n" : " = %s%d->first();\n",
                Option::IterPrefix, iterId);
    }
  }
  if (m_stmt) {
    m_stmt->outputCPP(cg, ar);
  }
  if (cg.findLabelId("continue", labelId)) {
    cg.printf("continue%d:;\n", labelId);
  }
  cg.indentEnd("}\n");
  if (cg.findLabelId("break", labelId)) {
    cg.printf("break%d:;\n", labelId);
  }
  cg.popBreakScope();

  cg.indentEnd("}\n");
}