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; }
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; }
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"); }