32#ifndef _QORE_QORECLASSINTERN_H
34#define _QORE_QORECLASSINTERN_H
36#include "qore/safe_dslist"
37#include "qore/intern/ConstantList.h"
38#include "qore/intern/QoreLValue.h"
39#include "qore/intern/qore_var_rwlock_priv.h"
40#include "qore/intern/VRMutex.h"
41#include "qore/vector_map"
42#include "qore/vector_set"
54#define OTF_USER CT_USER
55#define OTF_BUILTIN CT_BUILTIN
58#ifdef HAVE_QORE_HASH_MAP
59#include <qore/hash_map_include.h>
60#include "qore/intern/xxhash.h"
62typedef HASH_MAP<std::string, QoreMethod*> hm_method_t;
64typedef std::map<std::string, QoreMethod*> hm_method_t;
68class qore_class_private;
73typedef std::map<const char*, MethodVariantBase*, ltstr> vmap_t;
75hashdecl AbstractMethod {
81 bool check_parse =
false;
85 DLLLOCAL AbstractMethod(
bool relaxed_match) : relaxed_match(relaxed_match) {
88 DLLLOCAL AbstractMethod(
const AbstractMethod& old);
90 DLLLOCAL ~AbstractMethod();
93 DLLLOCAL
void parseMergeBase(AbstractMethod& m,
bool committed =
false);
96 DLLLOCAL
void parseMergeBase(AbstractMethod& m, MethodFunctionBase* f,
bool committed =
false);
98 DLLLOCAL
void parseAdd(MethodVariantBase* v);
100 DLLLOCAL
void parseOverride(MethodVariantBase* v);
104 DLLLOCAL
int parseCommit();
107 DLLLOCAL
void parseRollback() {
110 DLLLOCAL
static void checkAbstract(
const char* cname,
const char* mname, vmap_t& vlist,
QoreStringNode*& desc);
112 DLLLOCAL
void add(MethodVariantBase* v);
113 DLLLOCAL
void override(MethodVariantBase* v);
115 DLLLOCAL
bool empty()
const {
116 return vlist.empty();
121#ifdef HAVE_QORE_HASH_MAP
122typedef HASH_MAP<std::string, AbstractMethod*> amap_t;
124typedef std::map<std::string, AbstractMethod*> amap_t;
127hashdecl AbstractMethodMap : amap_t {
128 DLLLOCAL AbstractMethodMap(
const AbstractMethodMap& old) : relaxed_match(old.relaxed_match) {
129 for (
auto& i : old) {
130 assert(!i.second->vlist.empty());
131 insert(amap_t::value_type(i.first,
new AbstractMethod(*(i.second))));
135 DLLLOCAL AbstractMethodMap() {
138 DLLLOCAL ~AbstractMethodMap() {
139 for (
auto& i : *
this) {
144 DLLLOCAL AbstractMethod* findMethod(
const std::string& name) {
145 amap_t::iterator i = find(name);
146 return i == end() ? nullptr : i->second;
150 DLLLOCAL
void parseAddAbstractVariant(
const char* name, MethodVariantBase* f);
152 DLLLOCAL
void parseOverrideAbstractVariant(
const char* name, MethodVariantBase* f);
155 DLLLOCAL
void addAbstractVariant(
const char* name, MethodVariantBase* f);
158 DLLLOCAL
void overrideAbstractVariant(
const char* name, MethodVariantBase* f);
160 DLLLOCAL
void parseCommit() {
161 for (amap_t::iterator i = begin(), e = end(); i != e;) {
162 if (i->second->parseCommit()) {
172 DLLLOCAL
void parseRollback() {
173 for (
auto& i : *
this)
174 i.second->parseRollback();
177 DLLLOCAL
void parseInit(qore_class_private& qc, BCList* scl);
182 DLLLOCAL
void parseCheckAbstractNew(
const QoreProgramLocation* loc,
const char* name)
const;
185 DLLLOCAL
int runtimeCheckInstantiateClass(
const char* name,
ExceptionSink* xsink)
const;
188 bool relaxed_match =
false;
193static inline const char* privpub(ClassAccess access) {
194 return access == Public
198 : (access == Internal ?
"private:internal" :
"inaccessible"));
208class MethodVariantBase :
public AbstractQoreFunctionVariant {
219 DLLLOCAL MethodVariantBase(ClassAccess n_access,
bool n_final,
int64 n_flags,
bool n_is_user =
false,
220 bool n_is_abstract =
false) :
221 AbstractQoreFunctionVariant(n_flags |
223 ? QCF_USES_EXTRA_ARGS
225 ), n_is_user), access(n_access), final(n_final), abstract(n_is_abstract) {
228 DLLLOCAL
bool isAbstract()
const {
232 DLLLOCAL
bool isPrivate()
const {
233 return access > Public;
236 DLLLOCAL ClassAccess getAccess()
const {
240 DLLLOCAL
bool isFinal()
const {
244 DLLLOCAL
void clearAbstract() {
253 DLLLOCAL
void setNormalUserMethod(
QoreMethod* n_qm, LocalVar* selfid) {
255 getUserVariantBase()->setSelfId(selfid);
257 assert(selfid->getTypeInfo());
258 assert(QoreTypeInfo::getUniqueReturnClass(selfid->getTypeInfo()));
266 DLLLOCAL
const QoreClass* getClass()
const {
270 DLLLOCAL
const char* getAbstractSignature();
272 DLLLOCAL
const qore_class_private* getClassPriv()
const;
274 DLLLOCAL MethodVariantBase* ref() {
279 DLLLOCAL
void deref() {
286#define METHVB(f) (reinterpret_cast<MethodVariantBase*>(f))
287#define METHVB_const(f) (reinterpret_cast<const MethodVariantBase*>(f))
289class MethodVariant :
public MethodVariantBase {
291 DLLLOCAL MethodVariant(ClassAccess n_access,
bool n_final,
int64 n_flags,
bool n_is_user =
false,
292 bool is_abstract =
false) : MethodVariantBase(n_access, n_final, n_flags, n_is_user, is_abstract) {
301#define METHV(f) (reinterpret_cast<MethodVariant*>(f))
302#define METHV_const(f) (reinterpret_cast<const MethodVariant*>(f))
304class ConstructorMethodVariant :
public MethodVariantBase {
307 DLLLOCAL
int constructorPrelude(
const QoreClass &thisclass, CodeEvaluationHelper& ceh,
QoreObject* self, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const;
310 DLLLOCAL ConstructorMethodVariant(ClassAccess n_access,
int64 n_flags,
bool n_is_user =
false) : MethodVariantBase(n_access, false, n_flags, n_is_user) {
312 DLLLOCAL
virtual const BCAList* getBaseClassArgumentList()
const = 0;
313 DLLLOCAL
virtual void evalConstructor(
const QoreClass &thisclass,
QoreObject* self, CodeEvaluationHelper& ceh, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const = 0;
316#define CONMV(f) (reinterpret_cast<ConstructorMethodVariant*>(f))
317#define CONMV_const(f) (reinterpret_cast<const ConstructorMethodVariant*>(f))
319class DestructorMethodVariant :
public MethodVariantBase {
322 DLLLOCAL DestructorMethodVariant(
bool n_is_user =
false) : MethodVariantBase(Public, false, QCF_NO_FLAGS, n_is_user) {
328#define DESMV(f) (reinterpret_cast<DestructorMethodVariant*>(f))
329#define DESMV_const(f) (reinterpret_cast<const DestructorMethodVariant*>(f))
331class CopyMethodVariant :
public MethodVariantBase {
334 DLLLOCAL CopyMethodVariant(ClassAccess n_access,
bool n_is_user =
false)
335 : MethodVariantBase(n_access, false, QCF_NO_FLAGS, n_is_user) {
339 CodeEvaluationHelper& ceh, BCList* scl,
ExceptionSink* xsink)
const = 0;
342#define COPYMV(f) (reinterpret_cast<CopyMethodVariant*>(f))
343#define COPYMV_const(f) (reinterpret_cast<const CopyMethodVariant*>(f))
345class UserMethodVariant :
public MethodVariant,
public UserVariantBase {
350 DLLLOCAL UserMethodVariant(ClassAccess n_access,
bool n_final, StatementBlock* b,
int n_sig_first_line,
351 int n_sig_last_line,
QoreValue params, RetTypeInfo* rv,
bool synced,
int64 n_flags,
bool is_abstract)
352 : MethodVariant(n_access, n_final, n_flags, true, is_abstract),
353 UserVariantBase(b, n_sig_first_line, n_sig_last_line, params, rv, false), synchronized(synced) {
354 if (signature.hasVarargs()) {
355 flags |= QCF_USES_EXTRA_ARGS;
359 DLLLOCAL ~UserMethodVariant() {
363 COMMON_USER_VARIANT_FUNCTIONS
365 DLLLOCAL
virtual int parseInit(QoreFunction* f) {
366 MethodFunctionBase* mf =
static_cast<MethodFunctionBase*
>(f);
370 ParseCodeInfoHelper rtih(mf->getName(), signature.getReturnTypeInfo());
375 if (!mf->isStatic()) {
377 err = statements->parseInitMethod(mf->MethodFunctionBase::getClass()->getTypeInfo(),
this);
380 err = statements->parseInit(
this);
385 f->parseCheckDuplicateSignatureCommitted(&signature);
394#define UMV(f) (reinterpret_cast<UserMethodVariant*>(f))
395#define UMV_const(f) (reinterpret_cast<const UserMethodVariant*>(f))
397class UserConstructorVariant :
public ConstructorMethodVariant,
public UserVariantBase {
402 DLLLOCAL
virtual ~UserConstructorVariant();
405 DLLLOCAL UserConstructorVariant(ClassAccess n_access, StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line,
407 : ConstructorMethodVariant(n_access, n_flags, true), UserVariantBase(b, n_sig_first_line, n_sig_last_line,
408 params, nullptr, false), bcal(n_bcal) {
409 if (signature.hasVarargs()) {
410 flags |= QCF_USES_EXTRA_ARGS;
415 COMMON_USER_VARIANT_FUNCTIONS
417 DLLLOCAL
virtual const BCAList* getBaseClassArgumentList()
const {
421 DLLLOCAL
virtual void evalConstructor(
const QoreClass& thisclass,
QoreObject* self, CodeEvaluationHelper& ceh,
424 DLLLOCAL
virtual int parseInit(QoreFunction* f);
427#define UCONV(f) (reinterpret_cast<UserConstructorVariant*>(f))
428#define UCONV_const(f) (reinterpret_cast<const UserConstructorVariant*>(f))
430class UserDestructorVariant :
public DestructorMethodVariant,
public UserVariantBase {
433 DLLLOCAL UserDestructorVariant(StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line)
434 : DestructorMethodVariant(true), UserVariantBase(b, n_sig_first_line, n_sig_last_line,
QoreValue(),
439 COMMON_USER_VARIANT_FUNCTIONS
441 DLLLOCAL
virtual int parseInit(QoreFunction* f) {
442 MethodFunctionBase* mf =
static_cast<MethodFunctionBase*
>(f);
444 int err = signature.resolve();
445 assert(!signature.getReturnTypeInfo() || signature.getReturnTypeInfo() == nothingTypeInfo);
448 ParseCodeInfoHelper rtih(
"destructor", nothingTypeInfo);
451 if (statements->parseInitMethod(mf->MethodFunctionBase::getClass()->getTypeInfo(),
this) && !err) {
461 assert(!signature.numParams());
462 assert(!signature.getReturnTypeInfo() || signature.getReturnTypeInfo() == nothingTypeInfo);
463 eval(
"destructor", 0, self, xsink, getClassPriv()).discard(xsink);
467#define UDESV(f) (reinterpret_cast<UserDestructorVariant*>(f))
468#define UDESV_const(f) (reinterpret_cast<const UserDestructorVariant*>(f))
470class UserCopyVariant :
public CopyMethodVariant,
public UserVariantBase {
473 DLLLOCAL UserCopyVariant(ClassAccess n_access, StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line,
QoreValue params, RetTypeInfo* rv,
bool synced) : CopyMethodVariant(n_access, true), UserVariantBase(b, n_sig_first_line, n_sig_last_line, params, rv, synced) {
477 COMMON_USER_VARIANT_FUNCTIONS
479 DLLLOCAL
virtual int parseInit(QoreFunction* f);
484#define UCOPYV(f) (reinterpret_cast<UserCopyVariant*>(f))
486class BuiltinMethodVariant :
public MethodVariant,
public BuiltinFunctionVariantBase {
488 DLLLOCAL BuiltinMethodVariant(ClassAccess n_access,
bool n_final,
int64 n_flags,
int64 n_functionality,
491 : MethodVariant(n_access, n_final, n_flags),
492 BuiltinFunctionVariantBase(n_flags, n_functionality, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names) {}
495 COMMON_BUILTIN_VARIANT_FUNCTIONS
498class BuiltinAbstractMethodVariant :
public BuiltinMethodVariant {
500 DLLLOCAL BuiltinAbstractMethodVariant(ClassAccess n_access,
int64 n_flags,
const QoreTypeInfo* n_returnTypeInfo,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinMethodVariant(n_access, false, n_flags,
QDOM_DEFAULT, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names) {
510class BuiltinNormalMethodVariantBase :
public BuiltinMethodVariant {
512 DLLLOCAL BuiltinNormalMethodVariantBase(ClassAccess n_access,
bool n_final,
int64 n_flags,
int64 n_functionality,
const QoreTypeInfo* n_returnTypeInfo,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinMethodVariant(n_access, n_final, n_flags, n_functionality, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names) {}
521class BuiltinNormalMethodValueVariant :
public BuiltinNormalMethodVariantBase {
526 DLLLOCAL BuiltinNormalMethodValueVariant(
q_method_n_t m, ClassAccess n_access,
bool n_final =
false,
int64 n_flags = QCF_USES_EXTRA_ARGS,
int64 n_functionality =
QDOM_DEFAULT,
const QoreTypeInfo* n_returnTypeInfo = 0,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinNormalMethodVariantBase(n_access, n_final, n_flags, n_functionality, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names), method(m) {
529 return method(self, private_data, args, rtflags, xsink);
533class BuiltinExternalNormalMethodValueVariant :
public BuiltinNormalMethodVariantBase {
539 DLLLOCAL BuiltinExternalNormalMethodValueVariant(
const void* n_ptr,
q_external_method_t m, ClassAccess n_access,
bool n_final =
false,
int64 n_flags = QCF_USES_EXTRA_ARGS,
int64 n_functionality =
QDOM_DEFAULT,
const QoreTypeInfo* n_returnTypeInfo = 0,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinNormalMethodVariantBase(n_access, n_final, n_flags, n_functionality, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names), method(m), ptr(n_ptr) {
542 return method(*qmethod, ptr, self, private_data, args, rtflags, xsink);
546class BuiltinStaticMethodValueVariant :
public BuiltinMethodVariant {
551 DLLLOCAL BuiltinStaticMethodValueVariant(
q_func_n_t m, ClassAccess n_access,
bool n_final =
false,
int64 n_flags = QCF_USES_EXTRA_ARGS,
int64 n_functionality =
QDOM_DEFAULT,
const QoreTypeInfo* n_returnTypeInfo = 0,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinMethodVariant(n_access, n_final, n_flags, n_functionality, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names), static_method(m) {
555 CodeContextHelper cch(xsink, CT_BUILTIN, qmethod->
getName(), 0, getClassPriv());
557 return static_method(ceh.getArgs(), ceh.getRuntimeFlags(), xsink);
561class BuiltinExternalStaticMethodValueVariant :
public BuiltinMethodVariant {
567 DLLLOCAL BuiltinExternalStaticMethodValueVariant(
const void* n_ptr,
q_external_static_method_t m, ClassAccess n_access,
bool n_final =
false,
int64 n_flags = QCF_USES_EXTRA_ARGS,
int64 n_functionality =
QDOM_DEFAULT,
const QoreTypeInfo* n_returnTypeInfo = 0,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinMethodVariant(n_access, n_final, n_flags, n_functionality, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names), static_method(m), ptr(n_ptr) {
571 CodeContextHelper cch(xsink, CT_BUILTIN, qmethod->
getName(), 0, getClassPriv());
573 return static_method(*qmethod, ptr, ceh.getArgs(), ceh.getRuntimeFlags(), xsink);
577class BuiltinConstructorVariantBase :
public ConstructorMethodVariant,
public BuiltinFunctionVariantBase {
580 DLLLOCAL BuiltinConstructorVariantBase(ClassAccess n_access,
int64 n_flags = QCF_USES_EXTRA_ARGS,
583 : ConstructorMethodVariant(n_access, n_flags),
584 BuiltinFunctionVariantBase(n_flags, n_functionality, 0, n_typeList, n_defaultArgList, n_names) {
588 COMMON_BUILTIN_VARIANT_FUNCTIONS
590 DLLLOCAL
virtual const BCAList* getBaseClassArgumentList()
const {
595class BuiltinConstructorValueVariant :
public BuiltinConstructorVariantBase {
600 DLLLOCAL BuiltinConstructorValueVariant(
q_constructor_n_t m, ClassAccess n_access,
int64 n_flags = QCF_USES_EXTRA_ARGS,
int64 n_functionality =
QDOM_DEFAULT,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinConstructorVariantBase(n_access, n_flags, n_functionality, n_typeList, n_defaultArgList, n_names), constructor(m) {
603 DLLLOCAL
virtual void evalConstructor(
const QoreClass& thisclass,
QoreObject* self, CodeEvaluationHelper& ceh, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const;
606class BuiltinExternalConstructorValueVariant :
public BuiltinConstructorVariantBase {
612 DLLLOCAL BuiltinExternalConstructorValueVariant(
const void* n_ptr,
q_external_constructor_t m, ClassAccess n_access,
int64 n_flags = QCF_USES_EXTRA_ARGS,
int64 n_functionality =
QDOM_DEFAULT,
const type_vec_t &n_typeList =
type_vec_t(),
const arg_vec_t &n_defaultArgList =
arg_vec_t(),
const name_vec_t& n_names =
name_vec_t()) : BuiltinConstructorVariantBase(n_access, n_flags, n_functionality, n_typeList, n_defaultArgList, n_names), constructor(m), ptr(n_ptr) {
615 DLLLOCAL
virtual void evalConstructor(
const QoreClass& thisclass,
QoreObject* self, CodeEvaluationHelper& ceh, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const;
618class BuiltinDestructorVariantBase :
public DestructorMethodVariant,
public BuiltinFunctionVariantBase {
621 COMMON_BUILTIN_VARIANT_FUNCTIONS
624class BuiltinDestructorVariant :
public BuiltinDestructorVariantBase {
629 DLLLOCAL BuiltinDestructorVariant(
q_destructor_t n_destructor) : destructor(n_destructor) {
635class BuiltinExternalDestructorVariant :
public BuiltinDestructorVariantBase {
641 DLLLOCAL BuiltinExternalDestructorVariant(
const void* ptr,
q_external_destructor_t destructor) : destructor(destructor), ptr(ptr) {
647class BuiltinCopyVariantBase :
public CopyMethodVariant,
public BuiltinFunctionVariantBase {
650 DLLLOCAL BuiltinCopyVariantBase(
const QoreClass* c)
651 : CopyMethodVariant(Public),
652 BuiltinFunctionVariantBase(0,
QDOM_DEFAULT, c->getTypeInfo()) {
656 COMMON_BUILTIN_VARIANT_FUNCTIONS
662class BuiltinCopyVariant :
public BuiltinCopyVariantBase {
667 DLLLOCAL BuiltinCopyVariant(
QoreClass* c,
q_copy_t m) : BuiltinCopyVariantBase(c), copy(m) {
670 copy(self, old, private_data, xsink);
674class BuiltinExternalCopyVariant :
public BuiltinCopyVariantBase {
680 DLLLOCAL BuiltinExternalCopyVariant(
const void* n_ptr,
QoreClass* c,
q_external_copy_t m) : BuiltinCopyVariantBase(c), copy(m), ptr(n_ptr) {
684 copy(thisclass, ptr, self, old, private_data, xsink);
689class NormalMethodFunction :
public MethodFunctionBase {
691 DLLLOCAL NormalMethodFunction(
const char* nme,
const QoreClass* n_qc) : MethodFunctionBase(nme, n_qc, false) {
694 DLLLOCAL NormalMethodFunction(
const NormalMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
697 DLLLOCAL
virtual ~NormalMethodFunction() {
708 const QoreValue n,
const QoreListNode* args,
const qore_class_private* cctx = runtime_get_class())
const;
711#define NMETHF(f) (reinterpret_cast<NormalMethodFunction*>(f))
714class StaticMethodFunction :
public MethodFunctionBase {
716 DLLLOCAL StaticMethodFunction(
const char* nme,
const QoreClass* n_qc) : MethodFunctionBase(nme, n_qc, true) {
718 DLLLOCAL StaticMethodFunction(
const StaticMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
720 DLLLOCAL
virtual ~StaticMethodFunction() {
724 DLLLOCAL
QoreValue evalMethod(
ExceptionSink* xsink,
const AbstractQoreFunctionVariant* variant,
const QoreListNode* args,
const qore_class_private* cctx =
nullptr)
const;
727 DLLLOCAL
QoreValue evalMethodTmpArgs(
ExceptionSink* xsink,
const AbstractQoreFunctionVariant* variant,
QoreListNode* args,
const qore_class_private* cctx =
nullptr)
const;
730#define SMETHF(f) (reinterpret_cast<StaticMethodFunction*>(f))
733class ConstructorMethodFunction :
public MethodFunctionBase {
735 DLLLOCAL ConstructorMethodFunction(
const QoreClass* n_qc) : MethodFunctionBase(
"constructor", n_qc, false) {
737 DLLLOCAL ConstructorMethodFunction(
const ConstructorMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
743 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
744 return new ConstructorMethodFunction(*
this, n_qc);
748#define CONMF(f) (reinterpret_cast<ConstructorMethodFunction*>(f))
751class DestructorMethodFunction :
public MethodFunctionBase {
753 DLLLOCAL DestructorMethodFunction(
const QoreClass* n_qc) : MethodFunctionBase(
"destructor", n_qc, false) {
755 DLLLOCAL DestructorMethodFunction(
const DestructorMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
759 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
760 return new DestructorMethodFunction(*
this, n_qc);
764#define DESMF(f) (reinterpret_cast<DestructorMethodFunction*>(f))
767class CopyMethodFunction :
public MethodFunctionBase {
769 DLLLOCAL CopyMethodFunction(
const QoreClass* n_qc) : MethodFunctionBase(
"copy", n_qc, false) {
771 DLLLOCAL CopyMethodFunction(
const CopyMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
775 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
776 return new CopyMethodFunction(*
this, n_qc);
780#define COPYMF(f) (reinterpret_cast<CopyMethodFunction*>(f))
782class BuiltinSystemConstructorBase :
public MethodFunctionBase {
784 DLLLOCAL BuiltinSystemConstructorBase(
const QoreClass* n_qc) : MethodFunctionBase(
"constructor", n_qc, false) {
786 DLLLOCAL BuiltinSystemConstructorBase(
const BuiltinSystemConstructorBase &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
788 DLLLOCAL
virtual void eval(
const QoreClass &thisclass,
QoreObject* self,
int code, va_list args)
const = 0;
790 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const = 0;
793#define BSYSCONB(f) (reinterpret_cast<BuiltinSystemConstructorBase* >(f))
797class BuiltinSystemConstructor :
public BuiltinSystemConstructorBase {
805 DLLLOCAL BuiltinSystemConstructor(
const BuiltinSystemConstructor &old,
const QoreClass* n_qc) : BuiltinSystemConstructorBase(old, n_qc), system_constructor(old.system_constructor) {
808 DLLLOCAL
virtual void eval(
const QoreClass &thisclass,
QoreObject* self,
int code, va_list args)
const {
809 system_constructor(self, code, args);
812 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
813 return new BuiltinSystemConstructor(*
this, n_qc);
817class BuiltinNormalMethod :
public NormalMethodFunction {
819 DLLLOCAL BuiltinNormalMethod(
const QoreClass* n_qc,
const char* mname) : NormalMethodFunction(mname, n_qc) {
822 DLLLOCAL BuiltinNormalMethod(
const BuiltinNormalMethod &old,
const QoreClass* n_qc) : NormalMethodFunction(old, n_qc) {
825 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
826 return new BuiltinNormalMethod(*
this, n_qc);
830class BuiltinStaticMethod :
public StaticMethodFunction {
832 DLLLOCAL BuiltinStaticMethod(
const QoreClass* n_qc,
const char* mname) : StaticMethodFunction(mname, n_qc) {
835 DLLLOCAL BuiltinStaticMethod(
const BuiltinStaticMethod &old,
const QoreClass* n_qc) : StaticMethodFunction(old, n_qc) {
838 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
839 return new BuiltinStaticMethod(*
this, n_qc);
843class NormalUserMethod :
public NormalMethodFunction {
845 DLLLOCAL NormalUserMethod(
const QoreClass* n_qc,
const char* mname) : NormalMethodFunction(mname, n_qc) {
847 DLLLOCAL NormalUserMethod(
const NormalUserMethod &old,
const QoreClass* n_qc) : NormalMethodFunction(old, n_qc) {
849 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
850 return new NormalUserMethod(*
this, n_qc);
854class StaticUserMethod :
public StaticMethodFunction {
856 DLLLOCAL StaticUserMethod(
const QoreClass* n_qc,
const char* mname) : StaticMethodFunction(mname, n_qc) {
858 DLLLOCAL StaticUserMethod(
const StaticUserMethod &old,
const QoreClass* n_qc) : StaticMethodFunction(old, n_qc) {
860 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
861 return new StaticUserMethod(*
this, n_qc);
865class QoreMemberInfoBase {
867 const QoreTypeInfo* typeInfo;
869 DLLLOCAL QoreMemberInfoBase(
const QoreMemberInfoBase& old) : typeInfo(old.typeInfo), exp(old.exp.refSelf()),
870 loc(old.loc), parseTypeInfo(old.parseTypeInfo ? new QoreParseTypeInfo(*old.parseTypeInfo) : nullptr) {
878 const QoreProgramLocation* loc;
879 QoreParseTypeInfo* parseTypeInfo;
881 DLLLOCAL QoreMemberInfoBase(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeinfo =
nullptr,
883 : typeInfo(n_typeinfo), exp(e), loc(loc), parseTypeInfo(n_parseTypeInfo) {
886 DLLLOCAL ~QoreMemberInfoBase() {
890 DLLLOCAL
void del() {
893 delete parseTypeInfo;
894 parseTypeInfo =
nullptr;
898 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
902 DLLLOCAL
const QoreTypeInfo* parseGetTypeInfo()
const {
904 return QoreTypeInfo::isReference(typeInfo) ? anyTypeInfo : typeInfo;
908 DLLLOCAL
bool parseHasTypeInfo()
const {
909 return (typeInfo || parseTypeInfo);
913class QoreMemberInfoBaseAccess :
public QoreMemberInfoBase {
917 DLLLOCAL QoreMemberInfoBaseAccess(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeinfo =
nullptr,
918 QoreParseTypeInfo* n_parseTypeInfo =
nullptr,
QoreValue e =
QoreValue(), ClassAccess n_access = Public) :
919 QoreMemberInfoBase(loc, n_typeinfo, n_parseTypeInfo, e), access(n_access) {
922 DLLLOCAL ClassAccess getAccess()
const {
927 DLLLOCAL QoreMemberInfoBaseAccess(
const QoreMemberInfoBaseAccess& old, ClassAccess n_access)
928 : QoreMemberInfoBase(old), access(old.access >= n_access ? old.access : n_access), init(old.init) {
935typedef std::vector<const qore_class_private*> cls_vec_t;
938typedef std::map<const qore_class_private*, const qore_class_private*> cls_context_map_t;
941typedef std::deque<const QoreMemberInfo*> member_info_list_t;
946class QoreMemberInfo :
public QoreMemberInfoBaseAccess {
947 friend class qore_class_private;
949 DLLLOCAL QoreMemberInfo(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeInfo =
nullptr,
950 QoreParseTypeInfo* n_parseTypeInfo =
nullptr,
QoreValue e =
QoreValue(), ClassAccess n_access = Public,
951 const qore_class_private* qc =
nullptr)
952 : QoreMemberInfoBaseAccess(loc, n_typeInfo, n_parseTypeInfo, e, n_access), is_local(true) {
954 cls_vec.push_back(qc);
959 DLLLOCAL QoreMemberInfo(
const QoreMemberInfo& old,
const qore_class_private* cls);
961 DLLLOCAL ~QoreMemberInfo() {
962 delete cls_context_map;
963 delete member_info_list;
966 DLLLOCAL
void setDeclaringClass(
const qore_class_private* qc) {
967 assert(cls_vec.empty());
968 cls_vec.push_back(qc);
973 DLLLOCAL
bool isLocalInternal()
const {
974 return is_local && access == Internal;
978 DLLLOCAL
bool local()
const {
983 DLLLOCAL
const qore_class_private* getClass()
const {
988 DLLLOCAL
const qore_class_private* getClassContext(
const qore_class_private* class_ctx)
const {
989 if (local() && class_ctx == getClass()) {
990 if (access == Internal) {
995 if (cls_context_map) {
996 cls_context_map_t::const_iterator i = cls_context_map->find(class_ctx);
997 if (i != cls_context_map->end()) {
1005 DLLLOCAL
size_t getContextSize()
const {
1006 return cls_context_map ? cls_context_map->size() : 0;
1011 DLLLOCAL
void addContextAccess(
const QoreMemberInfo& mi);
1015 DLLLOCAL
void addContextAccess(
const QoreMemberInfo& mi,
const qore_class_private* qc);
1018 DLLLOCAL
size_t numParentMembers()
const {
1019 return member_info_list ? member_info_list->size() : 0;
1023 DLLLOCAL member_info_list_t::const_iterator initializationBegin()
const {
1024 assert(member_info_list);
1025 return member_info_list->begin();
1029 DLLLOCAL member_info_list_t::const_iterator initializationEnd()
const {
1030 assert(member_info_list);
1031 return member_info_list->end();
1035 DLLLOCAL
int parseInit(
const char* name, LocalVar& selfid);
1038 DLLLOCAL
void setTransient() {
1039 assert(!is_transient);
1040 is_transient =
true;
1044 DLLLOCAL
bool getTransient()
const {
1045 return is_transient;
1052 cls_context_map_t* cls_context_map =
nullptr;
1054 member_info_list_t* member_info_list =
nullptr;
1059 is_transient =
false;
1071 DLLLOCAL QoreMemberInfo(
const QoreMemberInfo& old,
const qore_class_private* cls, ClassAccess cls_access);
1074class QoreVarInfo :
public QoreMemberInfoBaseAccess {
1076 mutable QoreVarRWLock rwl;
1077 QoreLValueGeneric val;
1080 bool eval_init =
false;
1082 DLLLOCAL QoreVarInfo(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeinfo =
nullptr,
1083 QoreParseTypeInfo* n_parseTypeInfo =
nullptr,
QoreValue e =
QoreValue(), ClassAccess n_access = Public) :
1084 QoreMemberInfoBaseAccess(loc, n_typeinfo, n_parseTypeInfo, e, n_access), finalized(false) {
1087 DLLLOCAL QoreVarInfo(
const QoreVarInfo& old, ClassAccess n_access = Public)
1088 : QoreMemberInfoBaseAccess(old, n_access), val(old.val), finalized(old.finalized), eval_init(old.eval_init) {
1091 DLLLOCAL ~QoreVarInfo() {
1092 assert(!val.hasValue());
1095 DLLLOCAL
int evalInit(
const char* name,
ExceptionSink* xsink);
1098 DLLLOCAL
void del() {
1099 assert(!val.hasValue());
1100 QoreMemberInfoBaseAccess::del();
1106 QoreAutoVarRWWriteLocker al(rwl);
1109 tmp = val.removeValue(
true);
1114 QoreMemberInfoBaseAccess::del();
1118 val.removeValue(
true).discard(xsink);
1123 val.set(getTypeInfo());
1124 return val.assignInitial(v);
1127 DLLLOCAL
void getLValue(LValueHelper& lvh) {
1128 lvh.setAndLock(rwl);
1129 if (checkFinalized(lvh.vl.xsink))
1131 lvh.setValue(val, getTypeInfo());
1134 DLLLOCAL
void init() {
1135 val.set(getTypeInfo());
1138 discard(val.assignInitial(QoreTypeInfo::getDefaultQoreValue(typeInfo)),
nullptr);
1144 if (!eval_init && evalInit(name, xsink)) {
1147 return getRuntimeReferencedValue();
1150 DLLLOCAL
QoreValue getRuntimeReferencedValue()
const {
1151 QoreAutoVarRWReadLocker al(rwl);
1152 return val.getReferencedValue();
1155 DLLLOCAL
int64 getAsBigInt()
const {
1156 QoreAutoVarRWReadLocker al(rwl);
1157 return val.getAsBigInt();
1160 DLLLOCAL
double getAsFloat()
const {
1161 QoreAutoVarRWReadLocker al(rwl);
1162 return val.getAsFloat();
1165 DLLLOCAL
bool getAsBool()
const {
1166 QoreAutoVarRWReadLocker al(rwl);
1167 return val.getAsBool();
1170 DLLLOCAL
int parseInit(
const char* name);
1175 xsink->
raiseException(
"DESTRUCTOR-ERROR",
"illegal class static variable assignment after second phase "
1176 "of variable destruction");
1183template <
typename T>
1184class QoreMemberMapBase {
1186 typedef std::pair<char*, std::unique_ptr<T>> member_list_element_t;
1187 typedef std::deque<member_list_element_t> member_list_t;
1188 typedef typename member_list_t::iterator iterator;
1189 typedef typename member_list_t::const_iterator const_iterator;
1190 member_list_t member_list;
1192 DLLLOCAL ~QoreMemberMapBase() {
1193 for (
auto& i : member_list) {
1198 member_list.clear();
1201 DLLLOCAL
bool inList(
const char* name)
const {
1202 return (
bool)find(name);
1205 DLLLOCAL T* find(
const char* name)
const {
1206 typename member_list_t::const_iterator i =
1207 std::find_if(member_list.begin(), member_list.end(), [name](
const member_list_element_t& e)
1208 ->
bool {return !strcmp(e.first, name); });
1209 return i == member_list.end() ? nullptr : i->second.get();
1212 DLLLOCAL T* replace(
const char* name, T* info) {
1213 typename member_list_t::iterator i =
1214 std::find_if(member_list.begin(), member_list.end(), [name](
const member_list_element_t& e)
1215 ->
bool {return !strcmp(e.first, name); });
1216 assert(i != member_list.end());
1217 T* rv = i->second.release();
1218 i->second = std::unique_ptr<T>(info);
1222 DLLLOCAL
bool empty()
const {
1223 return member_list.empty();
1226 DLLLOCAL
void addNoCheck(
char* name, T* info) {
1229 assert(!inList(name));
1230 member_list.push_back(std::make_pair(name, std::unique_ptr<T>(info)));
1233 DLLLOCAL
void addNoCheck(std::pair<char*, T*> pair) {
1234 addNoCheck(pair.first, pair.second);
1237 DLLLOCAL
void moveAllTo(QoreMemberMapBase<T>& dest) {
1238 dest.member_list.insert(dest.member_list.end(), member_list.begin(), member_list.end());
1239 member_list.clear();
1242 DLLLOCAL
size_t size()
const {
1243 return member_list.size();
1247class QoreMemberMap :
public QoreMemberMapBase<QoreMemberInfo> {
1249 using QoreMemberMapBase<QoreMemberInfo>::moveAllTo;
1250 DLLLOCAL
void moveAllTo(
QoreClass* qc, ClassAccess access);
1252 using QoreMemberMapBase<QoreMemberInfo>::addNoCheck;
1253 DLLLOCAL
void addNoCheck(
char* name, QoreMemberInfo* info) {
1254 assert(info->getClass());
1255 QoreMemberMapBase<QoreMemberInfo>::addNoCheck(name, info);
1258 DLLLOCAL
void addInheritedNoCheck(
char* name, QoreMemberInfo* info) {
1261 assert(!inList(name));
1262 member_list.insert(member_list.begin(), std::make_pair(name, std::unique_ptr<QoreMemberInfo>(info)));
1265 DLLLOCAL
int parseInit(LocalVar& selfid);
1271class QoreVarMap :
public QoreMemberMapBase<QoreVarInfo> {
1274 for (member_list_t::reverse_iterator i = member_list.rbegin(), e = member_list.rend(); i != e; ++i) {
1275 i->second->clear(xsink);
1280 for (member_list_t::reverse_iterator i = member_list.rbegin(), e = member_list.rend(); i != e; ++i) {
1281 i->second->delVar(xsink);
1285 member_list.clear();
1288 DLLLOCAL
void del() {
1289 for (member_list_t::reverse_iterator i = member_list.rbegin(), e = member_list.rend(); i != e; ++i) {
1290 assert(!i->second->val.hasValue());
1298 member_list.clear();
1301 DLLLOCAL
void clearNoFree() {
1302 member_list.clear();
1305 DLLLOCAL
void moveAllTo(
QoreClass* qc, ClassAccess access);
1317class BCANode :
public FunctionCallBase {
1320 const QoreProgramLocation* loc;
1327 DLLLOCAL BCANode(NamedScope* n, QoreParseListNode* n_args,
const QoreProgramLocation* loc)
1328 : FunctionCallBase(n_args), loc(loc), ns(n), name(nullptr) {
1329 assert(loc->start_line > 0);
1333 DLLLOCAL BCANode(
char* n, QoreParseListNode* n_args,
const QoreProgramLocation* loc)
1334 : FunctionCallBase(n_args), loc(loc), ns(nullptr), name(n) {
1335 assert(loc->start_line > 0);
1338 DLLLOCAL ~BCANode() {
1345 DLLLOCAL
int parseInit(BCList* bcl,
const char* classname);
1348typedef std::vector<BCANode*> bcalist_t;
1354class BCAList :
public bcalist_t {
1356 DLLLOCAL BCAList(BCANode* n) {
1360 DLLLOCAL ~BCAList() {
1361 for (bcalist_t::iterator i = begin(), e = end(); i != e; ++i)
1366 DLLLOCAL
int execBaseClassConstructorArgs(BCEAList* bceal,
ExceptionSink* xsink)
const;
1369typedef std::pair<QoreClass*, bool> class_virt_pair_t;
1371typedef std::vector<class_virt_pair_t> class_list_t;
1374hashdecl member_init_entry_t {
1376 const QoreMemberInfo* info;
1377 const qore_class_private* member_class_ctx;
1379 DLLLOCAL member_init_entry_t(
const char* name,
const QoreMemberInfo* info,
const qore_class_private* member_class_ctx) :
1380 name(name), info(info), member_class_ctx(member_class_ctx) {
1385typedef std::vector<member_init_entry_t> member_init_list_t;
1390class BCSMList :
public class_list_t {
1392 DLLLOCAL BCSMList() {
1395 DLLLOCAL BCSMList(
const BCSMList &old);
1397 DLLLOCAL ~BCSMList();
1399 DLLLOCAL
void processMemberInitializationList(
const QoreMemberMap& members, member_init_list_t& member_init_list);
1402 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* thisclass,
QoreClass* sc,
bool is_virtual);
1404 DLLLOCAL
void alignBaseClassesInSubclass(
QoreClass* thisclass,
QoreClass* child,
bool is_virtual);
1416 DLLLOCAL
void resolveCopy();
1420typedef vector_set_t<qore_class_private*> qcp_set_t;
1428 const QoreProgramLocation* loc;
1429 NamedScope* cname =
nullptr;
1430 char* cstr =
nullptr;
1433 bool is_virtual : 1;
1435 DLLLOCAL BCNode(
const QoreProgramLocation* loc, NamedScope* c, ClassAccess a) : loc(loc), cname(c), access(a),
1440 DLLLOCAL BCNode(
const QoreProgramLocation* loc,
char* str, ClassAccess a) : loc(loc), cstr(str), access(a),
1445 DLLLOCAL BCNode(
const QoreProgramLocation* loc,
QoreClass* qc,
bool n_virtual =
false) : loc(loc), sclass(qc),
1446 access(Public), is_virtual(n_virtual) {
1450 DLLLOCAL BCNode(
const BCNode &old) : loc(old.loc), sclass(old.sclass), access(old.access),
1451 is_virtual(old.is_virtual) {
1457 DLLLOCAL ~BCNode() {
1463 DLLLOCAL
int tryResolveClass(
QoreClass* cls,
bool raise_error);
1465 DLLLOCAL ClassAccess getAccess()
const {
return access; }
1468 DLLLOCAL
int initializeHierarchy(
QoreClass* cls, qcp_set_t& qcp_set);
1470 DLLLOCAL
int initializeMembers(
QoreClass* cls);
1473 DLLLOCAL
int initialize(
QoreClass* cls);
1475 DLLLOCAL
bool isBaseClass(
QoreClass* qc,
bool toplevel)
const;
1477 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethod(
const char* name, ClassAccess& n_access,
1478 const qore_class_private* class_ctx,
bool allow_internal)
const;
1479 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethod(
const char* name, ClassAccess& n_access,
1480 const qore_class_private* class_ctx,
bool allow_internal)
const;
1482 DLLLOCAL
bool runtimeIsPrivateMember(
const char* str,
bool toplevel)
const;
1486 DLLLOCAL
const QoreMemberInfo* parseFindMember(
const char* mem,
const qore_class_private*& qc,
1487 ClassAccess& n_access,
bool toplevel)
const;
1488 DLLLOCAL
const QoreVarInfo* parseFindVar(
const char* name,
const qore_class_private*& qc, ClassAccess& n_access,
1489 bool toplevel)
const;
1491 DLLLOCAL
const QoreClass* findInHierarchy(
const qore_class_private& qc);
1494 DLLLOCAL
const QoreClass* getClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1495 DLLLOCAL
const QoreClass* parseGetClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1496 DLLLOCAL
bool inHierarchy(
const qore_class_private& qc, ClassAccess& n_access)
const;
1497 DLLLOCAL
bool inHierarchyStrict(
const qore_class_private& qc, ClassAccess& n_access)
const;
1500 DLLLOCAL
const QoreMethod* parseFindNormalMethod(
const char* name,
const qore_class_private* class_ctx,
1501 bool allow_internal)
const;
1504 DLLLOCAL
const QoreMethod* parseFindStaticMethod(
const char* name,
const qore_class_private* class_ctx,
1505 bool allow_internal)
const;
1508 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc,
const char* name,
1509 const qore_class_private* class_ctx,
bool allow_internal)
const;
1511 DLLLOCAL
bool parseCheckHierarchy(
const QoreClass* cls, ClassAccess& n_access,
bool toplevel)
const;
1513 DLLLOCAL QoreVarInfo* parseFindStaticVar(
const char* vname,
const QoreClass*& qc, ClassAccess& n_access,
1514 bool check,
bool toplevel)
const;
1516 DLLLOCAL
QoreValue parseFindConstantValue(
const char* cname,
const QoreTypeInfo*& typeInfo,
bool &found,
1517 const qore_class_private* class_ctx,
bool allow_internal)
const;
1519 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* child,
bool is_virtual);
1521 DLLLOCAL
void initializeBuiltin();
1524typedef std::vector<BCNode*> bclist_t;
1532class BCList :
public bclist_t {
1538 bool rescanned =
false;
1540 DLLLOCAL BCList(BCNode* n) {
1547 DLLLOCAL BCList(
const BCList& old) : sml(old.sml) {
1549 reserve(old.size());
1550 for (bclist_t::const_iterator i = old.begin(), e = old.end(); i != e; ++i)
1551 push_back(
new BCNode(*(*i)));
1554 DLLLOCAL ~BCList() {
1555 for (bclist_t::iterator i = begin(), e = end(); i != e; ++i)
1559 DLLLOCAL
int initializeHierarchy(
QoreClass* thisclass, qcp_set_t& qcp_set);
1561 DLLLOCAL
int initializeMembers(
QoreClass* thisclass);
1563 DLLLOCAL
int initialize(
QoreClass* thisclass);
1566 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc,
const char* name,
1567 const qore_class_private* class_ctx,
bool allow_internal);
1570 DLLLOCAL
const QoreMethod* parseFindNormalMethod(
const char* name,
const qore_class_private* class_ctx,
1571 bool allow_internal);
1573 DLLLOCAL
const QoreMethod* parseFindStaticMethod(
const char* name,
const qore_class_private* class_ctx,
1574 bool allow_internal);
1576 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethod(
const char* name, ClassAccess& access,
1577 const qore_class_private* class_ctx,
bool allow_internal)
const;
1578 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethod(
const char* name, ClassAccess& access,
1579 const qore_class_private* class_ctx,
bool allow_internal)
const;
1581 DLLLOCAL
bool match(
const QoreClass* cls);
1584 DLLLOCAL
bool runtimeIsPrivateMember(
const char* str,
bool toplevel)
const;
1586 DLLLOCAL
bool parseCheckHierarchy(
const QoreClass* cls, ClassAccess& access,
bool toplevel)
const;
1588 DLLLOCAL
const QoreMemberInfo* parseFindMember(
const char* mem,
const qore_class_private*& qc,
1589 ClassAccess& n_access,
bool toplevel)
const;
1591 DLLLOCAL
const QoreVarInfo* parseFindVar(
const char* vname,
const qore_class_private*& qc, ClassAccess& access,
1592 bool toplevel)
const;
1594 DLLLOCAL
bool parseHasPublicMembersInHierarchy()
const;
1596 DLLLOCAL
const QoreClass* findInHierarchy(
const qore_class_private& qc);
1599 DLLLOCAL
const QoreClass* getClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1601 DLLLOCAL
const QoreClass* parseGetClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1602 DLLLOCAL
bool inHierarchy(
const qore_class_private& qc, ClassAccess& n_access)
const;
1603 DLLLOCAL
bool inHierarchyStrict(
const qore_class_private& qc, ClassAccess& n_access)
const;
1605 DLLLOCAL
void addNewAncestors(
QoreMethod* m);
1607 DLLLOCAL
void addNewStaticAncestors(
QoreMethod* m);
1608 DLLLOCAL
void addStaticAncestors(
QoreMethod* m);
1609 DLLLOCAL
void parseAddAncestors(
QoreMethod* m);
1610 DLLLOCAL
void parseAddStaticAncestors(
QoreMethod* m);
1612 DLLLOCAL
void parseResolveAbstract();
1614 DLLLOCAL
QoreValue parseFindConstantValue(
const char* cname,
const QoreTypeInfo*& typeInfo,
bool& found,
1615 const qore_class_private* class_ctx,
bool allow_internal)
const;
1617 DLLLOCAL QoreVarInfo* parseFindStaticVar(
const char* vname,
const QoreClass*& qc, ClassAccess& access,
bool check,
1618 bool toplevel)
const;
1620 DLLLOCAL
void resolveCopy();
1622 DLLLOCAL MethodVariantBase* matchNonAbstractVariant(
const std::string& name, MethodVariantBase* v)
const;
1624 DLLLOCAL
bool isBaseClass(
QoreClass* qc,
bool toplevel)
const;
1626 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* thisparent,
QoreClass* child,
bool is_virtual) {
1627 for (
auto& i : *
this) {
1628 if ((*i).addBaseClassesToSubclass(child, is_virtual))
1631 return sml.addBaseClassesToSubclass(thisparent, child, is_virtual);
1634 DLLLOCAL
void rescanParents(
QoreClass* cls);
1636 DLLLOCAL
void initializeBuiltin() {
1637 for (
auto& i : *
this) {
1638 (*i).initializeBuiltin();
1647 const QoreProgramLocation* loc;
1649 const AbstractQoreFunctionVariant* variant =
nullptr;
1650 bool execed =
false;
1651 bool member_init_done =
false;
1653 DLLLOCAL BCEANode(
const QoreProgramLocation* loc,
QoreListNode* args,
const AbstractQoreFunctionVariant* variant) : loc(loc), args(args), variant(reinterpret_cast<const MethodVariant*>(variant)) {
1656 DLLLOCAL BCEANode(
bool n_execed =
true,
bool mid =
true) : execed(n_execed), member_init_done(mid) {
1669typedef vector_map_t<qore_classid_t, BCEANode*> bceamap_t;
1675class BCEAList :
public bceamap_t {
1677 DLLLOCAL ~BCEAList() {
1685 DLLLOCAL
QoreListNode* findArgs(
qore_classid_t classid,
bool* aexeced,
const AbstractQoreFunctionVariant*& variant,
const QoreProgramLocation*& loc);
1702hashdecl SelfInstantiatorHelper {
1704 DLLLOCAL SelfInstantiatorHelper(LocalVar* n_selfid,
QoreObject* self) : selfid(n_selfid) {
1705 selfid->instantiateSelf(self);
1707 DLLLOCAL ~SelfInstantiatorHelper() {
1708 selfid->uninstantiateSelf();
1716class SignatureHash {
1718 unsigned char buf[SH_SIZE];
1723 DLLLOCAL
void clearHash() {
1724 memset(buf, 0, SH_SIZE);
1727 DLLLOCAL
void copyHash(
const SignatureHash& other) {
1728 memcpy(buf, other.buf, SH_SIZE);
1732 DLLLOCAL SignatureHash() : is_set(false) {
1736 DLLLOCAL SignatureHash(
const SignatureHash& old) : is_set(old.is_set) {
1743 DLLLOCAL
void updateEmpty() {
1749 DLLLOCAL
bool operator==(
const SignatureHash& other)
const {
1751 if (!is_set || !other.is_set)
1753 return !memcmp(buf, other.buf, SH_SIZE);
1756 DLLLOCAL SignatureHash& operator=(
const SignatureHash& other) {
1757 if (!other.is_set) {
1768 DLLLOCAL
operator bool()
const {
1773 DLLLOCAL
void toString(
QoreString& str)
const {
1774 for (
unsigned i = 0; i < SH_SIZE; ++i) {
1781 DLLLOCAL
const char* debugToString()
const {
1784 for (
unsigned i = 0; i < SH_SIZE; ++i) {
1791 DLLLOCAL
char* getHash()
const {
1796 DLLLOCAL
void clear() {
1804#define QCCM_NORMAL (1 << 0)
1805#define QCCM_STATIC (1 << 1)
1808typedef vector_set_t<QoreClass*> qc_set_t;
1813class qore_class_private {
1815 const QoreProgramLocation* loc;
1819 qore_ns_private* ns =
nullptr;
1820 BCList* scl =
nullptr;
1823 mutable VRMutex gate;
1828 AbstractMethodMap ahm;
1830 ConstantList constlist;
1833 QoreMemberMap members;
1835 member_init_list_t member_init_list;
1840 const QoreMethod* system_constructor =
nullptr,
1841 * constructor =
nullptr,
1842 * destructor =
nullptr,
1843 * copyMethod =
nullptr,
1844 * methodGate =
nullptr,
1845 * memberGate =
nullptr,
1846 * memberNotification =
nullptr;
1858 parse_init_called : 1,
1859 parse_init_partial_called : 1,
1860 has_public_memdecl : 1,
1861 pending_has_public_memdecl : 1,
1863 resolve_copy_done : 1,
1864 has_new_user_changes : 1,
1865 has_sig_changes : 1,
1866 owns_ornothingtypeinfo : 1,
1872 parse_resolve_hierarchy : 1,
1873 parse_resolve_class_members : 1,
1874 parse_resolve_abstract : 1,
1875 has_transient_member : 1
1883 unsigned num_methods, num_user_methods, num_static_methods, num_static_user_methods;
1887 QoreClassTypeInfo* typeInfo =
nullptr;
1888 QoreClassOrNothingTypeInfo* orNothingTypeInfo =
nullptr;
1890 const qore_class_private* injectedClass =
nullptr;
1893 mutable LocalVar selfid;
1899 const void* ptr =
nullptr;
1911 bool deref_source_program =
true;
1914 std::string from_module;
1917 std::string lang =
"Qore";
1920 typedef std::map<std::string, QoreValue> kvmap_t;
1924 QoreClassTypeInfo* n_typeinfo =
nullptr);
1928 DLLLOCAL qore_class_private(
const qore_class_private& old, qore_ns_private* ns,
QoreProgram* spgm,
1929 const char* nme,
bool inject,
const qore_class_private* injectedClass, q_setpub_t set_pub);
1963 DLLLOCAL
bool setKeyValueIfNotSet(
const std::string& key,
const char* str);
1972 DLLLOCAL
QoreValue getReferencedKeyValue(
const std::string& key)
const;
1981 DLLLOCAL
QoreValue getReferencedKeyValue(
const char* key)
const;
1984 DLLLOCAL
void addBaseClass(
QoreClass* qc,
bool virt);
1989 DLLLOCAL
const char* getModuleName()
const {
1990 return from_module.empty() ? nullptr : from_module.c_str();
1994 DLLLOCAL BCSMList* getBCSMList()
const {
1995 return scl ? &scl->sml :
nullptr;
1998 DLLLOCAL
void pgmRef()
const {
2004 DLLLOCAL
void ref()
const {
2008 DLLLOCAL
bool deref(
bool ns_const,
bool ns_vars,
bool in_del =
false) {
2011 if (!constlist.empty()) {
2012 constlist.deleteAll(
nullptr);
2017 if (!vars.empty()) {
2024 cls->priv =
nullptr;
2030 for (
auto& i : qcset) {
2041 DLLLOCAL
bool hasAbstract()
const {
2042 return !ahm.empty();
2045 DLLLOCAL
void parseSetEmptyPublicMemberDeclaration() {
2046 pending_has_public_memdecl =
true;
2047 if (!has_new_user_changes) {
2048 has_new_user_changes =
true;
2052 DLLLOCAL
int runtimeCheckInstantiateClass(
ExceptionSink* xsink)
const {
2053 return ahm.runtimeCheckInstantiateClass(name.c_str(), xsink);
2056 DLLLOCAL
void parseCheckAbstractNew(
const QoreProgramLocation* loc)
const;
2058 DLLLOCAL
void parseDoCheckAbstractNew(
const QoreProgramLocation* loc)
const;
2060 DLLLOCAL
void setNamespace(qore_ns_private* n) {
2066 DLLLOCAL
bool setNamespaceConditional(qore_ns_private* n) {
2076 DLLLOCAL
void updateNamespace(qore_ns_private* n) {
2082 DLLLOCAL
void resolveCopy();
2084 DLLLOCAL
void setUserData(
const void* n_ptr) {
2089 DLLLOCAL
const void* getUserData()
const {
2102 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
2106 DLLLOCAL
const QoreTypeInfo* getOrNothingTypeInfo()
const {
2107 return orNothingTypeInfo;
2110 DLLLOCAL
bool runtimeIsPrivateMemberIntern(
const char* str,
bool toplevel)
const;
2112 DLLLOCAL
void parseImportMembers(qore_class_private& qc, ClassAccess access);
2114 DLLLOCAL
bool parseHasMemberGate()
const {
2115 return memberGate || hm.find(
"memberGate") != hm.end() || ahm.find(
"memberGate") != ahm.end();
2118 DLLLOCAL
bool parseHasMethodGate()
const {
2119 return methodGate || hm.find(
"methodGate") != hm.end() || ahm.find(
"methodGate") != ahm.end();
2123 DLLLOCAL
bool checkAssignSpecialIntern(
const QoreMethod* m) {
2125 if (!methodGate && !strcmp(m->
getName(),
"methodGate")) {
2130 if (!memberGate && !strcmp(m->
getName(),
"memberGate")) {
2136 if (!memberNotification && !strcmp(m->
getName(),
"memberNotification")) {
2137 memberNotification = m;
2145 DLLLOCAL
bool checkSpecialStaticIntern(
const char* mname) {
2147 if ((!methodGate && !strcmp(mname,
"methodGate"))
2148 || (!memberGate && !strcmp(mname,
"memberGate"))
2149 || (!memberNotification && !strcmp(mname,
"memberNotification")))
2155 DLLLOCAL
bool checkSpecial(
const char* mname) {
2157 if ((!methodGate && !strcmp(mname,
"methodGate"))
2158 || (!memberGate && !strcmp(mname,
"memberGate"))
2159 || (!memberNotification && !strcmp(mname,
"memberNotification"))
2160 || (!constructor && !strcmp(mname,
"constructor"))
2161 || (!destructor && !strcmp(mname,
"destructor"))
2162 || (!copyMethod && !strcmp(mname,
"copy")))
2168 DLLLOCAL
bool checkAssignSpecial(
const QoreMethod* m) {
2170 if (!constructor && !strcmp(m->
getName(),
"constructor")) {
2175 if (!destructor && !strcmp(m->
getName(),
"destructor")) {
2180 if (!copyMethod && !strcmp(m->
getName(),
"copy")) {
2185 return checkAssignSpecialIntern(m);
2189 DLLLOCAL
void mergeAbstract();
2192 DLLLOCAL
int initializeIntern();
2193 DLLLOCAL
int initializeHierarchy(qcp_set_t& qcp_set);
2194 DLLLOCAL
int initializeMembers();
2195 DLLLOCAL
int initialize();
2197 DLLLOCAL
int parseInitPartial();
2198 DLLLOCAL
int parseInitPartialIntern();
2200 DLLLOCAL
int parseCheckMemberAccess(
const QoreProgramLocation* loc,
const char* mem,
2201 const QoreTypeInfo*& memberTypeInfo,
int pflag)
const {
2202 const_cast<qore_class_private*
>(
this)->parseInitPartial();
2204 const qore_class_private* qc =
nullptr;
2206 const QoreMemberInfo* omi = parseFindMember(mem, qc, access);
2210 if (!parseHasMemberGate() || (pflag & PF_FOR_ASSIGNMENT)) {
2212 parse_error(*loc,
"member '%s' of class '%s' referenced has no type information because it was " \
2213 "not declared in a public or private member list, but parse options require type " \
2214 "information for all declarations",
2218 if (parseHasPublicMembersInHierarchy()) {
2221 parse_error(*loc,
"illegal access to unknown member '%s' in class '%s' which has a public " \
2222 "member list (or inherited public member list)", mem, name.c_str());
2229 memberTypeInfo = omi->getTypeInfo();
2232 if ((access > Public) && !parseHasMemberGate() && !parseCheckPrivateClassAccess()) {
2233 memberTypeInfo =
nullptr;
2234 parse_error(*loc,
"illegal access to private member '%s' of class '%s'", mem, name.c_str());
2240 DLLLOCAL
int parseResolveInternalMemberAccess(
const char* mem,
const QoreTypeInfo*& memberTypeInfo)
const {
2241 const_cast<qore_class_private*
>(
this)->parseInitPartial();
2243 const qore_class_private* qc =
nullptr;
2245 const QoreMemberInfo* omi = parseFindMember(mem, qc, access);
2247 memberTypeInfo = omi->getTypeInfo();
2250 return omi ? 0 : -1;
2253 DLLLOCAL
int parseCheckInternalMemberAccess(
const char* mem,
const QoreTypeInfo*& memberTypeInfo,
2254 const QoreProgramLocation* loc)
const {
2255 const_cast<qore_class_private*
>(
this)->parseInitPartial();
2258 const qore_class_private* qc =
nullptr;
2260 const QoreMemberInfo* omi = parseFindMember(mem, qc, access);
2266 rc =
const_cast<QoreMemberInfo*
>(omi)->parseInit(mem, selfid);
2267 memberTypeInfo = omi->parseGetTypeInfo();
2272 parse_error(*loc,
"member '%s' of class '%s' referenced has no type information because it was not " \
2273 "declared in a public or private member list, but parse options require type information for " \
2274 "all declarations", mem, name.c_str());
2279 if (parseHasPublicMembersInHierarchy()) {
2280 parse_error(*loc,
"illegal access to unknown member '%s' in class '%s' which has a public member " \
2281 "list (or inherited public member list)", mem, name.c_str());
2290 DLLLOCAL
bool parseHasPublicMembersInHierarchy()
const {
2291 if (has_public_memdecl || pending_has_public_memdecl)
2294 return scl ? scl->parseHasPublicMembersInHierarchy() :
false;
2304 DLLLOCAL
const qore_class_private* runtimeGetMemberContext(
const char* mem,
const qore_class_private* class_ctx)
const {
2305 const QoreMemberInfo* info = runtimeGetMemberInfo(mem, class_ctx);
2307 return info ? info->getClassContext(class_ctx) :
nullptr;
2310 DLLLOCAL
bool runtimeIsMemberInternal(
const char* mem)
const {
2311 QoreMemberInfo* info = members.find(mem);
2312 return info && info->isLocalInternal() ? true :
false;
2324 DLLLOCAL
const QoreMemberInfo* runtimeGetMemberInfo(
const char* mem,
const qore_class_private* class_ctx)
const {
2325 QoreMemberInfo* info;
2327 info = class_ctx->members.find(mem);
2328 if (info && info->isLocalInternal()) {
2335 if (class_ctx !=
this) {
2336 info = members.find(mem);
2339 if (info && info->access == Inaccessible && !info->getClassContext(class_ctx)) {
2346 DLLLOCAL
const QoreMemberInfo* parseFindMember(
const char* mem,
const qore_class_private*& qc, ClassAccess& access)
const {
2348 const_cast<qore_class_private*
>(
this)->initialize();
2349 return parseFindMemberNoInit(mem, qc, access,
true);
2355 DLLLOCAL
const QoreMemberInfo* parseFindMemberNoInit(
const char* mem,
const qore_class_private*& qc, ClassAccess& access,
bool toplevel)
const {
2356 const QoreMemberInfo* mi = members.find(mem);
2358 ClassAccess ma = mi->getAccess();
2359 if (toplevel || ma < Internal) {
2363 qc = mi->getClass();
2368 return scl ? scl->parseFindMember(mem, qc, access,
true) : 0;
2371 DLLLOCAL
const QoreVarInfo* parseFindVar(
const char* vname,
const qore_class_private*& qc, ClassAccess& access,
bool toplevel)
const {
2374 QoreVarInfo* vi = vars.find(
const_cast<char*
>(vname));
2378 access = vi->getAccess();
2382 return scl ? scl->parseFindVar(vname, qc, access, toplevel) :
nullptr;
2385 DLLLOCAL
int parseCheckClassHierarchyMembers(
const char* mname,
const QoreMemberInfo& l_mi,
const QoreMemberInfo& b_mi)
const;
2387 DLLLOCAL
int checkExistingVarMember(
const char* dname,
const QoreMemberInfoBaseAccess* mi,
const QoreMemberInfoBaseAccess* omi,
const qore_class_private* qc, ClassAccess oaccess,
bool var =
false)
const;
2389 DLLLOCAL
int parseCheckVar(
const char* dname,
const QoreVarInfo* vi)
const {
2390 const qore_class_private* qc = 0;
2392 const QoreVarInfo* ovi = parseFindVar(dname, qc, access,
true);
2395 if (parseHasConstant(dname)) {
2396 parse_error(*vi->loc,
"'%s' has already been declared as a constant in class '%s' and therefore cannot be also declared as a static class variable in the same class with the same name", dname, name.c_str());
2402 return checkExistingVarMember(dname, vi, ovi, qc, access,
true);
2405 DLLLOCAL
int parseCheckMember(
const char* mem,
const QoreMemberInfo* mi)
const {
2406 const qore_class_private* qc =
nullptr;
2407 ClassAccess access = Public;
2408 const QoreMemberInfo* omi = parseFindMemberNoInit(mem, qc, access,
true);
2413 return checkExistingVarMember(mem, mi, omi, qc, omi->access);
2416 DLLLOCAL
int parseCheckMemberInBaseClasses(
const char* mem,
const QoreMemberInfo* mi)
const {
2417 const qore_class_private* qc =
nullptr;
2418 ClassAccess access = Public;
2421 const QoreMemberInfo* omi = scl ? scl->parseFindMember(mem, qc, access,
false) :
nullptr;
2422 if (!omi || (omi->getClass() == mi->getClass())) {
2426 return checkExistingVarMember(mem, mi, omi, qc, omi->access);
2429 DLLLOCAL
int parseCheckSystemCommitted(
const QoreProgramLocation* loc) {
2431 parse_error(*loc,
"cannot modify system class '%s'", name.c_str());
2435 parse_error(*loc,
"cannot modify user class '%s' once it's been committed", name.c_str());
2441 DLLLOCAL
void parseAddMember(
char* mem, ClassAccess access, QoreMemberInfo* memberInfo) {
2442 memberInfo->access = access;
2443 if (!parseCheckSystemCommitted(memberInfo->loc) && !parseCheckMember(mem, memberInfo)) {
2444 if (!has_new_user_changes) {
2445 has_new_user_changes =
true;
2447 if (!has_sig_changes) {
2448 has_sig_changes =
true;
2450 memberInfo->setDeclaringClass(
this);
2451 if (!has_transient_member && memberInfo->getTransient()) {
2452 has_transient_member =
true;
2455 members.addNoCheck(mem, memberInfo);
2463 DLLLOCAL
void parseAddStaticVar(
char* dname, ClassAccess access, QoreVarInfo* VarInfo) {
2464 VarInfo->access = access;
2465 if (!parseCheckSystemCommitted(VarInfo->loc) && !parseCheckVar(dname, VarInfo)) {
2466 if (!has_new_user_changes) {
2467 has_new_user_changes =
true;
2469 if (!has_sig_changes) {
2470 has_sig_changes =
true;
2474 vars.addNoCheck(dname, VarInfo);
2482 DLLLOCAL
void addBuiltinConstant(
const char* cname,
QoreValue value, ClassAccess access = Public,
const QoreTypeInfo* cTypeInfo =
nullptr) {
2483 assert(!constlist.inList(cname));
2485 sys = committed =
true;
2487 constlist.add(cname, value, cTypeInfo, access);
2490 DLLLOCAL
void addBuiltinStaticVar(
const char* vname,
QoreValue value, ClassAccess access = Public,
const QoreTypeInfo* vTypeInfo =
nullptr);
2492 DLLLOCAL
void parseAssimilateConstants(ConstantList &cmap, ClassAccess access) {
2493 assert(!sys && !committed);
2494 if (!has_new_user_changes)
2495 has_new_user_changes =
true;
2496 if (!has_sig_changes)
2497 has_sig_changes =
true;
2500 cmap.setAccess(access);
2501 constlist.assimilate(cmap,
"class", name.c_str());
2504 DLLLOCAL
void parseAddConstant(
const QoreProgramLocation* loc,
const std::string &cname,
QoreValue val, ClassAccess access) {
2506 if (parseCheckSystemCommitted(loc)) {
2509 if (parseHasVar(cname.c_str())) {
2510 parse_error(*loc,
"'%s' has already been declared as a static variable in class '%s' and therefore cannot be also declared as a constant in the same class with the same name", cname.c_str(), name.c_str());
2513 if (!has_new_user_changes)
2514 has_new_user_changes =
true;
2515 if (!has_sig_changes)
2516 has_sig_changes =
true;
2520 constlist.parseAdd(loc, cname, val_holder.release(), access, name.c_str());
2523 DLLLOCAL
bool parseHasVar(
const char* vn) {
2524 return vars.inList(vn);
2527 DLLLOCAL
bool parseHasConstant(
const std::string &cname)
const {
2528 return constlist.inList(cname);
2531 DLLLOCAL
QoreValue parseFindLocalConstantValue(
const char* cname,
const QoreTypeInfo*& cTypeInfo,
bool& found) {
2535 ClassAccess access = Public;
2536 QoreValue rv = constlist.find(cname, cTypeInfo, access, found);
2539 if (found && (access > Public)) {
2540 qore_class_private* class_ctx = parse_get_class_priv();
2541 if ((access >= Internal && class_ctx !=
this) || !parseCheckPrivateClassAccess(class_ctx)) {
2543 cTypeInfo =
nullptr;
2553 DLLLOCAL
QoreValue parseFindConstantValue(
const char* cname,
const QoreTypeInfo*& cTypeInfo,
bool& found,
2554 const qore_class_private* class_ctx) {
2556 return parseFindConstantValueIntern(cname, cTypeInfo, found, class_ctx);
2559 DLLLOCAL
QoreValue parseFindConstantValueIntern(
const char* cname,
const QoreTypeInfo*& cTypeInfo,
bool& found,
2560 const qore_class_private* class_ctx) {
2564 ClassAccess access = Public;
2565 QoreValue rv = constlist.find(cname, cTypeInfo, access, found);
2569 if (access == Internal) {
2570 if (class_ctx ==
this)
2573 cTypeInfo =
nullptr;
2576 }
else if (access == Private && !parseCheckPrivateClassAccess(class_ctx)) {
2577 cTypeInfo =
nullptr;
2584 return scl ? scl->parseFindConstantValue(cname, cTypeInfo, found, class_ctx, class_ctx ==
this) :
QoreValue();
2587 DLLLOCAL QoreVarInfo* parseFindLocalStaticVar(
const char* vname)
const {
2588 QoreVarInfo* vi = vars.find(vname);
2590 if (vi && (vi->access > Public) && !parseCheckPrivateClassAccess())
2596 DLLLOCAL QoreVarInfo* parseFindStaticVar(
const char* vname,
const QoreClass*& qc, ClassAccess& access,
bool check =
false)
const {
2598 return parseFindStaticVarIntern(vname, qc, access, check,
true);
2601 DLLLOCAL QoreVarInfo* parseFindStaticVarIntern(
const char* vname,
const QoreClass*& qc, ClassAccess& access,
bool check,
bool toplevel)
const {
2602 QoreVarInfo* vi = vars.find(vname);
2605 ClassAccess va = vi->getAccess();
2606 if (toplevel || va != Internal) {
2612 if (check && (access > Public) && !parseCheckPrivateClassAccess()) {
2621 return scl ? scl->parseFindStaticVar(vname, qc, access, check, toplevel) :
nullptr;
2624 DLLLOCAL
void addMember(
const char* mem, ClassAccess access,
const QoreTypeInfo* n_typeinfo,
QoreValue initial_value) {
2625 assert(!members.inList(mem));
2626 if (!has_sig_changes) {
2627 has_sig_changes =
true;
2629 members.addNoCheck(strdup(mem),
new QoreMemberInfo(&loc_builtin, n_typeinfo,
nullptr, initial_value, access,
this));
2630 if (access == Public && !has_public_memdecl) {
2631 has_public_memdecl =
true;
2635 DLLLOCAL
void insertBuiltinStaticMethod(
QoreMethod* m) {
2640 ++num_static_methods;
2642 sys = committed =
true;
2645 assert(!checkSpecialStaticIntern(m->
getName()));
2647 addStaticAncestors(m);
2650 DLLLOCAL
void insertBuiltinMethod(
QoreMethod* m,
bool special_method =
false) {
2657 sys = committed =
true;
2660 if (!special_method && !checkAssignSpecialIntern(m))
2665 DLLLOCAL
void recheckBuiltinMethodHierarchy();
2667 DLLLOCAL
void addNewAncestors(
QoreMethod* m) {
2672 scl->addNewAncestors(m);
2675 DLLLOCAL
void addNewStaticAncestors(
QoreMethod* m) {
2680 scl->addNewStaticAncestors(m);
2683 DLLLOCAL
void addStaticAncestors(
QoreMethod* m) {
2688 scl->addStaticAncestors(m);
2692 assert(strcmp(m->
getName(),
"constructor"));
2698 scl->addAncestors(m);
2701 DLLLOCAL
void parseAddStaticAncestors(
QoreMethod* m) {
2706 scl->parseAddStaticAncestors(m);
2709 DLLLOCAL
void parseAddAncestors(
QoreMethod* m) {
2711 assert(strcmp(m->
getName(),
"constructor"));
2716 scl->parseAddAncestors(m);
2721 DLLLOCAL
int initMember(
QoreObject& o,
bool& need_scan,
const char* member_name,
const QoreMemberInfo& info,
const qore_class_private* member_class_ctx,
ExceptionSink* xsink)
const;
2731 constlist.deleteAll(xsink);
2744 DLLLOCAL
void deleteClassData(
bool deref_vars,
ExceptionSink* xsink) {
2754 for (
auto& i : kvmap) {
2755 i.second.discard(xsink);
2765 if (deref_source_program) {
2793 const qore_class_private* class_ctx,
ExceptionSink* xsink)
const;
2800 DLLLOCAL
void addBuiltinMethod(
const char* mname, MethodVariantBase* variant);
2801 DLLLOCAL
void addBuiltinStaticMethod(
const char* mname, MethodVariantBase* variant);
2802 DLLLOCAL
void addBuiltinConstructor(BuiltinConstructorVariantBase* variant);
2803 DLLLOCAL
void addBuiltinDestructor(BuiltinDestructorVariantBase* variant);
2804 DLLLOCAL
void addBuiltinCopyMethod(BuiltinCopyVariantBase* variant);
2805 DLLLOCAL
void setBuiltinSystemConstructor(BuiltinSystemConstructorBase* m);
2812 DLLLOCAL
QoreMethod* parseFindLocalMethod(
const char* nme) {
2813 hm_method_t::iterator i = hm.find(nme);
2814 return (i != hm.end()) ? i->second :
nullptr;
2817 DLLLOCAL
const QoreMethod* parseFindLocalMethod(
const char* nme)
const {
2818 hm_method_t::const_iterator i = hm.find(nme);
2819 return (i != hm.end()) ? i->second :
nullptr;
2822 DLLLOCAL
QoreMethod* parseFindLocalMethod(
const std::string& nme) {
2823 hm_method_t::iterator i = hm.find(nme);
2824 return (i != hm.end()) ? i->second :
nullptr;
2827 DLLLOCAL
const QoreMethod* parseFindLocalMethod(
const std::string& nme)
const {
2828 hm_method_t::const_iterator i = hm.find(nme);
2829 return (i != hm.end()) ? i->second :
nullptr;
2833 DLLLOCAL
const QoreMethod* parseFindAnyLocalMethod(
const char* nme)
const {
2834 const QoreMethod* m = parseFindLocalMethod(nme);
2835 return m ? m : parseFindLocalStaticMethod(nme);
2839 DLLLOCAL
QoreMethod* parseFindLocalStaticMethod(
const char* nme) {
2840 hm_method_t::iterator i = shm.find(nme);
2841 return (i != shm.end()) ? i->second :
nullptr;
2844 DLLLOCAL
const QoreMethod* parseFindLocalStaticMethod(
const char* nme)
const {
2845 hm_method_t::const_iterator i = shm.find(nme);
2846 return (i != shm.end()) ? i->second :
nullptr;
2849 DLLLOCAL
const QoreMethod* parseGetConstructor()
const {
2850 const_cast<qore_class_private*
>(
this)->initialize();
2854 return parseFindLocalMethod(
"constructor");
2857 DLLLOCAL
void unsetPublicMemberFlag() {
2858 assert(has_public_memdecl);
2859 has_public_memdecl =
false;
2866 DLLLOCAL
QoreMethod* findLocalCommittedMethod(
const char* nme);
2868 DLLLOCAL
const QoreMethod* findLocalCommittedMethod(
const char* nme)
const;
2871 DLLLOCAL
QoreMethod* findLocalCommittedStaticMethod(
const char* nme);
2873 DLLLOCAL
const QoreMethod* findLocalCommittedStaticMethod(
const char* nme)
const;
2875 DLLLOCAL
void finalizeBuiltin(
const char* nspath);
2876 DLLLOCAL
void generateBuiltinSignature(
const char* nspath);
2877 DLLLOCAL
void initializeBuiltin();
2883 DLLLOCAL
static const QoreMethod* doParseMethodAccess(
const QoreMethod* m,
const qore_class_private* class_ctx);
2885 DLLLOCAL
static const QoreMethod* doMethodAccess(
const QoreMethod* m, ClassAccess ma,
const qore_class_private* class_ctx) {
2887 return ((ma == Public) || ((ma == Private && class_ctx))) ? m :
nullptr;
2890 DLLLOCAL
static const QoreMethod* doMethodAccess(
const QoreMethod* m, ClassAccess& access, ClassAccess ma) {
2895 else if (access < ma)
2901 DLLLOCAL
const QoreMethod* doRuntimeMethodAccess(
const QoreMethod* m, ClassAccess& access, ClassAccess ma,
const qore_class_private* class_ctx)
const {
2904 if (ma >= Internal && (!class_ctx || !equal(*class_ctx)))
2906 else if (access < ma)
2913 DLLLOCAL
const QoreMethod* parseFindNormalMethod(
const char* mname,
const qore_class_private* class_ctx);
2916 DLLLOCAL
const QoreMethod* parseFindStaticMethod(
const char* mname,
const qore_class_private* class_ctx);
2919 DLLLOCAL
const QoreMethod* parseFindNormalMethodIntern(
const char* mname,
const qore_class_private* class_ctx);
2922 DLLLOCAL
const QoreMethod* parseFindStaticMethodIntern(
const char* mname,
const qore_class_private* class_ctx);
2924 DLLLOCAL
const QoreMethod* parseResolveSelfMethodIntern(
const QoreProgramLocation* loc,
const char* nme,
2925 const qore_class_private* class_ctx);
2929 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethodIntern(
const char* nme, ClassAccess& access,
2930 const qore_class_private* class_ctx)
const {
2931 const QoreMethod* m = findLocalCommittedStaticMethod(nme);
2933 (class_ctx ==
this || doRuntimeMethodAccess(m, access, m->
getAccess(), class_ctx))) {
2940 return scl->runtimeFindCommittedStaticMethod(nme, access, class_ctx, class_ctx ==
this);
2945 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethodIntern(
const char* nme, ClassAccess& access,
2946 const qore_class_private* class_ctx)
const {
2947 const QoreMethod* m = findLocalCommittedMethod(nme);
2951 (class_ctx ==
this || doRuntimeMethodAccess(m, access, m->
getAccess(), class_ctx))) {
2958 return scl->runtimeFindCommittedMethod(nme, access, class_ctx, class_ctx ==
this);
2961 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethod(
const char* nme, ClassAccess& access,
2962 const qore_class_private* class_ctx)
const;
2964 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethod(
const char* nme, ClassAccess& access,
2965 const qore_class_private* class_ctx)
const;
2967 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethodForEval(
const char* nme, ClassAccess& access,
2968 const qore_class_private* class_ctx)
const;
2970 DLLLOCAL
const QoreMethod* runtimeFindAnyCommittedMethod(
const char* nme)
const {
2971 ClassAccess access = Public;
2972 const qore_class_private* class_ctx =
this;
2973 const QoreMethod* m = runtimeFindCommittedMethodIntern(nme, access, class_ctx);
2976 if (!strcmp(nme,
"constructor"))
2978 if (!strcmp(nme,
"destructor"))
2980 if (!strcmp(nme,
"copy"))
2982 if (!strcmp(nme,
"methodGate"))
2984 if (!strcmp(nme,
"memberGate"))
2986 if (!strcmp(nme,
"memberNotification"))
2987 return memberNotification;
2992 DLLLOCAL
const QoreMethod* findMethod(
const char* nme, ClassAccess& access)
const {
2993 CurrentProgramRuntimeParseContextHelper pch;
2994 const qore_class_private* class_ctx = runtime_get_class();
2995 if (class_ctx && !runtimeCheckPrivateClassAccess(class_ctx))
2996 class_ctx =
nullptr;
2997 return runtimeFindCommittedMethod(nme, access, class_ctx);
3000 DLLLOCAL
bool runtimeHasCallableMethod(
const char* m,
int mask)
const;
3010 DLLLOCAL
int parseInit();
3011 DLLLOCAL
int parseResolveHierarchy();
3012 DLLLOCAL
void parseResolveClassMembers();
3013 DLLLOCAL
void parseResolveAbstract();
3014 DLLLOCAL
void parseCommit();
3016 DLLLOCAL
void parseRollback();
3017 DLLLOCAL
int addUserMethod(
const char* mname, MethodVariantBase* f,
bool n_static);
3018 DLLLOCAL
void addLocalMembersForInit();
3023 DLLLOCAL
QoreValue evalPseudoMethod(
const QoreMethod* m,
const AbstractQoreFunctionVariant* variant,
3030 const qore_class_private* class_ctx = runtime_get_class();
3031 if (class_ctx && !runtimeCheckPrivateClassAccess(class_ctx)) {
3032 class_ctx =
nullptr;
3035 if (!(w = runtimeFindCommittedMethod(nme, access, class_ctx))) {
3039 const char* cname = n.
get<
const QoreObject>()->getClassName();
3040 xsink->
raiseException(
"METHOD-DOES-NOT-EXIST",
"no method %s::%s() or pseudo-method %s::%s() is " \
3041 "available", cname, nme, name.c_str(), nme);
3043 xsink->
raiseException(
"PSEUDO-METHOD-DOES-NOT-EXIST",
"no pseudo method <%s>::%s() has been defined",
3052 DLLLOCAL
bool parseCheckPrivateClassAccess(
const qore_class_private* qc = parse_get_class_priv())
const;
3053 DLLLOCAL
bool runtimeCheckPrivateClassAccess(
const qore_class_private* qc = runtime_get_class())
const;
3056 DLLLOCAL qore_type_result_e parseCheckCompatibleClass(
const qore_class_private& oc)
const {
3057 bool may_not_match =
false;
3058 qore_type_result_e rv = parseCheckCompatibleClass(oc, may_not_match);
3061 return QTI_NOT_EQUAL;
3065 DLLLOCAL qore_type_result_e parseCheckCompatibleClass(
const qore_class_private& oc,
bool& may_not_match)
const;
3066 DLLLOCAL qore_type_result_e parseCheckCompatibleClassIntern(
const qore_class_private& oc,
bool& may_not_match)
const;
3068 DLLLOCAL qore_type_result_e runtimeCheckCompatibleClass(
const qore_class_private& oc)
const;
3069 DLLLOCAL qore_type_result_e runtimeCheckCompatibleClassIntern(
const qore_class_private& oc)
const;
3072 DLLLOCAL
const QoreClass* findInHierarchy(
const qore_class_private& qc) {
3075 return scl ? scl->findInHierarchy(qc) :
nullptr;
3081 return scl ? scl->
getClass(cid, n_access, toplevel) :
nullptr;
3084 DLLLOCAL
const QoreClass* getClass(
const qore_class_private& qc, ClassAccess& n_access)
const {
3086 return getClassIntern(qc, n_access,
true);
3089 DLLLOCAL
const QoreClass* getClassIntern(
const qore_class_private& qc, ClassAccess& n_access,
3090 bool toplevel)
const {
3096 if (qc.name == name) {
3099 qc.hash.toString(rh);
3100 printd(5,
"qore_class_private::getClassIntern() this: %p '%s' != '%s' scl: %p (hash: %s qc.hash: %s)\n",
3105 return scl ? scl->getClass(qc, n_access, toplevel) :
nullptr;
3108 DLLLOCAL
const QoreClass* parseGetClassIntern(
const qore_class_private& qc, ClassAccess& n_access,
3109 bool toplevel)
const {
3116 if (qc.name == name) {
3117 printd(5,
"qore_class_private::parseGetClassIntern() this: %p '%s' != '%s' scl: %p\n",
this, name.c_str(),
3118 qc.name.c_str(), scl);
3120 qc.parseShowHashes();
3124 return scl ? scl->parseGetClass(qc, n_access, toplevel) :
nullptr;
3127 DLLLOCAL
bool inHierarchy(
const qore_class_private& qc, ClassAccess& n_access)
const {
3132 return scl ? scl->
inHierarchy(qc, n_access) :
false;
3135 DLLLOCAL
bool inHierarchyStrict(
const qore_class_private& qc, ClassAccess& n_access)
const {
3136 if (strictEqual(qc)) {
3144 DLLLOCAL
void parseShowHash()
const {
3147 printd(5,
" + %p %s committed: %s\n",
this, name.c_str(), ch.
getBuffer());
3151 DLLLOCAL
bool parseCheckEqualHash(
const qore_class_private& qc)
const {
3153 printd(5,
"qore_class_private::parseCheckEqualHash() %s == %s\n", name.c_str(), qc.name.c_str());
3157 return hash == qc.hash;
3160 DLLLOCAL
bool strictEqual(
const qore_class_private& qc)
const {
3165 if (qc.classID == classID || (qc.name == name && qc.hash == hash)) {
3172 DLLLOCAL
bool equal(
const qore_class_private& qc)
const {
3176 if (qc.classID == classID || (qc.name == name && qc.hash == hash))
3179 if (injectedClass && injectedClass->equal(qc))
3182 if (qc.injectedClass && equal(*qc.injectedClass))
3188 DLLLOCAL
bool parseEqual(
const qore_class_private& qc)
const {
3192 if (qc.classID == classID || (qc.name == name && parseCheckEqualHash(qc)))
3195 if (injectedClass && injectedClass->parseEqual(qc))
3198 if (qc.injectedClass && parseEqual(*qc.injectedClass))
3204 DLLLOCAL
const QoreClass* parseGetClass(
const qore_class_private& qc, ClassAccess& n_access)
const;
3206 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* sc,
bool is_virtual);
3208 DLLLOCAL
void setPublic();
3210 DLLLOCAL
void parseSetBaseClassList(BCList* bcl) {
3214 if (!has_new_user_changes)
3215 has_new_user_changes =
true;
3216 if (!has_sig_changes)
3217 has_sig_changes =
true;
3221 DLLLOCAL
bool parseHasPendingChanges()
const {
3222 return has_new_user_changes;
3225 DLLLOCAL
bool parseCheckHierarchy(
const QoreClass* n_cls, ClassAccess& access)
const {
3227 return parseCheckHierarchyIntern(n_cls, access,
true);
3230 DLLLOCAL
bool parseCheckHierarchyIntern(
const QoreClass* n_cls, ClassAccess& access,
bool toplevel)
const {
3231 if (parseEqual(*n_cls->priv))
3234 return scl ? scl->parseCheckHierarchy(n_cls, access, toplevel) :
false;
3237 DLLLOCAL VRMutex* getGate()
const {
3242 DLLLOCAL
const QoreMethod* parseFindAnyMethod(
const char* nme,
const qore_class_private* class_ctx);
3245 DLLLOCAL
const QoreMethod* parseFindAnyMethodStaticFirst(
const char* nme,
const qore_class_private* class_ctx);
3248 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc,
const char* nme,
3249 const qore_class_private* class_ctx);
3250 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc, NamedScope* nme);
3253 DLLLOCAL
const QoreMethod* parseFindSelfMethod(
const char* nme);
3255 DLLLOCAL
char* getHash()
const {
3256 return hash.getHash();
3260 assert(!serializer);
3265 assert(!deserializer);
3272 DLLLOCAL
static char* getHash(
const QoreClass& qc) {
3273 return qc.priv->getHash();
3276 DLLLOCAL
static void parseAddConstant(
QoreClass& qc,
const QoreProgramLocation* loc,
const std::string &cname,
3278 qc.priv->parseAddConstant(loc, cname, val, access);
3281 DLLLOCAL
static LocalVar* getSelfId(
const QoreClass& qc) {
3282 return &qc.priv->selfid;
3285 DLLLOCAL
static QoreObject* execConstructor(
const QoreClass& qc,
const AbstractQoreFunctionVariant* variant,
3287 return qc.priv->execConstructor(xsink, variant, args);
3290 DLLLOCAL
static bool injected(
const QoreClass& qc) {
3291 return qc.priv->inject;
3295 const qore_class_private* injectedClass, qore_ns_private* ns, q_setpub_t set_pub) {
3296 qore_class_private* priv =
new qore_class_private(*qc.priv, ns, spgm, nme, inject, injectedClass, set_pub);
3302 DLLLOCAL
static const QoreMethod* runtimeFindCommittedStaticMethod(
const QoreClass& qc,
const char* nme,
3303 ClassAccess& access,
const qore_class_private* class_ctx) {
3304 return qc.priv->runtimeFindCommittedStaticMethod(nme, access, class_ctx);
3307 DLLLOCAL
static const QoreMethod* parseFindLocalMethod(
const QoreClass& qc,
const char* mname) {
3308 return qc.priv->parseFindLocalMethod(mname);
3311 DLLLOCAL
static bool parseHasPendingChanges(
const QoreClass& qc) {
3312 return qc.priv->parseHasPendingChanges();
3315 DLLLOCAL
static int parseCheckMemberAccess(
const QoreClass& qc,
const QoreProgramLocation* loc,
const char* mem,
3316 const QoreTypeInfo*& memberTypeInfo,
int pflag) {
3317 return qc.priv->parseCheckMemberAccess(loc, mem, memberTypeInfo, pflag);
3320 DLLLOCAL
static bool runtimeHasCallableMethod(
const QoreClass& qc,
const char* m) {
3321 return qc.priv->runtimeHasCallableMethod(m, QCCM_NORMAL | QCCM_STATIC);
3324 DLLLOCAL
static bool runtimeHasCallableNormalMethod(
const QoreClass& qc,
const char* m) {
3325 return qc.priv->runtimeHasCallableMethod(m, QCCM_NORMAL);
3328 DLLLOCAL
static bool runtimeHasCallableStaticMethod(
const QoreClass& qc,
const char* m) {
3329 return qc.priv->runtimeHasCallableMethod(m, QCCM_STATIC);
3333 return qc.priv->runtimeCheckInstantiateClass(xsink);
3336 DLLLOCAL
static int parseInitPartial(
QoreClass& qc) {
3337 return qc.priv->parseInitPartial();
3340 DLLLOCAL
static void parseCommit(
QoreClass& qc) {
3341 qc.priv->parseCommit();
3345 qc.priv->parseCommitRuntimeInit(xsink);
3348 DLLLOCAL
static void parseRollback(
QoreClass& qc) {
3349 qc.priv->parseRollback();
3352 DLLLOCAL
static void resolveCopy(
QoreClass& qc) {
3353 qc.priv->resolveCopy();
3356 DLLLOCAL
static int addUserMethod(
QoreClass& qc,
const char* mname, MethodVariantBase* f,
bool n_static) {
3357 return qc.priv->addUserMethod(mname, f, n_static);
3360 DLLLOCAL
static void initialize(
QoreClass& qc) {
3361 qc.priv->initialize();
3364 DLLLOCAL
static void parseSetBaseClassList(
QoreClass& qc, BCList* bcl) {
3365 qc.priv->parseSetBaseClassList(bcl);
3368 DLLLOCAL
static BCList* getBaseClassList(
const QoreClass& qc) {
3369 return qc.priv->scl;
3372 DLLLOCAL
static void parseAddStaticVar(
QoreClass* qc,
char* dname, ClassAccess access, QoreVarInfo* VarInfo) {
3373 qc->priv->parseAddStaticVar(dname, access, VarInfo);
3377 DLLLOCAL
static QoreValue parseFindLocalConstantValue(
QoreClass* qc,
const char* cname,
3378 const QoreTypeInfo*& typeInfo,
bool& found) {
3379 return qc->priv->parseFindLocalConstantValue(cname, typeInfo, found);
3383 DLLLOCAL
static QoreVarInfo* parseFindLocalStaticVar(
const QoreClass* qc,
const char* vname) {
3384 return qc->priv->parseFindLocalStaticVar(vname);
3388 DLLLOCAL
static QoreValue parseFindConstantValue(
QoreClass* qc,
const char* cname,
const QoreTypeInfo*& typeInfo,
3389 bool& found,
const qore_class_private* class_ctx) {
3390 return qc->priv->parseFindConstantValue(cname, typeInfo, found, class_ctx);
3395 DLLLOCAL
static QoreVarInfo* parseFindStaticVar(
const QoreClass* qc,
const char* vname,
const QoreClass*& nqc,
3396 ClassAccess& access,
bool check =
false) {
3397 return qc->priv->parseFindStaticVar(vname, nqc, access, check);
3400 DLLLOCAL
static int parseCheckInternalMemberAccess(
const QoreClass* qc,
const char* mem,
3401 const QoreTypeInfo*& memberTypeInfo,
const QoreProgramLocation* loc) {
3402 return qc->priv->parseCheckInternalMemberAccess(mem, memberTypeInfo, loc);
3405 DLLLOCAL
static int parseResolveInternalMemberAccess(
const QoreClass* qc,
const char* mem,
3406 const QoreTypeInfo*& memberTypeInfo) {
3407 return qc->priv->parseResolveInternalMemberAccess(mem, memberTypeInfo);
3411 return qc->priv->parseFindSelfMethod(mname);
3414 DLLLOCAL
static void parseAddMember(
QoreClass& qc,
char* nme, ClassAccess access, QoreMemberInfo* mInfo) {
3415 qc.priv->parseAddMember(nme, access, mInfo);
3420 return qc->priv->evalPseudoMethod(n, name, args, xsink);
3426 return qc->priv->evalPseudoMethod(m, variant, n, args, xsink);
3429 DLLLOCAL
static bool parseCheckPrivateClassAccess(
const QoreClass& qc,
3430 const qore_class_private* oqc = parse_get_class_priv()) {
3431 return qc.priv->parseCheckPrivateClassAccess(oqc);
3434 DLLLOCAL
static bool runtimeCheckPrivateClassAccess(
const QoreClass& qc,
3435 const qore_class_private* oqc = runtime_get_class()) {
3436 return qc.priv->runtimeCheckPrivateClassAccess(oqc);
3439 DLLLOCAL
static qore_type_result_e parseCheckCompatibleClass(
const QoreClass* qc,
const QoreClass* oc) {
3441 return QTI_NOT_EQUAL;
3442 return qc->priv->parseCheckCompatibleClass(*(oc->priv));
3445 DLLLOCAL
static qore_type_result_e runtimeCheckCompatibleClass(
const QoreClass& qc,
const QoreClass& oc) {
3446 return qc.priv->runtimeCheckCompatibleClass(*oc.priv);
3449 DLLLOCAL
static qore_class_private* get(
QoreClass& qc) {
3453 DLLLOCAL
static const qore_class_private* get(
const QoreClass& qc) {
3457 DLLLOCAL
static bool isPublic(
const QoreClass& qc) {
3458 return qc.priv->pub;
3461 DLLLOCAL
static bool isUserPublic(
const QoreClass& qc) {
3462 return qc.priv->pub && !qc.priv->sys;
3465 DLLLOCAL
static bool isFinal(
const QoreClass& qc) {
3466 return qc.priv->final;
3469 DLLLOCAL
static void setPublic(
QoreClass& qc) {
3470 qc.priv->setPublic();
3473 DLLLOCAL
static void setFinal(
QoreClass& qc) {
3474 assert(!qc.priv->final);
3475 qc.priv->final =
true;
3480 DLLLOCAL ~qore_class_private();
3483class qore_class_private_holder {
3484 qore_class_private* c;
3487 DLLLOCAL qore_class_private_holder(
QoreClass* n_c) : c(qore_class_private::get(*n_c)) {
3490 DLLLOCAL qore_class_private_holder(qore_class_private* n_c) : c(n_c) {
3493 DLLLOCAL ~qore_class_private_holder() {
3495 c->deref(
true,
true);
3499 DLLLOCAL qore_class_private* operator*() {
3513class qore_method_private {
3516 MethodFunctionBase* func;
3517 bool static_flag, all_user;
3519 DLLLOCAL qore_method_private(
const QoreClass* n_parent_class, MethodFunctionBase* n_func,
bool n_static)
3520 : parent_class(n_parent_class), func(n_func), static_flag(n_static), all_user(true) {
3521 assert(parent_class == n_func->getClass());
3524 DLLLOCAL ~qore_method_private() {
3528 DLLLOCAL
void setBuiltin() {
3533 DLLLOCAL
bool isUniquelyUser()
const {
3537 DLLLOCAL
bool isAbstract()
const {
3538 return func->isAbstract();
3541 DLLLOCAL
int addUserVariant(MethodVariantBase* variant) {
3542 return func->parseAddUserMethodVariant(variant);
3545 DLLLOCAL
void addBuiltinVariant(MethodVariantBase* variant) {
3547 func->addBuiltinMethodVariant(variant);
3550 DLLLOCAL MethodFunctionBase* getFunction()
const {
3551 return const_cast<MethodFunctionBase*
>(func);
3554 DLLLOCAL
const char* getName()
const {
3555 return func->getName();
3558 DLLLOCAL
const std::string& getNameStr()
const {
3559 return func->getNameStr();
3562 DLLLOCAL
int parseInit();
3564 DLLLOCAL
int parseInitStatic() {
3565 assert(static_flag);
3566 int err = func->parseInit();
3568 if (func->checkFinal() && !err) {
3574 DLLLOCAL
const QoreTypeInfo* getUniqueReturnTypeInfo()
const {
3575 return func->getUniqueReturnTypeInfo();
3578 DLLLOCAL
void evalConstructor(
const AbstractQoreFunctionVariant* variant,
QoreObject* self,
3580 CONMF(func)->evalConstructor(variant, *parent_class, self, args, parent_class->priv->scl, bceal, xsink);
3584 COPYMF(func)->evalCopy(*parent_class, self, old, parent_class->priv->scl, xsink);
3588 COPYMF(func)->evalCopy(*parent_class, self, old,
nullptr, xsink);
3592 DESMF(func)->evalDestructor(*parent_class, self, xsink);
3597 DESMF(func)->evalDestructor(*parent_class, self, xsink);
3600 DLLLOCAL
void evalSystemConstructor(
QoreObject* self,
int code, va_list args)
const {
3601 BSYSCONB(func)->eval(*parent_class, self, code, args);
3605 const qore_class_private* cctx =
nullptr)
const {
3608 return NMETHF(func)->evalMethod(xsink, 0, self, args, cctx);
3610 return SMETHF(func)->evalMethod(xsink, 0, args, cctx);
3614 const qore_class_private* cctx =
nullptr)
const {
3617 return NMETHF(func)->evalMethodTmpArgs(xsink,
nullptr, self, args, cctx);
3619 return SMETHF(func)->evalMethodTmpArgs(xsink,
nullptr, args, cctx);
3622 DLLLOCAL
QoreValue evalPseudoMethod(
const AbstractQoreFunctionVariant* variant,
const QoreValue n,
3626 assert(!static_flag);
3628 QoreValue rv = NMETHF(func)->evalPseudoMethod(xsink, variant, n, args);
3629 printd(5,
"qore_method_private::evalPseudoMethod() %s::%s() returning type: %s\n", parent_class->
getName(),
3638 DLLLOCAL ClassAccess getAccess()
const;
3641 DLLLOCAL
static ClassAccess getAccess(
const QoreMethod& m) {
3642 return m.priv->getAccess();
3647 return m.priv->evalNormalVariant(self, ev, args, xsink);
3652 return m.priv->evalPseudoMethod(variant, n, args, xsink);
3656 const QoreListNode* args,
const qore_class_private* cctx =
nullptr) {
3657 return m.priv->eval(xsink, self, args, cctx);
3661 QoreListNode* args,
const qore_class_private* cctx =
nullptr) {
3662 return m.priv->evalTmpArgs(xsink, self, args, cctx);
3665 DLLLOCAL
static qore_method_private* get(
QoreMethod& m) {
3669 DLLLOCAL
static const qore_method_private* get(
const QoreMethod& m) {
3675class PrivateIteratorBase {
3677 DLLLOCAL PrivateIteratorBase(
const T& obj) : obj(obj), i(obj.end()) {
3680 DLLLOCAL
bool next() {
3681 if (i == obj.end()) {
3686 return (i != obj.end());
3690 DLLLOCAL
bool valid()
const {
3691 return i != obj.end();
3696 typename T::const_iterator i;
3699template <
class T,
class U>
3700class PrivateMemberIteratorBase :
public PrivateIteratorBase<typename T::member_list_t> {
3702 DLLLOCAL PrivateMemberIteratorBase(
const typename T::member_list_t& obj)
3703 : PrivateIteratorBase<typename T::member_list_t>(obj) {
3706 DLLLOCAL
const U& getMember()
const {
3707 assert(this->valid());
3708 return *
reinterpret_cast<const U*
>(this->i->second.get());
3711 DLLLOCAL
const char* getName()
const {
3712 assert(this->valid());
3713 return this->i->first;
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:327
#define QDOM_DEFAULT
the default domain (no domain)
Definition: Restrictions.h:170
#define PO_REQUIRE_TYPES
require type information for all declarations
Definition: Restrictions.h:61
#define PO_STRICT_TYPES
enforce strict type checking and setting default values
Definition: Restrictions.h:98
#define PO_BROKEN_VARARGS
allow for old pre-Qore 1.17 vararg handling with implicit ellipses
Definition: Restrictions.h:101
the base class for all data to be used as private data of Qore objects
Definition: AbstractPrivateData.h:44
an abstract class for class-specific external user data
Definition: QoreClass.h:237
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
defines a Qore-language class
Definition: QoreClass.h:253
DLLEXPORT bool inHierarchy(const QoreClass &cls, ClassAccess &n_access) const
Returns true if the class passed as an argument is present in the current class's hierachy,...
DLLEXPORT bool inHierarchyStrict(const QoreClass &cls, ClassAccess &n_access) const
Returns true if the class passed as an argument is present in the current class's hierachy,...
DLLEXPORT const QoreClass * getClass(qore_classid_t cid) const
returns a pointer to the QoreClass object representing the class ID passed if it exists in the class ...
DLLEXPORT const char * getName() const
returns the class name
external wrapper class for method variants
Definition: QoreReflection.h:90
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
a method in a QoreClass
Definition: QoreClass.h:139
DLLEXPORT const char * getName() const
returns the method's name
DLLEXPORT bool isStatic() const
returns true if the method is static
DLLEXPORT ClassAccess getAccess() const
returns the lowest access code of all variants in the method
DLLEXPORT const QoreClass * getClass() const
returns a pointer to the parent class
the implementation of Qore's object data type, reference counted, dynamically-allocated only
Definition: QoreObject.h:60
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:128
virtual DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count of the object
provides atomic reference counting to Qore objects
Definition: QoreReferenceCounter.h:44
DLLEXPORT void ROreference() const
atomically increments the reference count
DLLEXPORT int reference_count() const
gets the reference count
DLLEXPORT bool ROdereference() const
atomically decrements the reference count
DLLLOCAL detail::QoreValueCastHelper< T >::Result get()
returns the value as the given type
Definition: QoreValue.h:214
DLLEXPORT qore_type_t getType() const
returns the type of value contained
DLLEXPORT const char * getTypeName() const
returns a string type description of the value contained (ex: "nothing" for a null AbstractQoreNode p...
DLLEXPORT void clear()
unconditionally set the QoreValue to QoreNothingNode (does not dereference any possible contained Abs...
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT const char * c_str() const
returns the string's buffer; this data should not be changed
DLLEXPORT void clear()
reset string to zero length; memory is not deallocated; string encoding does not change
DLLEXPORT const char * getBuffer() const
returns the string's buffer; this data should not be changed
DLLEXPORT int sprintf(const char *fmt,...)
this will concatentate a formatted string to the existing string according to the format string and t...
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
holds an object and dereferences it in the destructor
Definition: QoreValue.h:487
QoreValue(* q_external_method_t)(const QoreMethod &method, const void *ptr, QoreObject *self, AbstractPrivateData *private_data, const QoreListNode *args, q_rt_flags_t flags, ExceptionSink *xsink)
the type used for builtin QoreClass method signatures
Definition: common.h:345
void(* q_external_destructor_t)(const QoreClass &thisclass, const void *ptr, QoreObject *self, AbstractPrivateData *private_data, ExceptionSink *xsink)
the type used for builtin QoreClass destructor signatures with the new generic calling convention and...
Definition: common.h:408
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode)
Definition: common.h:70
uint64_t q_rt_flags_t
runtime code execution flags
Definition: common.h:263
QoreValue(* q_external_static_method_t)(const QoreMethod &method, const void *ptr, const QoreListNode *args, q_rt_flags_t flags, ExceptionSink *xsink)
the type used for external static methods
Definition: common.h:358
QoreValue(* q_func_n_t)(const QoreListNode *args, q_rt_flags_t flags, ExceptionSink *xsink)
the type used for builtin function signatures
Definition: common.h:307
void(* q_copy_t)(QoreObject *self, QoreObject *old, AbstractPrivateData *private_data, ExceptionSink *xsink)
the type used for builtin QoreClass copy signatures
Definition: common.h:417
void(* q_system_constructor_t)(QoreObject *self, int code, va_list args)
the type used for builtin QoreClass system constructor method signatures
Definition: common.h:390
QoreValue(* q_method_n_t)(QoreObject *self, AbstractPrivateData *private_data, const QoreListNode *args, q_rt_flags_t flags, ExceptionSink *xsink)
the type used for builtin QoreClass method signatures
Definition: common.h:330
void(* q_external_constructor_t)(const QoreMethod &method, const void *ptr, QoreObject *self, const QoreListNode *args, q_rt_flags_t rtflags, ExceptionSink *xsink)
the type used for builtin QoreClass constructor method signatures
Definition: common.h:378
std::vector< const QoreTypeInfo * > type_vec_t
vector of type information for parameter lists
Definition: common.h:251
QoreHashNode *(* q_serializer_t)(const QoreObject &self, const AbstractPrivateData &data, QoreSerializationContext &context, ExceptionSink *xsink)
the type used for builtin QoreClass serializer method signatures
Definition: common.h:438
void(* q_destructor_t)(QoreObject *self, AbstractPrivateData *private_data, ExceptionSink *xsink)
the type used for builtin QoreClass destructor signatures
Definition: common.h:398
void(* q_external_copy_t)(const QoreClass &thisclass, const void *ptr, QoreObject *self, QoreObject *old, AbstractPrivateData *private_data, ExceptionSink *xsink)
the type used for builtin QoreClass copy signatures with the new generic calling convention
Definition: common.h:428
unsigned qore_classid_t
used for the unique class ID for QoreClass objects
Definition: common.h:79
std::vector< std::string > name_vec_t
vector of parameter names for parameter lists
Definition: common.h:257
void(* q_deserializer_t)(QoreObject &self, const QoreHashNode *sdata, QoreDeserializationContext &context, ExceptionSink *xsink)
the type used for builtin QoreClass deserializer method signatures
Definition: common.h:450
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:260
void(* q_constructor_n_t)(QoreObject *self, const QoreListNode *args, q_rt_flags_t rtflags, ExceptionSink *xsink)
the type used for builtin QoreClass constructor method signatures
Definition: common.h:366
std::vector< QoreValue > arg_vec_t
vector of value information for default argument lists
Definition: common.h:254
const qore_type_t NT_OBJECT
type value for QoreObject
Definition: node_types.h:52
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:276
DLLEXPORT void discard(ExceptionSink *xsink)
dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values