void NewObjectExpression::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { string &cname = (m_origName == "self" || m_origName == "parent") ? m_name : m_origName; bool outsideClass = !ar->checkClassPresent(shared_from_this(), m_origName); if (!m_name.empty() && !m_redeclared && m_validClass && !m_dynamic) { ClassScopePtr cls = ar->resolveClass(shared_from_this(), m_name); ASSERT(cls); if (m_receiverTemp.empty()) { if (outsideClass) { cls->outputVolatileCheckBegin(cg, ar, getScope(), cname); } cg_printf("%s%s((NEWOBJ(%s%s)())->create(", Option::SmartPtrPrefix, cls->getId(cg).c_str(), Option::ClassPrefix, cls->getId(cg).c_str()); } else { cg_printf("(%s->create(", m_receiverTemp.c_str()); } FunctionScopePtr dummy; FunctionScope::OutputCPPArguments(m_params, dummy, cg, ar, m_extraArg, m_variableArgument, m_argArrayId, m_argArrayHash, m_argArrayIndex); if (m_receiverTemp.empty()) { cg_printf("))"); if (outsideClass) { cls->outputVolatileCheckEnd(cg); } } else { cg_printf(")"); if (!isUnused()) { cg_printf(", %s", m_receiverTemp.c_str()); } cg_printf(")"); } } else { bool wrap = false; wrap = m_actualType && m_actualType->is(Type::KindOfVariant) && !m_expectedType && !m_implementedType; if (wrap) { cg_printf("((Variant)"); } cg_printf("id(obj%d)", m_objectTemp); if (wrap) { cg_printf(")"); } } }
bool NewObjectExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar, int state) { bool tempRcvr = true; if (m_name.empty() || m_redeclared || !m_validClass || m_dynamic) { tempRcvr = false; } 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()) { ar->wrapExpressionBegin(cg); m_receiverTemp = genCPPTemp(cg, ar); bool outsideClass = !ar->checkClassPresent(m_origName); cg.printf("%s%s *%s = ", Option::ClassPrefix, m_name.c_str(), m_receiverTemp.c_str()); ClassScopePtr cls = ar->resolveClass(m_name); ASSERT(cls); if (outsideClass) { cls->outputVolatileCheckBegin(cg, ar, m_origName); } cg.printf("NEWOBJ(%s%s)()", Option::ClassPrefix, m_name.c_str()); if (outsideClass) { cls->outputVolatileCheckEnd(cg); } cg.printf(";\n"); } bool tempParams = FunctionCall::preOutputCPP(cg, ar, state); return tempRcvr || tempParams; }
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; } }
void SimpleFunctionCall::outputCPPParamOrderControlled(CodeGenerator &cg, AnalysisResultPtr ar) { if (m_className.empty()) { switch (m_type) { case ExtractFunction: cg.printf("extract(variables, "); FunctionScope::outputCPPArguments(m_params, cg, ar, 0, false); cg.printf(")"); return; case CompactFunction: cg.printf("compact(variables, "); FunctionScope::outputCPPArguments(m_params, cg, ar, -1, true); cg.printf(")"); return; default: break; } } bool volatileCheck = false; ClassScopePtr cls; if (!m_className.empty()) { cls = ar->findClass(m_className); if (cls && !ar->checkClassPresent(m_origClassName)) { volatileCheck = true; cls->outputVolatileCheckBegin(cg, ar, cls->getOriginalName()); } } if (m_valid) { bool tooManyArgs = (m_params && m_params->outputCPPTooManyArgsPre(cg, ar, m_name)); if (!m_className.empty()) { cg.printf("%s%s::", Option::ClassPrefix, m_className.c_str()); if (m_name == "__construct" && cls) { FunctionScopePtr func = cls->findConstructor(ar, true); cg.printf("%s%s(", Option::MethodPrefix, func->getName().c_str()); } else { cg.printf("%s%s(", Option::MethodPrefix, m_name.c_str()); } } else { int paramCount = m_params ? m_params->getCount() : 0; if (m_name == "get_class" && ar->getClassScope() && paramCount == 0) { cg.printf("(\"%s\"", ar->getClassScope()->getOriginalName()); } else if (m_name == "get_parent_class" && ar->getClassScope() && paramCount == 0) { const std::string parentClass = ar->getClassScope()->getParent(); if (!parentClass.empty()) { cg.printf("(\"%s\"", ar->getClassScope()->getParent().c_str()); } else { cg.printf("(false"); } } else { if (m_noPrefix) { cg.printf("%s(", m_name.c_str()); } else { cg.printf("%s%s(", m_builtinFunction ? Option::BuiltinFunctionPrefix : Option::FunctionPrefix, m_name.c_str()); } } } FunctionScope::outputCPPArguments(m_params, cg, ar, m_extraArg, m_variableArgument, m_argArrayId); cg.printf(")"); if (tooManyArgs) { m_params->outputCPPTooManyArgsPost(cg, ar, m_voidReturn); } } else { if (m_className.empty()) { if (m_redeclared && !m_dynamicInvoke) { if (canInvokeFewArgs()) { cg.printf("%s->%s%s_few_args(", cg.getGlobals(ar), Option::InvokePrefix, m_name.c_str()); int left = Option::InvokeFewArgsCount; if (m_params && m_params->getCount()) { left -= m_params->getCount(); cg.printf("%d, ", m_params->getCount()); FunctionScope::outputCPPArguments(m_params, cg, ar, 0, false); } else { cg.printf("0"); } for (int i = 0; i < left; i++) { cg.printf(", null_variant"); } cg.printf(")"); return; } else { cg.printf("%s->%s%s(", cg.getGlobals(ar), Option::InvokePrefix, m_name.c_str()); } } else { cg.printf("invoke(\"%s\", ", m_name.c_str()); } } else { bool inObj = m_parentClass && ar->getClassScope() && !dynamic_pointer_cast<FunctionScope>(ar->getScope())->isStatic(); if (m_redeclaredClass) { if (inObj) { // parent is redeclared cg.printf("parent->%sinvoke(\"%s\",", Option::ObjectPrefix, m_name.c_str()); } else { cg.printf("%s->%s%s->%sinvoke(\"%s\", \"%s\",", cg.getGlobals(ar), Option::ClassStaticsObjectPrefix, m_className.c_str(), Option::ObjectStaticPrefix, m_className.c_str(), m_name.c_str()); } } else if (m_validClass) { if (inObj) { cg.printf("%s%s::%sinvoke(\"%s\",", Option::ClassPrefix, m_className.c_str(), Option::ObjectPrefix, m_name.c_str()); } else { cg.printf("%s%s::%sinvoke(\"%s\", \"%s\",", Option::ClassPrefix, m_className.c_str(), Option::ObjectStaticPrefix, m_className.c_str(), m_name.c_str()); } } else { cg.printf("invoke_static_method(\"%s\", \"%s\",", m_className.c_str(), m_name.c_str()); } } if ((!m_params) || (m_params->getCount() == 0)) { cg.printf("Array()"); } else { FunctionScope::outputCPPArguments(m_params, cg, ar, -1, false); } bool needHash = true; if (m_className.empty()) { needHash = !(m_redeclared && !m_dynamicInvoke); } else { needHash = m_validClass || m_redeclaredClass; } if (!needHash) { cg.printf(")"); } else { cg.printf(", 0x%.16lXLL)", hash_string_i(m_name.data(), m_name.size())); } } if (volatileCheck) { cls->outputVolatileCheckEnd(cg); } }
void NewObjectExpression::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { bool linemap = outputLineMap(cg, ar, true); bool outsideClass = !ar->checkClassPresent(m_origName); if (!m_name.empty() && !m_redeclared && m_validClass && !m_dynamic) { bool tooManyArgs = (m_params && m_params->outputCPPTooManyArgsPre(cg, ar, m_name)); ClassScopePtr cls = ar->resolveClass(m_name); ASSERT(cls); if (m_receiverTemp.empty()) { if (outsideClass) { cls->outputVolatileCheckBegin(cg, ar, m_origName); } cg.printf("%s%s((NEWOBJ(%s%s)())->create(", Option::SmartPtrPrefix, m_name.c_str(), Option::ClassPrefix, m_name.c_str()); } else { cg.printf("%s%s(%s->create(", Option::SmartPtrPrefix, m_name.c_str(), m_receiverTemp.c_str()); } FunctionScope::outputCPPArguments(m_params, cg, ar, m_extraArg, m_variableArgument, m_argArrayId); cg.printf("))"); if (m_receiverTemp.empty()) { if (outsideClass) { cls->outputVolatileCheckEnd(cg); } } if (tooManyArgs) { m_params->outputCPPTooManyArgsPost(cg, ar, m_voidReturn); } } else { if (m_redeclared) { if (outsideClass) { ClassScope::OutputVolatileCheckBegin(cg, ar, m_origName); } cg.printf("g->%s%s->create(", Option::ClassStaticsObjectPrefix, m_name.c_str()); } else { cg.printf("create_object("); if (!m_name.empty()) { cg.printf("\"%s\"", m_name.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(", "); } if (m_params && m_params->getOutputCount()) { FunctionScope::outputCPPArguments(m_params, cg, ar, -1, false); } else { cg.printf("Array()"); } cg.printf(")"); if (m_redeclared && outsideClass) { ClassScope::OutputVolatileCheckEnd(cg); } } if (linemap) cg.printf(")"); }