32#ifndef _QORE_FUNCTION_H
34#define _QORE_FUNCTION_H
42#include "qore/intern/QoreListNodeEvalOptionalRefHolder.h"
44class qore_class_private;
51class QoreOperatorNode;
54class qore_class_private;
57typedef std::vector<QoreParseTypeInfo*> ptype_vec_t;
58typedef std::vector<LocalVar*> lvar_vec_t;
60class AbstractFunctionSignature {
62 DLLLOCAL AbstractFunctionSignature(
const QoreTypeInfo* n_returnTypeInfo =
nullptr)
63 : returnTypeInfo(n_returnTypeInfo) {
66 DLLLOCAL AbstractFunctionSignature(
const QoreTypeInfo* n_returnTypeInfo,
const type_vec_t& n_typeList,
68 : returnTypeInfo(n_returnTypeInfo), typeList(n_typeList), defaultArgList(n_defaultArgList),
69 names(n_names), varargs(varargs) {
72 DLLLOCAL
virtual ~AbstractFunctionSignature() {
74 for (arg_vec_t::iterator i = defaultArgList.begin(), e = defaultArgList.end(); i != e; ++i) {
75 (*i).discard(
nullptr);
80 DLLLOCAL
const QoreTypeInfo* parseGetReturnTypeInfo()
const {
82 return parseGetReturnTypeInfo(err);
86 DLLLOCAL
virtual const QoreTypeInfo* parseGetReturnTypeInfo(
int& err)
const = 0;
88 DLLLOCAL
virtual const QoreParseTypeInfo* getParseParamTypeInfo(
unsigned num)
const = 0;
90 DLLLOCAL
const QoreTypeInfo* getReturnTypeInfo()
const {
91 return returnTypeInfo;
94 DLLLOCAL
const arg_vec_t& getDefaultArgList()
const {
95 return defaultArgList;
98 DLLLOCAL
const type_vec_t& getTypeList()
const {
102 DLLLOCAL
const name_vec_t& getParamNames()
const {
107 assert(i < defaultArgList.size());
108 return defaultArgList[i].eval(xsink);
111 DLLLOCAL
const char* getSignatureText()
const {
115 DLLLOCAL
virtual void addAbstractParameterSignature(std::string& str)
const {
116 for (
unsigned i = 0; i < typeList.size(); ++i) {
117 str.append(QoreTypeInfo::getPath(typeList[i]));
118 const char* vname = getName(i);
123 if (hasDefaultArg(i)) {
124 addDefaultArgument(str, defaultArgList[i]);
126 if (i != typeList.size() - 1) {
131 if (!typeList.empty()) {
138 DLLLOCAL
unsigned numParams()
const {
139 return (
unsigned)typeList.size();
143 DLLLOCAL
unsigned getParamTypes()
const {
144 return num_param_types;
147 DLLLOCAL
unsigned getMinParamTypes()
const {
148 return min_param_types;
151 DLLLOCAL
const QoreTypeInfo* getParamTypeInfo(
unsigned num)
const {
152 return num >= typeList.size() ? 0 : typeList[num];
155 DLLLOCAL
bool hasDefaultArg(
unsigned i)
const {
156 return i >= defaultArgList.size() || !defaultArgList[i] ? false :
true;
160 DLLLOCAL
static void addDefaultArgument(std::string& str,
QoreValue arg);
162 DLLLOCAL
const char* getName(
unsigned i)
const {
163 return i < names.size() ? names[i].c_str() : 0;
166 DLLLOCAL
bool compare(
const AbstractFunctionSignature& sig,
bool relaxed_match =
false)
const;
168 DLLLOCAL
bool hasVarargs()
const {
173 unsigned short num_param_types = 0,
176 const QoreTypeInfo* returnTypeInfo;
185 bool varargs =
false;
190 QoreParseTypeInfo* parseTypeInfo;
191 const QoreTypeInfo* typeInfo;
194 DLLLOCAL RetTypeInfo(QoreParseTypeInfo* n_parseTypeInfo,
const QoreTypeInfo* n_typeInfo)
195 : parseTypeInfo(n_parseTypeInfo), typeInfo(n_typeInfo) {
197 DLLLOCAL ~RetTypeInfo() {
198 delete parseTypeInfo;
200 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
203 DLLLOCAL QoreParseTypeInfo* takeParseTypeInfo() {
204 QoreParseTypeInfo* rv = parseTypeInfo;
210class UserSignature :
public AbstractFunctionSignature {
212 ptype_vec_t parseTypeList;
213 QoreParseTypeInfo* parseReturnTypeInfo;
215 const QoreProgramLocation* loc;
217 DLLLOCAL
int pushParam(BarewordNode* b,
bool needs_types,
bool bare_refs);
218 DLLLOCAL
int pushParam(QoreOperatorNode* t,
bool needs_types);
219 DLLLOCAL
int pushParam(VarRefNode* v,
QoreValue defArg,
bool needs_types);
221 DLLLOCAL
void param_error() {
222 parse_error(*loc,
"parameter list contains non-variable reference expressions");
232 DLLLOCAL UserSignature(
int n_first_line,
int n_last_line,
QoreValue params, RetTypeInfo* retTypeInfo,
int64 po);
234 DLLLOCAL
virtual ~UserSignature() {
235 for (ptype_vec_t::iterator i = parseTypeList.begin(), e = parseTypeList.end(); i != e; ++i)
237 delete parseReturnTypeInfo;
240 DLLLOCAL
void setFirstParamType(
const QoreTypeInfo* typeInfo) {
241 assert(!typeList.empty());
242 typeList[0] = typeInfo;
245 DLLLOCAL
void setSelfId(LocalVar* n_selfid) {
250 DLLLOCAL LocalVar* getSelfId()
const {
254 DLLLOCAL
virtual const QoreParseTypeInfo* getParseParamTypeInfo(
unsigned num)
const {
255 return num < parseTypeList.size() ? parseTypeList[num] :
nullptr;
259 DLLLOCAL
virtual int resolve();
261 DLLLOCAL
virtual void addAbstractParameterSignature(std::string& str)
const {
263 AbstractFunctionSignature::addAbstractParameterSignature(str);
267 for (
unsigned i = 0; i < parseTypeList.size(); ++i) {
268 if (!parseTypeList[i] && typeList.size() > i && typeList[i])
269 str.append(QoreTypeInfo::getPath(typeList[i]));
271 str.append(QoreParseTypeInfo::getName(parseTypeList[i]));
272 if (i != parseTypeList.size() - 1)
278 DLLLOCAL
virtual const QoreTypeInfo* parseGetReturnTypeInfo(
int& err)
const {
279 if (
const_cast<UserSignature*
>(
this)->resolve() && !err) {
282 return returnTypeInfo;
285 DLLLOCAL
const QoreProgramLocation* getParseLocation()
const {
289 DLLLOCAL
bool hasReturnTypeInfo()
const {
290 return parseReturnTypeInfo || returnTypeInfo;
293 DLLLOCAL
void parseInitPushLocalVars(
const QoreTypeInfo* classTypeInfo);
296 DLLLOCAL
void parseInitPopLocalVars();
299class AbstractQoreFunctionVariant;
301#define ARG_DEF (1 << 0)
302#define ARG_OTHER (1 << 1)
304class CodeEvaluationHelper :
public QoreStackLocation,
public ProgramThreadCountContextHelper {
319 DLLLOCAL CodeEvaluationHelper(
ExceptionSink* n_xsink,
const QoreFunction* func,
320 const AbstractQoreFunctionVariant*& variant,
const char* n_name,
const QoreListNode* args =
nullptr,
321 QoreObject* self =
nullptr,
const qore_class_private* n_qc =
nullptr, qore_call_t n_ct = CT_UNUSED,
322 bool is_copy =
false,
const qore_class_private* cctx =
nullptr,
QoreProgram* pgm_ctx =
nullptr);
338 DLLLOCAL CodeEvaluationHelper(
ExceptionSink* n_xsink,
const QoreFunction* func,
339 const AbstractQoreFunctionVariant*& variant,
const char* n_name,
QoreListNode* args,
340 QoreObject* self =
nullptr,
const qore_class_private* n_qc =
nullptr, qore_call_t n_ct = CT_UNUSED,
341 bool is_copy =
false,
const qore_class_private* cctx =
nullptr,
QoreProgram* pgm_ctx =
nullptr);
343 DLLLOCAL ~CodeEvaluationHelper();
345 DLLLOCAL
void setReturnTypeInfo(
const QoreTypeInfo* n_returnTypeInfo) {
346 returnTypeInfo = saveReturnTypeInfo(n_returnTypeInfo);
350 DLLLOCAL
void setCallType(qore_call_t n_ct) {
354 DLLLOCAL
int prepareDefaultArgs(
ExceptionSink* xsink,
const AbstractQoreFunctionVariant* variant,
355 AbstractFunctionSignature* sig,
bool is_copy,
QoreObject* self,
int arg_type);
369 DLLLOCAL
int processDefaultArgs(
ExceptionSink* xsink,
const QoreFunction* func,
370 const AbstractQoreFunctionVariant* variant, AbstractFunctionSignature* sig,
bool is_copy,
375 tmp.assign(
true, n_args);
395 DLLLOCAL
const qore_class_private* getClass()
const {
400 DLLLOCAL
virtual const QoreProgramLocation&
getLocation()
const {
406 DLLLOCAL
virtual const std::string&
getCallName()
const {
419 DLLLOCAL
virtual const AbstractStatement*
getStatement()
const {
424 DLLLOCAL
const char* getName()
const {
433 const qore_class_private* qc;
434 const QoreProgramLocation* loc;
436 const QoreTypeInfo* returnTypeInfo;
438 const AbstractStatement* stmt =
nullptr;
440 std::string callName;
442 const QoreProgramLocation* old_runtime_loc =
nullptr;
443 bool restore_stack =
false;
445 DLLLOCAL
void init(
const QoreFunction* func,
const AbstractQoreFunctionVariant*& variant,
bool is_copy,
448 DLLLOCAL
int findVariant(
const QoreFunction* func,
const AbstractQoreFunctionVariant*& variant,
449 const qore_class_private* cctx);
451 DLLLOCAL
void setCallName(
const QoreFunction* func);
454class UserVariantBase;
459 DLLLOCAL AbstractQoreFunctionVariant(
int64 n_flags,
bool n_is_user =
false) : flags(n_flags), is_user(n_is_user) {
462 DLLLOCAL
const QoreTypeInfo* parseGetReturnTypeInfo()
const {
464 return parseGetReturnTypeInfo(err);
467 DLLLOCAL
virtual AbstractFunctionSignature* getSignature()
const = 0;
468 DLLLOCAL
virtual const QoreTypeInfo* parseGetReturnTypeInfo(
int& err)
const = 0;
470 DLLLOCAL
const QoreTypeInfo* getReturnTypeInfo()
const {
471 return getSignature()->getReturnTypeInfo();
474 DLLLOCAL
unsigned numParams()
const {
475 AbstractFunctionSignature* sig = getSignature();
476 return sig ? sig->numParams() : 0;
479 DLLLOCAL qore_call_t getCallType()
const {
480 return is_user ? CT_USER : CT_BUILTIN;
483 DLLLOCAL
int64 getParseOptions(
int64 po)
const;
485 DLLLOCAL
int64 getFlags()
const {
489 DLLLOCAL
virtual int64 getFunctionality()
const = 0;
493 DLLLOCAL
virtual void setRecheck() {
497 DLLLOCAL
void parseResolveUserSignature();
499 DLLLOCAL
virtual UserVariantBase* getUserVariantBase() {
503 DLLLOCAL
const UserVariantBase* getUserVariantBase()
const {
505 return is_user ?
const_cast<AbstractQoreFunctionVariant*
>(
this)->getUserVariantBase() : nullptr;
513 DLLLOCAL
virtual const QoreClass* getClass()
const {
517 DLLLOCAL
const char* className()
const {
519 return qc ? qc->
getName() :
nullptr;
522 DLLLOCAL std::string classPath()
const {
525 return std::string();
530 DLLLOCAL
bool isSignatureIdentical(
const AbstractFunctionSignature& sig,
bool relaxed_match =
false)
const {
533 return getSignature()->compare(sig, relaxed_match);
537 DLLLOCAL LocalVar* getSelfId()
const;
539 DLLLOCAL AbstractQoreFunctionVariant* ref() {
544 DLLLOCAL
void deref() {
550 DLLLOCAL
bool isUser()
const {
554 DLLLOCAL
bool hasBody()
const;
556 DLLLOCAL
virtual bool isModulePublic()
const {
561 DLLLOCAL
virtual int parseInit(QoreFunction* f) {
566 DLLLOCAL
virtual void parseCommit() {
569 DLLLOCAL
virtual bool hasVarargs()
const {
570 return flags & QCF_USES_EXTRA_ARGS;
578 DLLLOCAL
virtual ~AbstractQoreFunctionVariant() {}
582 DLLLOCAL AbstractQoreFunctionVariant(
const AbstractQoreFunctionVariant& old) =
delete;
583 DLLLOCAL AbstractQoreFunctionVariant& operator=(AbstractQoreFunctionVariant& orig) =
delete;
587class UserVariantExecHelper;
590class UserVariantBase {
591 friend class UserVariantExecHelper;
594 UserSignature signature;
595 StatementBlock* statements;
610 const qore_class_private* qc =
nullptr)
const;
615 DLLLOCAL UserVariantBase(StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line,
QoreValue params,
616 RetTypeInfo* rv,
bool synced);
617 DLLLOCAL
virtual ~UserVariantBase();
618 DLLLOCAL UserSignature* getUserSignature()
const {
619 return const_cast<UserSignature*
>(&signature);
622 DLLLOCAL
bool isSynchronized()
const {
626 DLLLOCAL
void setInit() {
630 DLLLOCAL
bool getInit()
const {
634 DLLLOCAL
bool hasBody()
const {
635 return (
bool)statements;
637 DLLLOCAL StatementBlock* getStatementBlock()
const {
641 DLLLOCAL
int64 getParseOptions(
int64 po)
const;
643 DLLLOCAL
void parseInitPushLocalVars(
const QoreTypeInfo* classTypeInfo);
645 DLLLOCAL
void parseInitPopLocalVars();
647 DLLLOCAL
void setSelfId(LocalVar* selfid) {
648 signature.setSelfId(selfid);
651 DLLLOCAL
void parseCommit();
655#define COMMON_USER_VARIANT_FUNCTIONS DLLLOCAL virtual int64 getFunctionality() const {\
656 const QoreClass* cls = getClass(); return QDOM_DEFAULT | (cls ? cls->getDomain() : 0);\
658 using AbstractQoreFunctionVariant::getUserVariantBase; \
659 DLLLOCAL virtual UserVariantBase* getUserVariantBase() { return static_cast<UserVariantBase*>(this); } \
660 DLLLOCAL virtual AbstractFunctionSignature* getSignature() const { return const_cast<UserSignature*>(&signature); } \
661 DLLLOCAL virtual const QoreTypeInfo* parseGetReturnTypeInfo(int& err) const { return signature.parseGetReturnTypeInfo(err); } \
662 DLLLOCAL virtual void setRecheck() { recheck = true; } \
663 DLLLOCAL virtual void parseCommit() { UserVariantBase::parseCommit(); } \
664 DLLLOCAL virtual bool hasVarargs() const { if (signature.hasVarargs()) return true; return AbstractQoreFunctionVariant::hasVarargs(); }
667class UserVariantExecHelper : ProgramThreadCountContextHelper, ThreadFrameBoundaryHelper {
669 const UserVariantBase* uvb;
674 DLLLOCAL UserVariantExecHelper(
const UserVariantBase* n_uvb, CodeEvaluationHelper* ceh,
ExceptionSink* n_xsink) :
675 ProgramThreadCountContextHelper(n_xsink, n_uvb->pgm, true),
676 ThreadFrameBoundaryHelper(!*n_xsink),
677 uvb(n_uvb), argv(n_xsink), xsink(n_xsink) {
679 if (*xsink || uvb->setupCall(ceh, argv, xsink))
683 DLLLOCAL ~UserVariantExecHelper();
685 DLLLOCAL
operator bool()
const {
694class UserFunctionVariant :
public AbstractQoreFunctionVariant,
public UserVariantBase {
698 DLLLOCAL
virtual ~UserFunctionVariant() {
702 DLLLOCAL UserFunctionVariant(StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line,
QoreValue params,
703 RetTypeInfo* rv,
bool synced,
int64 n_flags = QCF_NO_FLAGS) :
704 AbstractQoreFunctionVariant(n_flags, true),
705 UserVariantBase(b, n_sig_first_line, n_sig_last_line, params, rv, synced), mod_pub(false) {
706 if (signature.hasVarargs()) {
707 flags |= QCF_USES_EXTRA_ARGS;
712 COMMON_USER_VARIANT_FUNCTIONS
715 return eval(ceh.getName(), &ceh,
nullptr, xsink);
718 DLLLOCAL
virtual int parseInit(QoreFunction* f);
720 DLLLOCAL
virtual bool isModulePublic()
const {
724 DLLLOCAL
void setModulePublic() {
730#define UFV(f) (reinterpret_cast<UserFunctionVariant*>(f))
731#define UFV_const(f) (reinterpret_cast<const UserFunctionVariant*>(f))
735typedef safe_dslist<AbstractQoreFunctionVariant*> vlist_t;
737class VList :
public vlist_t {
742 DLLLOCAL
void del() {
744 for (vlist_t::iterator i = begin(), e = end(); i != e; ++i)
755 DLLLOCAL INode(QoreFunction* f, ClassAccess a) : func(f), access(a) {
760typedef std::vector<INode> ilist_t;
762hashdecl IList :
public ilist_t {
763 DLLLOCAL QoreFunction* getFunction(
const qore_class_private* class_ctx,
const qore_class_private*& last_class,
764 const_iterator aqfi,
bool& internal_access,
bool& stop)
const;
768friend class QoreFunctionIterator;
769friend class qore_external_function_iterator_private;
771 DLLLOCAL QoreFunction(
const char* n_name) : name(n_name),
772 same_return_type(true),
773 nn_same_return_type(true),
775 parse_init_done(true),
776 parse_init_in_progress(false),
784 ilist.push_back(INode(
this, Public));
786 const char* mod_name = get_module_context_name();
788 from_module = mod_name;
793 DLLLOCAL QoreFunction(
const QoreFunction& old,
int64 po = 0,
bool copy_all =
false,
bool n_inject =
false)
795 unique_functionality(old.unique_functionality),
796 unique_flags(old.unique_flags),
797 nn_unique_functionality(old.nn_unique_functionality),
798 nn_unique_flags(old.nn_unique_flags),
799 nn_count(old.nn_count),
800 same_return_type(old.same_return_type),
801 nn_same_return_type(old.nn_same_return_type),
803 parse_init_done(true),
804 parse_init_in_progress(false),
805 has_user(old.has_user),
806 has_builtin(old.has_builtin),
810 has_priv(old.has_priv),
811 all_priv(old.all_priv),
812 nn_uniqueReturnType(old.nn_uniqueReturnType),
813 from_module(old.from_module) {
815 bool no_builtin = po & PO_NO_SYSTEM_FUNC_VARIANTS;
818 for (vlist_t::const_iterator i = old.vlist.begin(), e = old.vlist.end(); i != e; ++i) {
820 if ((*i)->isUser()) {
821 if (no_user || !(*i)->isModulePublic()) {
831 vlist.push_back((*i)->ref());
834 if (no_user && has_user) {
837 if (no_builtin && has_builtin) {
842 assert(old.vlist.empty() || !vlist.empty());
844 assert(!old.ilist.empty());
845 assert(old.ilist.front().func == &old);
848 ilist.push_back(INode(
this, Public));
857 DLLLOCAL QoreFunction(
bool ignore,
const QoreFunction& old, qore_ns_private* nns)
858 : name(old.name), ns(nns), same_return_type(old.same_return_type),
859 unique_functionality(old.unique_functionality),
860 unique_flags(old.unique_flags),
861 nn_same_return_type(old.nn_same_return_type),
862 nn_unique_functionality(old.nn_unique_functionality),
863 nn_unique_flags(old.nn_unique_flags),
864 nn_count(old.nn_count),
865 parse_rt_done(true), parse_init_done(true),
866 has_user(true), has_builtin(false), has_mod_pub(false ), inject(false),
867 nn_uniqueReturnType(old.nn_uniqueReturnType) {
869 assert(old.has_mod_pub);
872 for (vlist_t::const_iterator i = old.vlist.begin(), e = old.vlist.end(); i != e; ++i) {
873 if (!(*i)->isModulePublic())
875 vlist.push_back((*i)->ref());
879 assert(old.vlist.empty() || !vlist.empty());
881 assert(!old.ilist.empty());
882 assert(old.ilist.front().func == &old);
885 ilist.push_back(INode(
this, Public));
894 DLLLOCAL
const AbstractQoreFunctionVariant* first()
const {
895 assert(!vlist.empty());
896 return *(vlist.begin());
900 DLLLOCAL AbstractQoreFunctionVariant* first() {
901 assert(!vlist.empty());
902 return *(vlist.begin());
905 DLLLOCAL
unsigned numVariants()
const {
912 DLLLOCAL
int parseCheckDuplicateSignatureCommitted(UserSignature* sig);
914 DLLLOCAL
const char* getName()
const {
918 DLLLOCAL
virtual const QoreClass* getClass()
const {
922 DLLLOCAL
void ref() {
926 DLLLOCAL
void deref() {
931 DLLLOCAL
const char* className()
const {
933 return qc ? qc->
getName() :
nullptr;
936 DLLLOCAL std::string classPath()
const {
939 return std::string();
944 DLLLOCAL
void addAncestor(QoreFunction* ancestor, ClassAccess access) {
945 ilist.push_back(INode(ancestor, access));
948 DLLLOCAL
void addNewAncestor(QoreFunction* ancestor, ClassAccess access) {
949 for (ilist_t::iterator i = ilist.begin(), e = ilist.end(); i != e; ++i)
950 if ((*i).func == ancestor)
952 ilist.push_back(INode(ancestor, access));
956 DLLLOCAL
void resolvePendingSignatures();
958 DLLLOCAL AbstractFunctionSignature* getUniqueSignature()
const {
959 return vlist.singular() ? first()->getSignature() : 0;
962 DLLLOCAL AbstractFunctionSignature* parseGetUniqueSignature()
const;
964 DLLLOCAL
int64 parseGetUniqueFunctionality()
const {
966 return nn_unique_functionality;
967 return unique_functionality;
970 DLLLOCAL
int64 parseGetUniqueFlags()
const {
972 return nn_unique_flags;
977 DLLLOCAL
int addPendingVariant(AbstractQoreFunctionVariant* variant);
979 DLLLOCAL
void addBuiltinVariant(AbstractQoreFunctionVariant* variant);
981 DLLLOCAL
int parseInit(qore_ns_private* ns);
982 DLLLOCAL
void parseCommit();
983 DLLLOCAL
void parseRollback();
985 DLLLOCAL
const QoreTypeInfo* getUniqueReturnTypeInfo()
const {
987 return nn_uniqueReturnType;
989 return same_return_type && !vlist.empty() ? first()->getReturnTypeInfo() : 0;
992 DLLLOCAL
const QoreTypeInfo* parseGetUniqueReturnTypeInfo() {
993 parseCheckReturnType();
997 if (!same_return_type)
1001 if (!nn_same_return_type)
1004 return nn_count ? nn_uniqueReturnType : (!vlist.empty() ? first()->getReturnTypeInfo() :
nullptr);
1008 return first()->getReturnTypeInfo();
1014 DLLLOCAL
virtual QoreValue evalFunction(
const AbstractQoreFunctionVariant* variant,
const QoreListNode* args,
1019 DLLLOCAL
virtual QoreValue evalFunctionTmpArgs(
const AbstractQoreFunctionVariant* variant,
QoreListNode* args,
1028 DLLLOCAL
const AbstractQoreFunctionVariant* parseFindVariant(
const QoreProgramLocation* loc,
1029 const type_vec_t& argTypeInfo,
const qore_class_private* class_ctx,
int& err)
const;
1032 DLLLOCAL
bool pendingEmpty()
const {
1033 return vlist.empty() || !check_parse;
1037 DLLLOCAL
bool committedEmpty()
const {
1038 return vlist.empty() || check_parse;
1041 DLLLOCAL
bool existsVariant(
const type_vec_t& paramTypeInfo)
const;
1045 DLLLOCAL
const AbstractQoreFunctionVariant* runtimeFindVariant(
ExceptionSink* xsink,
const QoreListNode* args,
bool only_user,
const qore_class_private* class_ctx)
const;
1048 DLLLOCAL
const AbstractQoreFunctionVariant* runtimeFindVariant(
ExceptionSink* xsink,
const type_vec_t& args,
const qore_class_private* class_ctx)
const;
1050 DLLLOCAL
const AbstractQoreFunctionVariant* runtimeFindExactVariant(
ExceptionSink* xsink,
const type_vec_t& args,
const qore_class_private* class_ctx)
const;
1052 DLLLOCAL
void parseAssimilate(QoreFunction& other) {
1053 while (!other.vlist.empty()) {
1054 addPendingVariant(*(other.vlist.begin()));
1055 other.vlist.pop_front();
1059 DLLLOCAL
bool hasUser()
const {
1063 DLLLOCAL
bool hasBuiltin()
const {
1067 DLLLOCAL
bool hasPublic()
const {
1071 DLLLOCAL
bool hasUserPublic()
const {
1072 return has_pub && has_user;
1075 DLLLOCAL
bool injected()
const {
1079 DLLLOCAL
bool hasPrivate()
const {
1083 DLLLOCAL
bool allPrivate()
const {
1087 DLLLOCAL
const std::string& getNameStr()
const {
1091 DLLLOCAL
const char* getModuleName()
const {
1092 return from_module.empty() ? nullptr : from_module.c_str();
1105 int64 unique_flags = QCF_NO_FLAGS;
1109 int64 nn_unique_flags = QCF_NO_FLAGS;
1113 bool same_return_type : 1;
1114 bool nn_same_return_type : 1;
1115 bool parse_rt_done : 1;
1116 bool parse_init_done : 1;
1117 bool parse_init_in_progress : 1;
1119 bool has_builtin : 1;
1122 bool check_parse : 1;
1126 const QoreTypeInfo* nn_uniqueReturnType =
nullptr;
1128 std::string from_module;
1130 DLLLOCAL
int parseCheckReturnType() {
1134 parse_rt_done =
true;
1136 if (!same_return_type)
1141 for (vlist_t::iterator i = vlist.begin(), e = vlist.end(); i != e; ++i) {
1142 if (
reinterpret_cast<UserSignature*
>((*i)->getUserVariantBase()->getUserSignature())->resolve() && !err) {
1145 const QoreTypeInfo* rti = (*i)->getReturnTypeInfo();
1147 if (i == vlist.begin()) {
1151 if (!QoreTypeInfo::isOutputIdentical(rti, first()->getReturnTypeInfo())) {
1152 same_return_type =
false;
1161 DLLLOCAL
static int parseCompareResolvedSignature(
const VList& vlist,
const AbstractFunctionSignature* sig,
1162 const AbstractFunctionSignature*& vs);
1165 DLLLOCAL
int parseCheckDuplicateSignature(AbstractQoreFunctionVariant* variant);
1168 DLLLOCAL
void addVariant(AbstractQoreFunctionVariant* variant) {
1169 const QoreTypeInfo* rti = variant->getReturnTypeInfo();
1170 if (same_return_type && !vlist.empty() && !QoreTypeInfo::isOutputIdentical(rti, first()->getReturnTypeInfo()))
1171 same_return_type =
false;
1173 int64 vf = variant->getFunctionality();
1174 int64 vflags = variant->getFlags();
1176 bool rtn = (bool)(vflags & QCF_RUNTIME_NOOP);
1178 if (vlist.empty()) {
1179 unique_functionality = vf;
1180 unique_flags = vflags;
1182 unique_functionality &= vf;
1183 unique_flags &= vflags;
1188 nn_unique_functionality = vf;
1189 nn_unique_flags = vflags;
1190 nn_uniqueReturnType = rti;
1193 nn_unique_functionality &= vf;
1194 nn_unique_flags &= vflags;
1195 if (nn_uniqueReturnType && !QoreTypeInfo::isOutputIdentical(rti, nn_uniqueReturnType))
1196 nn_uniqueReturnType = 0;
1201 vlist.push_back(variant);
1204 DLLLOCAL
virtual ~QoreFunction() {
1209 const qore_class_private* class_ctx,
const QoreFunction* aqf,
const qore_class_private* last_class,
1210 bool internal_access,
int64 ppo,
const AbstractQoreFunctionVariant* variant)
const;
1212 DLLLOCAL
const AbstractQoreFunctionVariant* checkVariantDomain(
ExceptionSink* xsink,
int64 ppo,
1213 const AbstractQoreFunctionVariant* variant)
const;
1216class QoreFunctionIterator {
1218 DLLLOCAL QoreFunctionIterator(
const QoreFunction& f) : f(f) {
1222 DLLLOCAL
bool next() {
1223 if (i == f.vlist.end()) {
1224 i = f.vlist.begin();
1230 return i != f.vlist.end();
1233 DLLLOCAL
const AbstractQoreFunctionVariant* getVariant()
const {
1238 const QoreFunction& f;
1239 VList::const_iterator i;
1242class MethodVariantBase;
1243class MethodFunctionBase;
1244#define METHFB(f) (reinterpret_cast<MethodFunctionBase*>(f))
1245#define METHFB_const(f) (reinterpret_cast<const MethodFunctionBase*>(f))
1247class MethodFunctionBase :
public QoreFunction {
1248friend hashdecl AbstractMethod;
1256 mutable MethodFunctionBase* new_copy =
nullptr;
1261 has_private_internal_variants =
false;
1265 DLLLOCAL
int checkFinalVariant(
const MethodFunctionBase* m,
const MethodVariantBase* v)
const;
1267 DLLLOCAL
void replaceAbstractVariantIntern(MethodVariantBase* variant);
1270 DLLLOCAL MethodFunctionBase(
const char* nme,
const QoreClass* n_qc,
bool n_is_static) : QoreFunction(nme),
1271 qc(n_qc), is_static(n_is_static), has_final(false), access(Internal) {
1275 DLLLOCAL MethodFunctionBase(
const MethodFunctionBase& old,
const QoreClass* n_qc)
1276 : QoreFunction(old, 0, true),
1278 is_static(old.is_static),
1279 has_final(old.has_final),
1280 is_abstract(old.is_abstract),
1281 has_private_internal_variants(old.has_private_internal_variants),
1282 access(old.access) {
1286 old.new_copy =
this;
1289 ilist.reserve(old.ilist.size());
1290 ilist_t::const_iterator i = old.ilist.begin(), e = old.ilist.end();
1292 for (; i != e; ++i) {
1293 ilist.push_back(*i);
1297 DLLLOCAL
void resolveCopy() {
1298 ilist_t::iterator i = ilist.begin(), e = ilist.end();
1300 for (; i != e; ++i) {
1301 MethodFunctionBase* mfb = METHFB((*i).func);
1304 printd(0,
"error resolving %p %s::%s() base method %p %s::%s() nas no new method pointer\n", qc, qc->
getName(), getName(), mfb->qc, mfb->qc->getName(), getName());
1305 assert(mfb->new_copy);
1308 (*i).func = mfb->new_copy;
1312 DLLLOCAL
int parseInit();
1313 DLLLOCAL
void parseCommit();
1314 DLLLOCAL
void parseRollback();
1317 DLLLOCAL
int parseAddUserMethodVariant(MethodVariantBase* variant);
1320 DLLLOCAL
void addBuiltinMethodVariant(MethodVariantBase* variant);
1323 DLLLOCAL
void parseCommitMethod(
QoreString& csig,
const char* mod);
1325 DLLLOCAL
void parseCommitMethod();
1327 DLLLOCAL
void parseSignatures(
QoreString& csig,
const char* mod)
const;
1330 DLLLOCAL MethodVariantBase* parseHasVariantWithSignature(MethodVariantBase* v,
bool relaxed_match =
false)
const;
1332 DLLLOCAL
void replaceAbstractVariant(MethodVariantBase* variant);
1334 DLLLOCAL
void parseRollbackMethod();
1336 DLLLOCAL
bool isUniquelyPrivate()
const {
1337 return access > Public;
1340 DLLLOCAL
bool isAbstract()
const {
1344 DLLLOCAL ClassAccess getAccess()
const {
1348 DLLLOCAL
virtual const QoreClass* getClass()
const {
1352 DLLLOCAL
const char* getClassName()
const {
1356 DLLLOCAL std::string classPath()
const {
1358 return std::string();
1363 DLLLOCAL
bool isStatic()
const {
1367 DLLLOCAL
bool hasPrivateInternalVariants()
const {
1368 return has_private_internal_variants;
1371 DLLLOCAL
int checkFinal()
const;
1374 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const = 0;
1377class UserParamListLocalVarHelper {
1379 UserVariantBase* uvb;
1382 DLLLOCAL UserParamListLocalVarHelper(UserVariantBase* n_uvb,
const QoreTypeInfo* classTypeInfo =
nullptr)
1384 uvb->parseInitPushLocalVars(classTypeInfo);
1387 DLLLOCAL ~UserParamListLocalVarHelper() {
1388 uvb->parseInitPopLocalVars();
1392class UserClosureVariant :
public UserFunctionVariant {
1395 DLLLOCAL UserClosureVariant(StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line,
QoreValue params, RetTypeInfo* rv,
bool synced =
false,
int64 n_flags = QCF_NO_FLAGS) : UserFunctionVariant(b, n_sig_first_line, n_sig_last_line, params, rv, synced, n_flags) {
1398 DLLLOCAL
virtual int parseInit(QoreFunction* f);
1401 return eval(
"<anonymous closure>", &ceh, self, xsink);
1405#define UCLOV(f) (reinterpret_cast<UserClosureVariant*>(f))
1406#define UCLOV_const(f) (reinterpret_cast<const UserClosureVariant*>(f))
1408class UserClosureFunction :
public QoreFunction {
1411 const QoreTypeInfo* classTypeInfo;
1414 DLLLOCAL UserClosureFunction(StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line,
QoreValue params, RetTypeInfo* rv,
bool synced =
false,
int64 n_flags = QCF_NO_FLAGS) : QoreFunction(
"<anonymous closure>"), classTypeInfo(0) {
1415 addPendingVariant(
new UserClosureVariant(b, n_sig_first_line, n_sig_last_line, params, rv, synced, n_flags));
1420 DLLLOCAL
void setClassType(
const QoreTypeInfo* cti) {
1421 classTypeInfo = cti;
1424 DLLLOCAL
const QoreTypeInfo* getClassType()
const {
1425 return classTypeInfo;
1428 DLLLOCAL LVarSet* getVList() {
1433 DLLLOCAL
bool needsScan()
const {
1434 return varlist.needsScan();
#define QDOM_DEFAULT
the default domain (no domain)
Definition Restrictions.h:172
#define PO_REQUIRE_TYPES
require type information for all declarations
Definition Restrictions.h:61
#define PO_NO_INHERIT_USER_FUNC_VARIANTS
do not inherit public user function variants from the parent into the new program's space
Definition Restrictions.h:70
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition ExceptionSink.h:50
defines a Qore-language class
Definition QoreClass.h:310
DLLEXPORT const char * getName() const
returns the class name
DLLEXPORT std::string getNamespacePath(bool anchored=false) const
returns the full namespace path of the class
For use on the stack only: manages result of the optional evaluation of a QoreListNode.
Definition QoreListNodeEvalOptionalRefHolder.h:37
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition QoreListNode.h:52
the implementation of Qore's object data type, reference counted, dynamically-allocated only
Definition QoreObject.h:61
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition QoreProgram.h:128
Provides atomic reference counting to Qore objects.
Definition QoreReferenceCounter.h:44
DLLEXPORT void ROreference() const
Atomically increments the reference count.
DLLEXPORT bool ROdereference() const
Atomically decrements the reference count.
Stack location element abstract class.
Definition ExceptionSink.h:426
virtual DLLLOCAL const QoreProgramLocation & getLocation() const =0
returns the source location of the element
virtual DLLLOCAL const std::string & getCallName() const =0
returns the name of the function or method call
virtual DLLLOCAL QoreProgram * getProgram() const =0
returns the QoreProgram container
virtual DLLLOCAL const AbstractStatement * getStatement() const =0
returns the statement for the call for internal Qore code
virtual DLLLOCAL qore_call_t getCallType() const =0
returns the call type
Qore's string type supported by the QoreEncoding class.
Definition QoreString.h:93
a templated class to manage a reference count of an object that can throw a Qore-language exception w...
Definition ReferenceHolder.h:52
uint64_t q_rt_flags_t
runtime code execution flags
Definition common.h:269
std::vector< const QoreTypeInfo * > type_vec_t
vector of type information for parameter lists
Definition common.h:257
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition common.h:263
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition common.h:266
std::vector< QoreValue > arg_vec_t
vector of value information for default argument lists
Definition common.h:260
The main value class in Qore, designed to be passed by value.
Definition QoreValue.h:279