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"
62 typedef HASH_MAP<std::string, QoreMethod*> hm_method_t;
64 typedef std::map<std::string, QoreMethod*> hm_method_t;
68 class qore_class_private;
73 typedef std::map<const char*, MethodVariantBase*, ltstr> vmap_t;
75 hashdecl 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
122 typedef HASH_MAP<std::string, AbstractMethod*> amap_t;
124 typedef std::map<std::string, AbstractMethod*> amap_t;
127 hashdecl 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;
193 static inline const char* privpub(ClassAccess access) {
194 return access == Public
198 : (access == Internal ?
"private:internal" :
"inaccessible"));
208 class MethodVariantBase :
public AbstractQoreFunctionVariant {
218 DLLLOCAL MethodVariantBase(ClassAccess n_access,
bool n_final,
int64 n_flags,
bool n_is_user =
false,
bool n_is_abstract =
false) :
219 AbstractQoreFunctionVariant(n_flags | (n_is_abstract ? QCF_USES_EXTRA_ARGS : 0), n_is_user), access(n_access), final(n_final), abstract(n_is_abstract) {
222 DLLLOCAL
bool isAbstract()
const {
226 DLLLOCAL
bool isPrivate()
const {
227 return access > Public;
230 DLLLOCAL ClassAccess getAccess()
const {
234 DLLLOCAL
bool isFinal()
const {
238 DLLLOCAL
void clearAbstract() {
247 DLLLOCAL
void setNormalUserMethod(
QoreMethod* n_qm, LocalVar* selfid) {
249 getUserVariantBase()->setSelfId(selfid);
251 assert(selfid->getTypeInfo());
252 assert(QoreTypeInfo::getUniqueReturnClass(selfid->getTypeInfo()));
260 DLLLOCAL
const QoreClass* getClass()
const {
264 DLLLOCAL
const char* getAbstractSignature();
266 DLLLOCAL
const qore_class_private* getClassPriv()
const;
268 DLLLOCAL MethodVariantBase* ref() {
273 DLLLOCAL
void deref() {
280 #define METHVB(f) (reinterpret_cast<MethodVariantBase*>(f))
281 #define METHVB_const(f) (reinterpret_cast<const MethodVariantBase*>(f))
283 class MethodVariant :
public MethodVariantBase {
285 DLLLOCAL MethodVariant(ClassAccess n_access,
bool n_final,
int64 n_flags,
bool n_is_user =
false,
286 bool is_abstract =
false) : MethodVariantBase(n_access, n_final, n_flags, n_is_user, is_abstract) {
295 #define METHV(f) (reinterpret_cast<MethodVariant*>(f))
296 #define METHV_const(f) (reinterpret_cast<const MethodVariant*>(f))
298 class ConstructorMethodVariant :
public MethodVariantBase {
301 DLLLOCAL
int constructorPrelude(
const QoreClass &thisclass, CodeEvaluationHelper& ceh,
QoreObject*
self, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const;
304 DLLLOCAL ConstructorMethodVariant(ClassAccess n_access,
int64 n_flags,
bool n_is_user =
false) : MethodVariantBase(n_access, false, n_flags, n_is_user) {
306 DLLLOCAL
virtual const BCAList* getBaseClassArgumentList()
const = 0;
307 DLLLOCAL
virtual void evalConstructor(
const QoreClass &thisclass,
QoreObject*
self, CodeEvaluationHelper& ceh, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const = 0;
310 #define CONMV(f) (reinterpret_cast<ConstructorMethodVariant*>(f))
311 #define CONMV_const(f) (reinterpret_cast<const ConstructorMethodVariant*>(f))
313 class DestructorMethodVariant :
public MethodVariantBase {
316 DLLLOCAL DestructorMethodVariant(
bool n_is_user =
false) : MethodVariantBase(Public, false, QCF_NO_FLAGS, n_is_user) {
322 #define DESMV(f) (reinterpret_cast<DestructorMethodVariant*>(f))
323 #define DESMV_const(f) (reinterpret_cast<const DestructorMethodVariant*>(f))
325 class CopyMethodVariant :
public MethodVariantBase {
328 DLLLOCAL CopyMethodVariant(ClassAccess n_access,
bool n_is_user =
false) : MethodVariantBase(n_access, false, QCF_NO_FLAGS, n_is_user) {
334 #define COPYMV(f) (reinterpret_cast<CopyMethodVariant*>(f))
335 #define COPYMV_const(f) (reinterpret_cast<const CopyMethodVariant*>(f))
337 class UserMethodVariant :
public MethodVariant,
public UserVariantBase {
342 DLLLOCAL UserMethodVariant(ClassAccess n_access,
bool n_final, StatementBlock* b,
int n_sig_first_line,
343 int n_sig_last_line,
QoreValue params, RetTypeInfo* rv,
bool synced,
int64 n_flags,
bool is_abstract)
344 : MethodVariant(n_access, n_final, n_flags, true, is_abstract),
345 UserVariantBase(b, n_sig_first_line, n_sig_last_line, params, rv, false), synchronized(synced) {
348 DLLLOCAL ~UserMethodVariant() {
352 COMMON_USER_VARIANT_FUNCTIONS
354 DLLLOCAL
virtual int parseInit(QoreFunction* f) {
355 MethodFunctionBase* mf =
static_cast<MethodFunctionBase*
>(f);
359 ParseCodeInfoHelper rtih(mf->getName(), signature.getReturnTypeInfo());
364 if (!mf->isStatic()) {
366 err = statements->parseInitMethod(mf->MethodFunctionBase::getClass()->getTypeInfo(),
this);
369 err = statements->parseInit(
this);
374 f->parseCheckDuplicateSignatureCommitted(&signature);
383 #define UMV(f) (reinterpret_cast<UserMethodVariant*>(f))
384 #define UMV_const(f) (reinterpret_cast<const UserMethodVariant*>(f))
386 class UserConstructorVariant :
public ConstructorMethodVariant,
public UserVariantBase {
391 DLLLOCAL
virtual ~UserConstructorVariant();
394 DLLLOCAL UserConstructorVariant(ClassAccess n_access, StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line,
QoreValue params, BCAList* n_bcal,
int64 n_flags = QCF_NO_FLAGS) : ConstructorMethodVariant(n_access, n_flags, true), UserVariantBase(b, n_sig_first_line, n_sig_last_line, params, nullptr, false), bcal(n_bcal) {
398 COMMON_USER_VARIANT_FUNCTIONS
400 DLLLOCAL
virtual const BCAList* getBaseClassArgumentList()
const {
404 DLLLOCAL
virtual void evalConstructor(
const QoreClass& thisclass,
QoreObject*
self, CodeEvaluationHelper& ceh, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const;
406 DLLLOCAL
virtual int parseInit(QoreFunction* f);
409 #define UCONV(f) (reinterpret_cast<UserConstructorVariant*>(f))
410 #define UCONV_const(f) (reinterpret_cast<const UserConstructorVariant*>(f))
412 class UserDestructorVariant :
public DestructorMethodVariant,
public UserVariantBase {
415 DLLLOCAL UserDestructorVariant(StatementBlock* b,
int n_sig_first_line,
int n_sig_last_line) : DestructorMethodVariant(true), UserVariantBase(b, n_sig_first_line, n_sig_last_line,
QoreValue(), nullptr, false) {
419 COMMON_USER_VARIANT_FUNCTIONS
421 DLLLOCAL
virtual int parseInit(QoreFunction* f) {
422 MethodFunctionBase* mf =
static_cast<MethodFunctionBase*
>(f);
424 int err = signature.resolve();
425 assert(!signature.getReturnTypeInfo() || signature.getReturnTypeInfo() == nothingTypeInfo);
428 ParseCodeInfoHelper rtih(
"destructor", nothingTypeInfo);
431 if (statements->parseInitMethod(mf->MethodFunctionBase::getClass()->getTypeInfo(),
this) && !err) {
441 assert(!signature.numParams());
442 assert(!signature.getReturnTypeInfo() || signature.getReturnTypeInfo() == nothingTypeInfo);
443 eval(
"destructor", 0,
self, xsink, getClassPriv()).discard(xsink);
447 #define UDESV(f) (reinterpret_cast<UserDestructorVariant*>(f))
448 #define UDESV_const(f) (reinterpret_cast<const UserDestructorVariant*>(f))
450 class UserCopyVariant :
public CopyMethodVariant,
public UserVariantBase {
453 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) {
457 COMMON_USER_VARIANT_FUNCTIONS
459 DLLLOCAL
virtual int parseInit(QoreFunction* f);
464 #define UCOPYV(f) (reinterpret_cast<UserCopyVariant*>(f))
466 class BuiltinMethodVariant :
public MethodVariant,
public BuiltinFunctionVariantBase {
468 DLLLOCAL BuiltinMethodVariant(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()) : MethodVariant(n_access, n_final, n_flags), BuiltinFunctionVariantBase(n_functionality, n_returnTypeInfo, n_typeList, n_defaultArgList, n_names) {}
471 COMMON_BUILTIN_VARIANT_FUNCTIONS
474 class BuiltinAbstractMethodVariant :
public BuiltinMethodVariant {
476 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) {
486 class BuiltinNormalMethodVariantBase :
public BuiltinMethodVariant {
488 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) {}
497 class BuiltinNormalMethodValueVariant :
public BuiltinNormalMethodVariantBase {
502 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) {
505 return method(
self, private_data, args, rtflags, xsink);
509 class BuiltinExternalNormalMethodValueVariant :
public BuiltinNormalMethodVariantBase {
515 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) {
518 return method(*qmethod, ptr,
self, private_data, args, rtflags, xsink);
522 class BuiltinStaticMethodValueVariant :
public BuiltinMethodVariant {
527 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) {
531 CodeContextHelper cch(xsink, CT_BUILTIN, qmethod->
getName(), 0, getClassPriv());
533 return static_method(ceh.getArgs(), ceh.getRuntimeFlags(), xsink);
537 class BuiltinExternalStaticMethodValueVariant :
public BuiltinMethodVariant {
543 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) {
547 CodeContextHelper cch(xsink, CT_BUILTIN, qmethod->
getName(), 0, getClassPriv());
549 return static_method(*qmethod, ptr, ceh.getArgs(), ceh.getRuntimeFlags(), xsink);
553 class BuiltinConstructorVariantBase :
public ConstructorMethodVariant,
public BuiltinFunctionVariantBase {
556 DLLLOCAL BuiltinConstructorVariantBase(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()) : ConstructorMethodVariant(n_access, n_flags), BuiltinFunctionVariantBase(n_functionality, 0, n_typeList, n_defaultArgList, n_names) {
560 COMMON_BUILTIN_VARIANT_FUNCTIONS
562 DLLLOCAL
virtual const BCAList* getBaseClassArgumentList()
const {
567 class BuiltinConstructorValueVariant :
public BuiltinConstructorVariantBase {
572 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) {
575 DLLLOCAL
virtual void evalConstructor(
const QoreClass& thisclass,
QoreObject*
self, CodeEvaluationHelper& ceh, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const;
578 class BuiltinExternalConstructorValueVariant :
public BuiltinConstructorVariantBase {
584 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) {
587 DLLLOCAL
virtual void evalConstructor(
const QoreClass& thisclass,
QoreObject*
self, CodeEvaluationHelper& ceh, BCList* bcl, BCEAList* bceal,
ExceptionSink* xsink)
const;
590 class BuiltinDestructorVariantBase :
public DestructorMethodVariant,
public BuiltinFunctionVariantBase {
593 COMMON_BUILTIN_VARIANT_FUNCTIONS
596 class BuiltinDestructorVariant :
public BuiltinDestructorVariantBase {
601 DLLLOCAL BuiltinDestructorVariant(
q_destructor_t n_destructor) : destructor(n_destructor) {
607 class BuiltinExternalDestructorVariant :
public BuiltinDestructorVariantBase {
613 DLLLOCAL BuiltinExternalDestructorVariant(
const void* ptr,
q_external_destructor_t destructor) : destructor(destructor), ptr(ptr) {
619 class BuiltinCopyVariantBase :
public CopyMethodVariant,
public BuiltinFunctionVariantBase {
622 DLLLOCAL BuiltinCopyVariantBase(
const QoreClass* c) : CopyMethodVariant(Public), BuiltinFunctionVariantBase(
QDOM_DEFAULT, c->getTypeInfo()) {
626 COMMON_BUILTIN_VARIANT_FUNCTIONS
632 class BuiltinCopyVariant :
public BuiltinCopyVariantBase {
637 DLLLOCAL BuiltinCopyVariant(
QoreClass* c,
q_copy_t m) : BuiltinCopyVariantBase(c), copy(m) {
640 copy(
self, old, private_data, xsink);
644 class BuiltinExternalCopyVariant :
public BuiltinCopyVariantBase {
650 DLLLOCAL BuiltinExternalCopyVariant(
const void* n_ptr,
QoreClass* c,
q_external_copy_t m) : BuiltinCopyVariantBase(c), copy(m), ptr(n_ptr) {
654 copy(thisclass, ptr,
self, old, private_data, xsink);
659 class NormalMethodFunction :
public MethodFunctionBase {
661 DLLLOCAL NormalMethodFunction(
const char* nme,
const QoreClass* n_qc) : MethodFunctionBase(nme, n_qc, false) {
664 DLLLOCAL NormalMethodFunction(
const NormalMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
667 DLLLOCAL
virtual ~NormalMethodFunction() {
678 const QoreValue n,
const QoreListNode* args,
const qore_class_private* cctx = runtime_get_class())
const;
681 #define NMETHF(f) (reinterpret_cast<NormalMethodFunction*>(f))
684 class StaticMethodFunction :
public MethodFunctionBase {
686 DLLLOCAL StaticMethodFunction(
const char* nme,
const QoreClass* n_qc) : MethodFunctionBase(nme, n_qc, true) {
688 DLLLOCAL StaticMethodFunction(
const StaticMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
690 DLLLOCAL
virtual ~StaticMethodFunction() {
694 DLLLOCAL
QoreValue evalMethod(
ExceptionSink* xsink,
const AbstractQoreFunctionVariant* variant,
const QoreListNode* args,
const qore_class_private* cctx =
nullptr)
const;
697 DLLLOCAL
QoreValue evalMethodTmpArgs(
ExceptionSink* xsink,
const AbstractQoreFunctionVariant* variant,
QoreListNode* args,
const qore_class_private* cctx =
nullptr)
const;
700 #define SMETHF(f) (reinterpret_cast<StaticMethodFunction*>(f))
703 class ConstructorMethodFunction :
public MethodFunctionBase {
705 DLLLOCAL ConstructorMethodFunction(
const QoreClass* n_qc) : MethodFunctionBase(
"constructor", n_qc, false) {
707 DLLLOCAL ConstructorMethodFunction(
const ConstructorMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
713 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
714 return new ConstructorMethodFunction(*
this, n_qc);
718 #define CONMF(f) (reinterpret_cast<ConstructorMethodFunction*>(f))
721 class DestructorMethodFunction :
public MethodFunctionBase {
723 DLLLOCAL DestructorMethodFunction(
const QoreClass* n_qc) : MethodFunctionBase(
"destructor", n_qc, false) {
725 DLLLOCAL DestructorMethodFunction(
const DestructorMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
729 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
730 return new DestructorMethodFunction(*
this, n_qc);
734 #define DESMF(f) (reinterpret_cast<DestructorMethodFunction*>(f))
737 class CopyMethodFunction :
public MethodFunctionBase {
739 DLLLOCAL CopyMethodFunction(
const QoreClass* n_qc) : MethodFunctionBase(
"copy", n_qc, false) {
741 DLLLOCAL CopyMethodFunction(
const CopyMethodFunction &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
745 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
746 return new CopyMethodFunction(*
this, n_qc);
750 #define COPYMF(f) (reinterpret_cast<CopyMethodFunction*>(f))
752 class BuiltinSystemConstructorBase :
public MethodFunctionBase {
754 DLLLOCAL BuiltinSystemConstructorBase(
const QoreClass* n_qc) : MethodFunctionBase(
"constructor", n_qc, false) {
756 DLLLOCAL BuiltinSystemConstructorBase(
const BuiltinSystemConstructorBase &old,
const QoreClass* n_qc) : MethodFunctionBase(old, n_qc) {
758 DLLLOCAL
virtual void eval(
const QoreClass &thisclass,
QoreObject*
self,
int code, va_list args)
const = 0;
760 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const = 0;
763 #define BSYSCONB(f) (reinterpret_cast<BuiltinSystemConstructorBase* >(f))
767 class BuiltinSystemConstructor :
public BuiltinSystemConstructorBase {
775 DLLLOCAL BuiltinSystemConstructor(
const BuiltinSystemConstructor &old,
const QoreClass* n_qc) : BuiltinSystemConstructorBase(old, n_qc), system_constructor(old.system_constructor) {
778 DLLLOCAL
virtual void eval(
const QoreClass &thisclass,
QoreObject*
self,
int code, va_list args)
const {
779 system_constructor(
self, code, args);
782 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
783 return new BuiltinSystemConstructor(*
this, n_qc);
787 class BuiltinNormalMethod :
public NormalMethodFunction {
789 DLLLOCAL BuiltinNormalMethod(
const QoreClass* n_qc,
const char* mname) : NormalMethodFunction(mname, n_qc) {
792 DLLLOCAL BuiltinNormalMethod(
const BuiltinNormalMethod &old,
const QoreClass* n_qc) : NormalMethodFunction(old, n_qc) {
795 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
796 return new BuiltinNormalMethod(*
this, n_qc);
800 class BuiltinStaticMethod :
public StaticMethodFunction {
802 DLLLOCAL BuiltinStaticMethod(
const QoreClass* n_qc,
const char* mname) : StaticMethodFunction(mname, n_qc) {
805 DLLLOCAL BuiltinStaticMethod(
const BuiltinStaticMethod &old,
const QoreClass* n_qc) : StaticMethodFunction(old, n_qc) {
808 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
809 return new BuiltinStaticMethod(*
this, n_qc);
813 class NormalUserMethod :
public NormalMethodFunction {
815 DLLLOCAL NormalUserMethod(
const QoreClass* n_qc,
const char* mname) : NormalMethodFunction(mname, n_qc) {
817 DLLLOCAL NormalUserMethod(
const NormalUserMethod &old,
const QoreClass* n_qc) : NormalMethodFunction(old, n_qc) {
819 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
820 return new NormalUserMethod(*
this, n_qc);
824 class StaticUserMethod :
public StaticMethodFunction {
826 DLLLOCAL StaticUserMethod(
const QoreClass* n_qc,
const char* mname) : StaticMethodFunction(mname, n_qc) {
828 DLLLOCAL StaticUserMethod(
const StaticUserMethod &old,
const QoreClass* n_qc) : StaticMethodFunction(old, n_qc) {
830 DLLLOCAL
virtual MethodFunctionBase* copy(
const QoreClass* n_qc)
const {
831 return new StaticUserMethod(*
this, n_qc);
835 class QoreMemberInfoBase {
837 const QoreTypeInfo* typeInfo;
839 DLLLOCAL QoreMemberInfoBase(
const QoreMemberInfoBase& old) : typeInfo(old.typeInfo), exp(old.exp.refSelf()),
840 loc(old.loc), parseTypeInfo(old.parseTypeInfo ? new QoreParseTypeInfo(*old.parseTypeInfo) : nullptr) {
848 const QoreProgramLocation* loc;
849 QoreParseTypeInfo* parseTypeInfo;
851 DLLLOCAL QoreMemberInfoBase(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeinfo =
nullptr,
853 : typeInfo(n_typeinfo), exp(e), loc(loc), parseTypeInfo(n_parseTypeInfo) {
856 DLLLOCAL ~QoreMemberInfoBase() {
860 DLLLOCAL
void del() {
863 delete parseTypeInfo;
864 parseTypeInfo =
nullptr;
868 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
872 DLLLOCAL
const QoreTypeInfo* parseGetTypeInfo()
const {
874 return QoreTypeInfo::isReference(typeInfo) ? anyTypeInfo : typeInfo;
878 DLLLOCAL
bool parseHasTypeInfo()
const {
879 return (typeInfo || parseTypeInfo);
883 class QoreMemberInfoBaseAccess :
public QoreMemberInfoBase {
887 DLLLOCAL QoreMemberInfoBaseAccess(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeinfo =
nullptr,
888 QoreParseTypeInfo* n_parseTypeInfo =
nullptr,
QoreValue e =
QoreValue(), ClassAccess n_access = Public) :
889 QoreMemberInfoBase(loc, n_typeinfo, n_parseTypeInfo, e), access(n_access) {
892 DLLLOCAL ClassAccess getAccess()
const {
897 DLLLOCAL QoreMemberInfoBaseAccess(
const QoreMemberInfoBaseAccess& old, ClassAccess n_access)
898 : QoreMemberInfoBase(old), access(old.access >= n_access ? old.access : n_access), init(old.init) {
905 typedef std::vector<const qore_class_private*> cls_vec_t;
908 typedef std::map<const qore_class_private*, const qore_class_private*> cls_context_map_t;
911 typedef std::deque<const QoreMemberInfo*> member_info_list_t;
916 class QoreMemberInfo :
public QoreMemberInfoBaseAccess {
917 friend class qore_class_private;
919 DLLLOCAL QoreMemberInfo(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeInfo =
nullptr,
920 QoreParseTypeInfo* n_parseTypeInfo =
nullptr,
QoreValue e =
QoreValue(), ClassAccess n_access = Public,
921 const qore_class_private* qc =
nullptr)
922 : QoreMemberInfoBaseAccess(loc, n_typeInfo, n_parseTypeInfo, e, n_access), is_local(true) {
924 cls_vec.push_back(qc);
929 DLLLOCAL QoreMemberInfo(
const QoreMemberInfo& old,
const qore_class_private* cls);
931 DLLLOCAL ~QoreMemberInfo() {
932 delete cls_context_map;
933 delete member_info_list;
936 DLLLOCAL
void setDeclaringClass(
const qore_class_private* qc) {
937 assert(cls_vec.empty());
938 cls_vec.push_back(qc);
943 DLLLOCAL
bool isLocalInternal()
const {
944 return is_local && access == Internal;
948 DLLLOCAL
bool local()
const {
953 DLLLOCAL
const qore_class_private* getClass()
const {
958 DLLLOCAL
const qore_class_private* getClassContext(
const qore_class_private* class_ctx)
const {
959 if (local() && class_ctx == getClass()) {
960 if (access == Internal) {
965 if (cls_context_map) {
966 cls_context_map_t::const_iterator i = cls_context_map->find(class_ctx);
967 if (i != cls_context_map->end()) {
975 DLLLOCAL
size_t getContextSize()
const {
976 return cls_context_map ? cls_context_map->size() : 0;
981 DLLLOCAL
void addContextAccess(
const QoreMemberInfo& mi);
985 DLLLOCAL
void addContextAccess(
const QoreMemberInfo& mi,
const qore_class_private* qc);
988 DLLLOCAL
size_t numParentMembers()
const {
989 return member_info_list ? member_info_list->size() : 0;
993 DLLLOCAL member_info_list_t::const_iterator initializationBegin()
const {
994 assert(member_info_list);
995 return member_info_list->begin();
999 DLLLOCAL member_info_list_t::const_iterator initializationEnd()
const {
1000 assert(member_info_list);
1001 return member_info_list->end();
1005 DLLLOCAL
int parseInit(
const char* name, LocalVar& selfid);
1008 DLLLOCAL
void setTransient() {
1009 assert(!is_transient);
1010 is_transient =
true;
1014 DLLLOCAL
bool getTransient()
const {
1015 return is_transient;
1022 cls_context_map_t* cls_context_map =
nullptr;
1024 member_info_list_t* member_info_list =
nullptr;
1029 is_transient =
false;
1041 DLLLOCAL QoreMemberInfo(
const QoreMemberInfo& old,
const qore_class_private* cls, ClassAccess cls_access);
1044 class QoreVarInfo :
public QoreMemberInfoBaseAccess {
1046 mutable QoreVarRWLock rwl;
1047 QoreLValueGeneric val;
1050 bool eval_init =
false;
1052 DLLLOCAL QoreVarInfo(
const QoreProgramLocation* loc,
const QoreTypeInfo* n_typeinfo =
nullptr,
1053 QoreParseTypeInfo* n_parseTypeInfo =
nullptr,
QoreValue e =
QoreValue(), ClassAccess n_access = Public) :
1054 QoreMemberInfoBaseAccess(loc, n_typeinfo, n_parseTypeInfo, e, n_access), finalized(false) {
1057 DLLLOCAL QoreVarInfo(
const QoreVarInfo& old, ClassAccess n_access = Public)
1058 : QoreMemberInfoBaseAccess(old, n_access), val(old.val), finalized(old.finalized), eval_init(old.eval_init) {
1061 DLLLOCAL ~QoreVarInfo() {
1062 assert(!val.hasValue());
1065 DLLLOCAL
int evalInit(
const char* name,
ExceptionSink* xsink);
1068 DLLLOCAL
void del() {
1069 assert(!val.hasValue());
1070 QoreMemberInfoBaseAccess::del();
1076 QoreAutoVarRWWriteLocker al(rwl);
1079 tmp = val.removeValue(
true);
1084 QoreMemberInfoBaseAccess::del();
1088 val.removeValue(
true).discard(xsink);
1093 val.set(getTypeInfo());
1094 return val.assignInitial(v);
1097 DLLLOCAL
void getLValue(LValueHelper& lvh) {
1098 lvh.setAndLock(rwl);
1099 if (checkFinalized(lvh.vl.xsink))
1101 lvh.setValue(val, getTypeInfo());
1104 DLLLOCAL
void init() {
1105 val.set(getTypeInfo());
1108 discard(val.assignInitial(QoreTypeInfo::getDefaultQoreValue(typeInfo)),
nullptr);
1114 if (!eval_init && evalInit(name, xsink)) {
1117 return getRuntimeReferencedValue();
1120 DLLLOCAL
QoreValue getRuntimeReferencedValue()
const {
1121 QoreAutoVarRWReadLocker al(rwl);
1122 return val.getReferencedValue();
1125 DLLLOCAL
int64 getAsBigInt()
const {
1126 QoreAutoVarRWReadLocker al(rwl);
1127 return val.getAsBigInt();
1130 DLLLOCAL
double getAsFloat()
const {
1131 QoreAutoVarRWReadLocker al(rwl);
1132 return val.getAsFloat();
1135 DLLLOCAL
bool getAsBool()
const {
1136 QoreAutoVarRWReadLocker al(rwl);
1137 return val.getAsBool();
1140 DLLLOCAL
int parseInit(
const char* name);
1145 xsink->
raiseException(
"DESTRUCTOR-ERROR",
"illegal class static variable assignment after second phase "
1146 "of variable destruction");
1153 template <
typename T>
1154 class QoreMemberMapBase {
1156 typedef std::pair<char*, std::unique_ptr<T>> member_list_element_t;
1157 typedef std::deque<member_list_element_t> member_list_t;
1158 typedef typename member_list_t::iterator iterator;
1159 typedef typename member_list_t::const_iterator const_iterator;
1160 member_list_t member_list;
1162 DLLLOCAL ~QoreMemberMapBase() {
1163 for (
auto& i : member_list) {
1168 member_list.clear();
1171 DLLLOCAL
bool inList(
const char* name)
const {
1172 return (
bool)find(name);
1175 DLLLOCAL T* find(
const char* name)
const {
1176 typename member_list_t::const_iterator i =
1177 std::find_if(member_list.begin(), member_list.end(), [name](
const member_list_element_t& e)
1178 ->
bool {return !strcmp(e.first, name); });
1179 return i == member_list.end() ? nullptr : i->second.get();
1182 DLLLOCAL T* replace(
const char* name, T* info) {
1183 typename member_list_t::iterator i =
1184 std::find_if(member_list.begin(), member_list.end(), [name](
const member_list_element_t& e)
1185 ->
bool {return !strcmp(e.first, name); });
1186 assert(i != member_list.end());
1187 T* rv = i->second.release();
1188 i->second = std::unique_ptr<T>(info);
1192 DLLLOCAL
bool empty()
const {
1193 return member_list.empty();
1196 DLLLOCAL
void addNoCheck(
char* name, T* info) {
1199 assert(!inList(name));
1200 member_list.push_back(std::make_pair(name, std::unique_ptr<T>(info)));
1203 DLLLOCAL
void addNoCheck(std::pair<char*, T*> pair) {
1204 addNoCheck(pair.first, pair.second);
1207 DLLLOCAL
void moveAllTo(QoreMemberMapBase<T>& dest) {
1208 dest.member_list.insert(dest.member_list.end(), member_list.begin(), member_list.end());
1209 member_list.clear();
1212 DLLLOCAL
size_t size()
const {
1213 return member_list.size();
1217 class QoreMemberMap :
public QoreMemberMapBase<QoreMemberInfo> {
1219 using QoreMemberMapBase<QoreMemberInfo>::moveAllTo;
1220 DLLLOCAL
void moveAllTo(
QoreClass* qc, ClassAccess access);
1222 using QoreMemberMapBase<QoreMemberInfo>::addNoCheck;
1223 DLLLOCAL
void addNoCheck(
char* name, QoreMemberInfo* info) {
1224 assert(info->getClass());
1225 QoreMemberMapBase<QoreMemberInfo>::addNoCheck(name, info);
1228 DLLLOCAL
void addInheritedNoCheck(
char* name, QoreMemberInfo* info) {
1231 assert(!inList(name));
1232 member_list.insert(member_list.begin(), std::make_pair(name, std::unique_ptr<QoreMemberInfo>(info)));
1235 DLLLOCAL
int parseInit(LocalVar& selfid);
1241 class QoreVarMap :
public QoreMemberMapBase<QoreVarInfo> {
1244 for (member_list_t::reverse_iterator i = member_list.rbegin(), e = member_list.rend(); i != e; ++i) {
1245 i->second->clear(xsink);
1250 for (member_list_t::reverse_iterator i = member_list.rbegin(), e = member_list.rend(); i != e; ++i) {
1251 i->second->delVar(xsink);
1255 member_list.clear();
1258 DLLLOCAL
void del() {
1259 for (member_list_t::reverse_iterator i = member_list.rbegin(), e = member_list.rend(); i != e; ++i) {
1260 assert(!i->second->val.hasValue());
1268 member_list.clear();
1271 DLLLOCAL
void clearNoFree() {
1272 member_list.clear();
1275 DLLLOCAL
void moveAllTo(
QoreClass* qc, ClassAccess access);
1287 class BCANode :
public FunctionCallBase {
1290 const QoreProgramLocation* loc;
1297 DLLLOCAL BCANode(NamedScope* n, QoreParseListNode* n_args,
const QoreProgramLocation* loc)
1298 : FunctionCallBase(n_args), loc(loc), ns(n), name(nullptr) {
1299 assert(loc->start_line > 0);
1303 DLLLOCAL BCANode(
char* n, QoreParseListNode* n_args,
const QoreProgramLocation* loc)
1304 : FunctionCallBase(n_args), loc(loc), ns(nullptr), name(n) {
1305 assert(loc->start_line > 0);
1308 DLLLOCAL ~BCANode() {
1315 DLLLOCAL
int parseInit(BCList* bcl,
const char* classname);
1318 typedef std::vector<BCANode*> bcalist_t;
1324 class BCAList :
public bcalist_t {
1326 DLLLOCAL BCAList(BCANode* n) {
1330 DLLLOCAL ~BCAList() {
1331 for (bcalist_t::iterator i = begin(), e = end(); i != e; ++i)
1336 DLLLOCAL
int execBaseClassConstructorArgs(BCEAList* bceal,
ExceptionSink* xsink)
const;
1339 typedef std::pair<QoreClass*, bool> class_virt_pair_t;
1341 typedef std::vector<class_virt_pair_t> class_list_t;
1344 hashdecl member_init_entry_t {
1346 const QoreMemberInfo* info;
1347 const qore_class_private* member_class_ctx;
1349 DLLLOCAL member_init_entry_t(
const char* name,
const QoreMemberInfo* info,
const qore_class_private* member_class_ctx) :
1350 name(name), info(info), member_class_ctx(member_class_ctx) {
1355 typedef std::vector<member_init_entry_t> member_init_list_t;
1360 class BCSMList :
public class_list_t {
1362 DLLLOCAL BCSMList() {
1365 DLLLOCAL BCSMList(
const BCSMList &old);
1367 DLLLOCAL ~BCSMList();
1369 DLLLOCAL
void processMemberInitializationList(
const QoreMemberMap& members, member_init_list_t& member_init_list);
1372 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* thisclass,
QoreClass* sc,
bool is_virtual);
1374 DLLLOCAL
void alignBaseClassesInSubclass(
QoreClass* thisclass,
QoreClass* child,
bool is_virtual);
1386 DLLLOCAL
void resolveCopy();
1390 typedef vector_set_t<qore_class_private*> qcp_set_t;
1398 const QoreProgramLocation* loc;
1399 NamedScope* cname =
nullptr;
1400 char* cstr =
nullptr;
1403 bool is_virtual : 1;
1405 DLLLOCAL BCNode(
const QoreProgramLocation* loc, NamedScope* c, ClassAccess a) : loc(loc), cname(c), access(a),
1410 DLLLOCAL BCNode(
const QoreProgramLocation* loc,
char* str, ClassAccess a) : loc(loc), cstr(str), access(a),
1415 DLLLOCAL BCNode(
const QoreProgramLocation* loc,
QoreClass* qc,
bool n_virtual =
false) : loc(loc), sclass(qc),
1416 access(Public), is_virtual(n_virtual) {
1420 DLLLOCAL BCNode(
const BCNode &old) : loc(old.loc), sclass(old.sclass), access(old.access),
1421 is_virtual(old.is_virtual) {
1427 DLLLOCAL ~BCNode() {
1433 DLLLOCAL
int tryResolveClass(
QoreClass* cls,
bool raise_error);
1435 DLLLOCAL ClassAccess getAccess()
const {
return access; }
1438 DLLLOCAL
int initializeHierarchy(
QoreClass* cls, qcp_set_t& qcp_set);
1440 DLLLOCAL
int initializeMembers(
QoreClass* cls);
1443 DLLLOCAL
int initialize(
QoreClass* cls);
1445 DLLLOCAL
bool isBaseClass(
QoreClass* qc,
bool toplevel)
const;
1447 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethod(
const char* name, ClassAccess& n_access,
1448 const qore_class_private* class_ctx,
bool allow_internal)
const;
1449 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethod(
const char* name, ClassAccess& n_access,
1450 const qore_class_private* class_ctx,
bool allow_internal)
const;
1452 DLLLOCAL
bool runtimeIsPrivateMember(
const char* str,
bool toplevel)
const;
1456 DLLLOCAL
const QoreMemberInfo* parseFindMember(
const char* mem,
const qore_class_private*& qc,
1457 ClassAccess& n_access,
bool toplevel)
const;
1458 DLLLOCAL
const QoreVarInfo* parseFindVar(
const char* name,
const qore_class_private*& qc, ClassAccess& n_access,
1459 bool toplevel)
const;
1461 DLLLOCAL
const QoreClass* findInHierarchy(
const qore_class_private& qc);
1464 DLLLOCAL
const QoreClass* getClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1465 DLLLOCAL
const QoreClass* parseGetClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1466 DLLLOCAL
bool inHierarchy(
const qore_class_private& qc, ClassAccess& n_access)
const;
1467 DLLLOCAL
bool inHierarchyStrict(
const qore_class_private& qc, ClassAccess& n_access)
const;
1470 DLLLOCAL
const QoreMethod* parseFindNormalMethod(
const char* name,
const qore_class_private* class_ctx,
1471 bool allow_internal)
const;
1474 DLLLOCAL
const QoreMethod* parseFindStaticMethod(
const char* name,
const qore_class_private* class_ctx,
1475 bool allow_internal)
const;
1478 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc,
const char* name,
1479 const qore_class_private* class_ctx,
bool allow_internal)
const;
1481 DLLLOCAL
bool parseCheckHierarchy(
const QoreClass* cls, ClassAccess& n_access,
bool toplevel)
const;
1483 DLLLOCAL QoreVarInfo* parseFindStaticVar(
const char* vname,
const QoreClass*& qc, ClassAccess& n_access,
1484 bool check,
bool toplevel)
const;
1486 DLLLOCAL
QoreValue parseFindConstantValue(
const char* cname,
const QoreTypeInfo*& typeInfo,
bool &found,
1487 const qore_class_private* class_ctx,
bool allow_internal)
const;
1489 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* child,
bool is_virtual);
1491 DLLLOCAL
void initializeBuiltin();
1494 typedef std::vector<BCNode*> bclist_t;
1502 class BCList :
public bclist_t {
1508 bool rescanned =
false;
1510 DLLLOCAL BCList(BCNode* n) {
1517 DLLLOCAL BCList(
const BCList& old) : sml(old.sml) {
1519 reserve(old.size());
1520 for (bclist_t::const_iterator i = old.begin(), e = old.end(); i != e; ++i)
1521 push_back(
new BCNode(*(*i)));
1524 DLLLOCAL ~BCList() {
1525 for (bclist_t::iterator i = begin(), e = end(); i != e; ++i)
1529 DLLLOCAL
int initializeHierarchy(
QoreClass* thisclass, qcp_set_t& qcp_set);
1531 DLLLOCAL
int initializeMembers(
QoreClass* thisclass);
1533 DLLLOCAL
int initialize(
QoreClass* thisclass);
1536 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc,
const char* name,
1537 const qore_class_private* class_ctx,
bool allow_internal);
1540 DLLLOCAL
const QoreMethod* parseFindNormalMethod(
const char* name,
const qore_class_private* class_ctx,
1541 bool allow_internal);
1543 DLLLOCAL
const QoreMethod* parseFindStaticMethod(
const char* name,
const qore_class_private* class_ctx,
1544 bool allow_internal);
1546 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethod(
const char* name, ClassAccess& access,
1547 const qore_class_private* class_ctx,
bool allow_internal)
const;
1548 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethod(
const char* name, ClassAccess& access,
1549 const qore_class_private* class_ctx,
bool allow_internal)
const;
1551 DLLLOCAL
bool match(
const QoreClass* cls);
1554 DLLLOCAL
bool runtimeIsPrivateMember(
const char* str,
bool toplevel)
const;
1556 DLLLOCAL
bool parseCheckHierarchy(
const QoreClass* cls, ClassAccess& access,
bool toplevel)
const;
1558 DLLLOCAL
const QoreMemberInfo* parseFindMember(
const char* mem,
const qore_class_private*& qc,
1559 ClassAccess& n_access,
bool toplevel)
const;
1561 DLLLOCAL
const QoreVarInfo* parseFindVar(
const char* vname,
const qore_class_private*& qc, ClassAccess& access,
1562 bool toplevel)
const;
1564 DLLLOCAL
bool parseHasPublicMembersInHierarchy()
const;
1566 DLLLOCAL
const QoreClass* findInHierarchy(
const qore_class_private& qc);
1569 DLLLOCAL
const QoreClass* getClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1571 DLLLOCAL
const QoreClass* parseGetClass(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const;
1572 DLLLOCAL
bool inHierarchy(
const qore_class_private& qc, ClassAccess& n_access)
const;
1573 DLLLOCAL
bool inHierarchyStrict(
const qore_class_private& qc, ClassAccess& n_access)
const;
1575 DLLLOCAL
void addNewAncestors(
QoreMethod* m);
1577 DLLLOCAL
void addNewStaticAncestors(
QoreMethod* m);
1578 DLLLOCAL
void addStaticAncestors(
QoreMethod* m);
1579 DLLLOCAL
void parseAddAncestors(
QoreMethod* m);
1580 DLLLOCAL
void parseAddStaticAncestors(
QoreMethod* m);
1582 DLLLOCAL
void parseResolveAbstract();
1584 DLLLOCAL
QoreValue parseFindConstantValue(
const char* cname,
const QoreTypeInfo*& typeInfo,
bool& found,
1585 const qore_class_private* class_ctx,
bool allow_internal)
const;
1587 DLLLOCAL QoreVarInfo* parseFindStaticVar(
const char* vname,
const QoreClass*& qc, ClassAccess& access,
bool check,
1588 bool toplevel)
const;
1590 DLLLOCAL
void resolveCopy();
1592 DLLLOCAL MethodVariantBase* matchNonAbstractVariant(
const std::string& name, MethodVariantBase* v)
const;
1594 DLLLOCAL
bool isBaseClass(
QoreClass* qc,
bool toplevel)
const;
1596 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* thisparent,
QoreClass* child,
bool is_virtual) {
1597 for (
auto& i : *
this) {
1598 if ((*i).addBaseClassesToSubclass(child, is_virtual))
1601 return sml.addBaseClassesToSubclass(thisparent, child, is_virtual);
1604 DLLLOCAL
void rescanParents(
QoreClass* cls);
1606 DLLLOCAL
void initializeBuiltin() {
1607 for (
auto& i : *
this) {
1608 (*i).initializeBuiltin();
1617 const QoreProgramLocation* loc;
1619 const AbstractQoreFunctionVariant* variant =
nullptr;
1620 bool execed =
false;
1621 bool member_init_done =
false;
1623 DLLLOCAL BCEANode(
const QoreProgramLocation* loc,
QoreListNode* args,
const AbstractQoreFunctionVariant* variant) : loc(loc), args(args), variant(reinterpret_cast<const MethodVariant*>(variant)) {
1626 DLLLOCAL BCEANode(
bool n_execed =
true,
bool mid =
true) : execed(n_execed), member_init_done(mid) {
1639 typedef vector_map_t<qore_classid_t, BCEANode*> bceamap_t;
1645 class BCEAList :
public bceamap_t {
1647 DLLLOCAL ~BCEAList() {
1655 DLLLOCAL
QoreListNode* findArgs(
qore_classid_t classid,
bool* aexeced,
const AbstractQoreFunctionVariant*& variant,
const QoreProgramLocation*& loc);
1672 hashdecl SelfInstantiatorHelper {
1674 DLLLOCAL SelfInstantiatorHelper(LocalVar* n_selfid,
QoreObject*
self) : selfid(n_selfid) {
1675 selfid->instantiateSelf(
self);
1677 DLLLOCAL ~SelfInstantiatorHelper() {
1678 selfid->uninstantiateSelf();
1686 class SignatureHash {
1688 unsigned char buf[SH_SIZE];
1693 DLLLOCAL
void clearHash() {
1694 memset(buf, 0, SH_SIZE);
1697 DLLLOCAL
void copyHash(
const SignatureHash& other) {
1698 memcpy(buf, other.buf, SH_SIZE);
1702 DLLLOCAL SignatureHash() : is_set(false) {
1706 DLLLOCAL SignatureHash(
const SignatureHash& old) : is_set(old.is_set) {
1713 DLLLOCAL
void updateEmpty() {
1719 DLLLOCAL
bool operator==(
const SignatureHash& other)
const {
1721 if (!is_set || !other.is_set)
1723 return !memcmp(buf, other.buf, SH_SIZE);
1726 DLLLOCAL SignatureHash& operator=(
const SignatureHash& other) {
1727 if (!other.is_set) {
1738 DLLLOCAL
operator bool()
const {
1743 DLLLOCAL
void toString(
QoreString& str)
const {
1744 for (
unsigned i = 0; i < SH_SIZE; ++i) {
1751 DLLLOCAL
const char* debugToString()
const {
1754 for (
unsigned i = 0; i < SH_SIZE; ++i) {
1761 DLLLOCAL
char* getHash()
const {
1766 DLLLOCAL
void clear() {
1774 #define QCCM_NORMAL (1 << 0)
1775 #define QCCM_STATIC (1 << 1)
1778 typedef vector_set_t<QoreClass*> qc_set_t;
1783 class qore_class_private {
1785 const QoreProgramLocation* loc;
1789 qore_ns_private* ns =
nullptr;
1790 BCList* scl =
nullptr;
1793 mutable VRMutex gate;
1798 AbstractMethodMap ahm;
1800 ConstantList constlist;
1803 QoreMemberMap members;
1805 member_init_list_t member_init_list;
1810 const QoreMethod* system_constructor =
nullptr,
1811 * constructor =
nullptr,
1812 * destructor =
nullptr,
1813 * copyMethod =
nullptr,
1814 * methodGate =
nullptr,
1815 * memberGate =
nullptr,
1816 * memberNotification =
nullptr;
1828 parse_init_called : 1,
1829 parse_init_partial_called : 1,
1830 has_public_memdecl : 1,
1831 pending_has_public_memdecl : 1,
1833 resolve_copy_done : 1,
1834 has_new_user_changes : 1,
1835 has_sig_changes : 1,
1836 owns_ornothingtypeinfo : 1,
1842 parse_resolve_hierarchy : 1,
1843 parse_resolve_class_members : 1,
1844 parse_resolve_abstract : 1,
1845 has_transient_member : 1
1853 unsigned num_methods, num_user_methods, num_static_methods, num_static_user_methods;
1857 QoreClassTypeInfo* typeInfo =
nullptr;
1858 QoreClassOrNothingTypeInfo* orNothingTypeInfo =
nullptr;
1860 const qore_class_private* injectedClass =
nullptr;
1863 mutable LocalVar selfid;
1869 const void* ptr =
nullptr;
1881 bool deref_source_program =
true;
1884 std::string from_module;
1887 std::string lang =
"Qore";
1890 typedef std::map<std::string, QoreValue> kvmap_t;
1894 QoreClassTypeInfo* n_typeinfo =
nullptr);
1898 DLLLOCAL qore_class_private(
const qore_class_private& old, qore_ns_private* ns,
QoreProgram* spgm,
1899 const char* nme,
bool inject,
const qore_class_private* injectedClass, q_setpub_t set_pub);
1933 DLLLOCAL
bool setKeyValueIfNotSet(
const std::string& key,
const char* str);
1942 DLLLOCAL
QoreValue getReferencedKeyValue(
const std::string& key)
const;
1951 DLLLOCAL
QoreValue getReferencedKeyValue(
const char* key)
const;
1954 DLLLOCAL
void addBaseClass(
QoreClass* qc,
bool virt);
1959 DLLLOCAL
const char* getModuleName()
const {
1960 return from_module.empty() ? nullptr : from_module.c_str();
1964 DLLLOCAL BCSMList* getBCSMList()
const {
1965 return scl ? &scl->sml :
nullptr;
1968 DLLLOCAL
void pgmRef()
const {
1974 DLLLOCAL
void ref()
const {
1978 DLLLOCAL
bool deref(
bool ns_const,
bool ns_vars,
bool in_del =
false) {
1981 if (!constlist.empty()) {
1982 constlist.deleteAll(
nullptr);
1987 if (!vars.empty()) {
1994 cls->priv =
nullptr;
2000 for (
auto& i : qcset) {
2011 DLLLOCAL
bool hasAbstract()
const {
2012 return !ahm.empty();
2015 DLLLOCAL
void parseSetEmptyPublicMemberDeclaration() {
2016 pending_has_public_memdecl =
true;
2017 if (!has_new_user_changes) {
2018 has_new_user_changes =
true;
2022 DLLLOCAL
int runtimeCheckInstantiateClass(
ExceptionSink* xsink)
const {
2023 return ahm.runtimeCheckInstantiateClass(name.c_str(), xsink);
2026 DLLLOCAL
void parseCheckAbstractNew(
const QoreProgramLocation* loc)
const;
2028 DLLLOCAL
void parseDoCheckAbstractNew(
const QoreProgramLocation* loc)
const;
2030 DLLLOCAL
void setNamespace(qore_ns_private* n) {
2036 DLLLOCAL
bool setNamespaceConditional(qore_ns_private* n) {
2046 DLLLOCAL
void updateNamespace(qore_ns_private* n) {
2052 DLLLOCAL
void resolveCopy();
2054 DLLLOCAL
void setUserData(
const void* n_ptr) {
2059 DLLLOCAL
const void* getUserData()
const {
2072 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
2076 DLLLOCAL
const QoreTypeInfo* getOrNothingTypeInfo()
const {
2077 return orNothingTypeInfo;
2080 DLLLOCAL
bool runtimeIsPrivateMemberIntern(
const char* str,
bool toplevel)
const;
2082 DLLLOCAL
void parseImportMembers(qore_class_private& qc, ClassAccess access);
2084 DLLLOCAL
bool parseHasMemberGate()
const {
2085 return memberGate || hm.find(
"memberGate") != hm.end();
2088 DLLLOCAL
bool parseHasMethodGate()
const {
2089 return methodGate || hm.find(
"methodGate") != hm.end();
2093 DLLLOCAL
bool checkAssignSpecialIntern(
const QoreMethod* m) {
2095 if (!methodGate && !strcmp(m->
getName(),
"methodGate")) {
2100 if (!memberGate && !strcmp(m->
getName(),
"memberGate")) {
2106 if (!memberNotification && !strcmp(m->
getName(),
"memberNotification")) {
2107 memberNotification = m;
2115 DLLLOCAL
bool checkSpecialStaticIntern(
const char* mname) {
2117 if ((!methodGate && !strcmp(mname,
"methodGate"))
2118 || (!memberGate && !strcmp(mname,
"memberGate"))
2119 || (!memberNotification && !strcmp(mname,
"memberNotification")))
2125 DLLLOCAL
bool checkSpecial(
const char* mname) {
2127 if ((!methodGate && !strcmp(mname,
"methodGate"))
2128 || (!memberGate && !strcmp(mname,
"memberGate"))
2129 || (!memberNotification && !strcmp(mname,
"memberNotification"))
2130 || (!constructor && !strcmp(mname,
"constructor"))
2131 || (!destructor && !strcmp(mname,
"destructor"))
2132 || (!copyMethod && !strcmp(mname,
"copy")))
2138 DLLLOCAL
bool checkAssignSpecial(
const QoreMethod* m) {
2140 if (!constructor && !strcmp(m->
getName(),
"constructor")) {
2145 if (!destructor && !strcmp(m->
getName(),
"destructor")) {
2150 if (!copyMethod && !strcmp(m->
getName(),
"copy")) {
2155 return checkAssignSpecialIntern(m);
2159 DLLLOCAL
void mergeAbstract();
2162 DLLLOCAL
int initializeIntern();
2163 DLLLOCAL
int initializeHierarchy(qcp_set_t& qcp_set);
2164 DLLLOCAL
int initializeMembers();
2165 DLLLOCAL
int initialize();
2167 DLLLOCAL
int parseInitPartial();
2168 DLLLOCAL
int parseInitPartialIntern();
2170 DLLLOCAL
int parseCheckMemberAccess(
const QoreProgramLocation* loc,
const char* mem,
2171 const QoreTypeInfo*& memberTypeInfo,
int pflag)
const {
2172 const_cast<qore_class_private*
>(
this)->parseInitPartial();
2174 const qore_class_private* qc =
nullptr;
2176 const QoreMemberInfo* omi = parseFindMember(mem, qc, access);
2180 if (!parseHasMemberGate() || (pflag & PF_FOR_ASSIGNMENT)) {
2182 parse_error(*loc,
"member '%s' of class '%s' referenced has no type information because it was " \
2183 "not declared in a public or private member list, but parse options require type " \
2184 "information for all declarations",
2188 if (parseHasPublicMembersInHierarchy()) {
2191 parse_error(*loc,
"illegal access to unknown member '%s' in class '%s' which has a public " \
2192 "member list (or inherited public member list)", mem, name.c_str());
2199 memberTypeInfo = omi->getTypeInfo();
2202 if ((access > Public) && !parseHasMemberGate() && !parseCheckPrivateClassAccess()) {
2204 parse_error(*loc,
"illegal access to private member '%s' of class '%s'", mem, name.c_str());
2210 DLLLOCAL
int parseResolveInternalMemberAccess(
const char* mem,
const QoreTypeInfo*& memberTypeInfo)
const {
2211 const_cast<qore_class_private*
>(
this)->parseInitPartial();
2213 const qore_class_private* qc =
nullptr;
2215 const QoreMemberInfo* omi = parseFindMember(mem, qc, access);
2217 memberTypeInfo = omi->getTypeInfo();
2220 return omi ? 0 : -1;
2223 DLLLOCAL
int parseCheckInternalMemberAccess(
const char* mem,
const QoreTypeInfo*& memberTypeInfo,
2224 const QoreProgramLocation* loc)
const {
2225 const_cast<qore_class_private*
>(
this)->parseInitPartial();
2228 const qore_class_private* qc =
nullptr;
2230 const QoreMemberInfo* omi = parseFindMember(mem, qc, access);
2236 rc =
const_cast<QoreMemberInfo*
>(omi)->parseInit(mem, selfid);
2237 memberTypeInfo = omi->parseGetTypeInfo();
2242 parse_error(*loc,
"member '%s' of class '%s' referenced has no type information because it was not " \
2243 "declared in a public or private member list, but parse options require type information for " \
2244 "all declarations", mem, name.c_str());
2249 if (parseHasPublicMembersInHierarchy()) {
2250 parse_error(*loc,
"illegal access to unknown member '%s' in class '%s' which has a public member " \
2251 "list (or inherited public member list)", mem, name.c_str());
2260 DLLLOCAL
bool parseHasPublicMembersInHierarchy()
const {
2261 if (has_public_memdecl || pending_has_public_memdecl)
2264 return scl ? scl->parseHasPublicMembersInHierarchy() :
false;
2274 DLLLOCAL
const qore_class_private* runtimeGetMemberContext(
const char* mem,
const qore_class_private* class_ctx)
const {
2275 const QoreMemberInfo* info = runtimeGetMemberInfo(mem, class_ctx);
2277 return info ? info->getClassContext(class_ctx) :
nullptr;
2280 DLLLOCAL
bool runtimeIsMemberInternal(
const char* mem)
const {
2281 QoreMemberInfo* info = members.find(mem);
2282 return info && info->isLocalInternal() ? true :
false;
2294 DLLLOCAL
const QoreMemberInfo* runtimeGetMemberInfo(
const char* mem,
const qore_class_private* class_ctx)
const {
2295 QoreMemberInfo* info;
2297 info = class_ctx->members.find(mem);
2298 if (info && info->isLocalInternal()) {
2305 if (class_ctx !=
this) {
2306 info = members.find(mem);
2309 if (info && info->access == Inaccessible && !info->getClassContext(class_ctx)) {
2316 DLLLOCAL
const QoreMemberInfo* parseFindMember(
const char* mem,
const qore_class_private*& qc, ClassAccess& access)
const {
2318 const_cast<qore_class_private*
>(
this)->initialize();
2319 return parseFindMemberNoInit(mem, qc, access,
true);
2325 DLLLOCAL
const QoreMemberInfo* parseFindMemberNoInit(
const char* mem,
const qore_class_private*& qc, ClassAccess& access,
bool toplevel)
const {
2326 const QoreMemberInfo* mi = members.find(mem);
2328 ClassAccess ma = mi->getAccess();
2329 if (toplevel || ma < Internal) {
2333 qc = mi->getClass();
2338 return scl ? scl->parseFindMember(mem, qc, access,
true) : 0;
2341 DLLLOCAL
const QoreVarInfo* parseFindVar(
const char* vname,
const qore_class_private*& qc, ClassAccess& access,
bool toplevel)
const {
2344 QoreVarInfo* vi = vars.find(
const_cast<char*
>(vname));
2348 access = vi->getAccess();
2352 return scl ? scl->parseFindVar(vname, qc, access, toplevel) :
nullptr;
2355 DLLLOCAL
int parseCheckClassHierarchyMembers(
const char* mname,
const QoreMemberInfo& l_mi,
const QoreMemberInfo& b_mi)
const;
2357 DLLLOCAL
int checkExistingVarMember(
const char* dname,
const QoreMemberInfoBaseAccess* mi,
const QoreMemberInfoBaseAccess* omi,
const qore_class_private* qc, ClassAccess oaccess,
bool var =
false)
const;
2359 DLLLOCAL
int parseCheckVar(
const char* dname,
const QoreVarInfo* vi)
const {
2360 const qore_class_private* qc = 0;
2362 const QoreVarInfo* ovi = parseFindVar(dname, qc, access,
true);
2365 if (parseHasConstant(dname)) {
2366 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());
2372 return checkExistingVarMember(dname, vi, ovi, qc, access,
true);
2375 DLLLOCAL
int parseCheckMember(
const char* mem,
const QoreMemberInfo* mi)
const {
2376 const qore_class_private* qc =
nullptr;
2377 ClassAccess access = Public;
2378 const QoreMemberInfo* omi = parseFindMemberNoInit(mem, qc, access,
true);
2383 return checkExistingVarMember(mem, mi, omi, qc, omi->access);
2386 DLLLOCAL
int parseCheckMemberInBaseClasses(
const char* mem,
const QoreMemberInfo* mi)
const {
2387 const qore_class_private* qc =
nullptr;
2388 ClassAccess access = Public;
2391 const QoreMemberInfo* omi = scl ? scl->parseFindMember(mem, qc, access,
false) :
nullptr;
2392 if (!omi || (omi->getClass() == mi->getClass())) {
2396 return checkExistingVarMember(mem, mi, omi, qc, omi->access);
2399 DLLLOCAL
int parseCheckSystemCommitted(
const QoreProgramLocation* loc) {
2401 parse_error(*loc,
"cannot modify system class '%s'", name.c_str());
2405 parse_error(*loc,
"cannot modify user class '%s' once it's been committed", name.c_str());
2411 DLLLOCAL
void parseAddMember(
char* mem, ClassAccess access, QoreMemberInfo* memberInfo) {
2412 memberInfo->access = access;
2413 if (!parseCheckSystemCommitted(memberInfo->loc) && !parseCheckMember(mem, memberInfo)) {
2414 if (!has_new_user_changes) {
2415 has_new_user_changes =
true;
2417 if (!has_sig_changes) {
2418 has_sig_changes =
true;
2420 memberInfo->setDeclaringClass(
this);
2421 if (!has_transient_member && memberInfo->getTransient()) {
2422 has_transient_member =
true;
2425 members.addNoCheck(mem, memberInfo);
2433 DLLLOCAL
void parseAddStaticVar(
char* dname, ClassAccess access, QoreVarInfo* VarInfo) {
2434 VarInfo->access = access;
2435 if (!parseCheckSystemCommitted(VarInfo->loc) && !parseCheckVar(dname, VarInfo)) {
2436 if (!has_new_user_changes) {
2437 has_new_user_changes =
true;
2439 if (!has_sig_changes) {
2440 has_sig_changes =
true;
2444 vars.addNoCheck(dname, VarInfo);
2452 DLLLOCAL
void addBuiltinConstant(
const char* cname,
QoreValue value, ClassAccess access = Public,
const QoreTypeInfo* cTypeInfo =
nullptr) {
2453 assert(!constlist.inList(cname));
2455 sys = committed =
true;
2457 constlist.add(cname, value, cTypeInfo, access);
2460 DLLLOCAL
void addBuiltinStaticVar(
const char* vname,
QoreValue value, ClassAccess access = Public,
const QoreTypeInfo* vTypeInfo =
nullptr);
2462 DLLLOCAL
void parseAssimilateConstants(ConstantList &cmap, ClassAccess access) {
2463 assert(!sys && !committed);
2464 if (!has_new_user_changes)
2465 has_new_user_changes =
true;
2466 if (!has_sig_changes)
2467 has_sig_changes =
true;
2470 cmap.setAccess(access);
2471 constlist.assimilate(cmap,
"class", name.c_str());
2474 DLLLOCAL
void parseAddConstant(
const QoreProgramLocation* loc,
const std::string &cname,
QoreValue val, ClassAccess access) {
2476 if (parseCheckSystemCommitted(loc)) {
2479 if (parseHasVar(cname.c_str())) {
2480 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());
2483 if (!has_new_user_changes)
2484 has_new_user_changes =
true;
2485 if (!has_sig_changes)
2486 has_sig_changes =
true;
2490 constlist.parseAdd(loc, cname, val_holder.release(), access, name.c_str());
2493 DLLLOCAL
bool parseHasVar(
const char* vn) {
2494 return vars.inList(vn);
2497 DLLLOCAL
bool parseHasConstant(
const std::string &cname)
const {
2498 return constlist.inList(cname);
2501 DLLLOCAL
QoreValue parseFindLocalConstantValue(
const char* cname,
const QoreTypeInfo*& cTypeInfo,
bool& found) {
2505 ClassAccess access = Public;
2506 QoreValue rv = constlist.find(cname, cTypeInfo, access, found);
2509 if (found && (access > Public)) {
2510 qore_class_private* class_ctx = parse_get_class_priv();
2511 if ((access >= Internal && class_ctx !=
this) || !parseCheckPrivateClassAccess(class_ctx)) {
2513 cTypeInfo =
nullptr;
2523 DLLLOCAL
QoreValue parseFindConstantValue(
const char* cname,
const QoreTypeInfo*& cTypeInfo,
bool& found,
2524 const qore_class_private* class_ctx) {
2526 return parseFindConstantValueIntern(cname, cTypeInfo, found, class_ctx);
2529 DLLLOCAL
QoreValue parseFindConstantValueIntern(
const char* cname,
const QoreTypeInfo*& cTypeInfo,
bool& found,
2530 const qore_class_private* class_ctx) {
2534 ClassAccess access = Public;
2535 QoreValue rv = constlist.find(cname, cTypeInfo, access, found);
2539 if (access == Internal) {
2540 if (class_ctx ==
this)
2543 cTypeInfo =
nullptr;
2546 }
else if (access == Private && !parseCheckPrivateClassAccess(class_ctx)) {
2547 cTypeInfo =
nullptr;
2554 return scl ? scl->parseFindConstantValue(cname, cTypeInfo, found, class_ctx, class_ctx ==
this) :
QoreValue();
2557 DLLLOCAL QoreVarInfo* parseFindLocalStaticVar(
const char* vname)
const {
2558 QoreVarInfo* vi = vars.find(vname);
2560 if (vi && (vi->access > Public) && !parseCheckPrivateClassAccess())
2566 DLLLOCAL QoreVarInfo* parseFindStaticVar(
const char* vname,
const QoreClass*& qc, ClassAccess& access,
bool check =
false)
const {
2568 return parseFindStaticVarIntern(vname, qc, access, check,
true);
2571 DLLLOCAL QoreVarInfo* parseFindStaticVarIntern(
const char* vname,
const QoreClass*& qc, ClassAccess& access,
bool check,
bool toplevel)
const {
2572 QoreVarInfo* vi = vars.find(vname);
2575 ClassAccess va = vi->getAccess();
2576 if (toplevel || va != Internal) {
2582 if (check && (access > Public) && !parseCheckPrivateClassAccess()) {
2591 return scl ? scl->parseFindStaticVar(vname, qc, access, check, toplevel) :
nullptr;
2594 DLLLOCAL
void addMember(
const char* mem, ClassAccess access,
const QoreTypeInfo* n_typeinfo,
QoreValue initial_value) {
2595 assert(!members.inList(mem));
2596 if (!has_sig_changes) {
2597 has_sig_changes =
true;
2599 members.addNoCheck(strdup(mem),
new QoreMemberInfo(&loc_builtin, n_typeinfo,
nullptr, initial_value, access,
this));
2600 if (access == Public && !has_public_memdecl) {
2601 has_public_memdecl =
true;
2605 DLLLOCAL
void insertBuiltinStaticMethod(
QoreMethod* m) {
2610 ++num_static_methods;
2612 sys = committed =
true;
2615 assert(!checkSpecialStaticIntern(m->
getName()));
2617 addStaticAncestors(m);
2620 DLLLOCAL
void insertBuiltinMethod(
QoreMethod* m,
bool special_method =
false) {
2627 sys = committed =
true;
2630 if (!special_method && !checkAssignSpecialIntern(m))
2635 DLLLOCAL
void recheckBuiltinMethodHierarchy();
2637 DLLLOCAL
void addNewAncestors(
QoreMethod* m) {
2642 scl->addNewAncestors(m);
2645 DLLLOCAL
void addNewStaticAncestors(
QoreMethod* m) {
2650 scl->addNewStaticAncestors(m);
2653 DLLLOCAL
void addStaticAncestors(
QoreMethod* m) {
2658 scl->addStaticAncestors(m);
2662 assert(strcmp(m->
getName(),
"constructor"));
2668 scl->addAncestors(m);
2671 DLLLOCAL
void parseAddStaticAncestors(
QoreMethod* m) {
2676 scl->parseAddStaticAncestors(m);
2679 DLLLOCAL
void parseAddAncestors(
QoreMethod* m) {
2681 assert(strcmp(m->
getName(),
"constructor"));
2686 scl->parseAddAncestors(m);
2691 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;
2701 constlist.deleteAll(xsink);
2714 DLLLOCAL
void deleteClassData(
bool deref_vars,
ExceptionSink* xsink) {
2724 for (
auto& i : kvmap) {
2725 i.second.discard(xsink);
2735 if (deref_source_program) {
2763 const qore_class_private* class_ctx,
ExceptionSink* xsink)
const;
2770 DLLLOCAL
void addBuiltinMethod(
const char* mname, MethodVariantBase* variant);
2771 DLLLOCAL
void addBuiltinStaticMethod(
const char* mname, MethodVariantBase* variant);
2772 DLLLOCAL
void addBuiltinConstructor(BuiltinConstructorVariantBase* variant);
2773 DLLLOCAL
void addBuiltinDestructor(BuiltinDestructorVariantBase* variant);
2774 DLLLOCAL
void addBuiltinCopyMethod(BuiltinCopyVariantBase* variant);
2775 DLLLOCAL
void setBuiltinSystemConstructor(BuiltinSystemConstructorBase* m);
2782 DLLLOCAL
QoreMethod* parseFindLocalMethod(
const char* nme) {
2783 hm_method_t::iterator i = hm.find(nme);
2784 return (i != hm.end()) ? i->second :
nullptr;
2787 DLLLOCAL
const QoreMethod* parseFindLocalMethod(
const char* nme)
const {
2788 hm_method_t::const_iterator i = hm.find(nme);
2789 return (i != hm.end()) ? i->second :
nullptr;
2792 DLLLOCAL
QoreMethod* parseFindLocalMethod(
const std::string& nme) {
2793 hm_method_t::iterator i = hm.find(nme);
2794 return (i != hm.end()) ? i->second :
nullptr;
2797 DLLLOCAL
const QoreMethod* parseFindLocalMethod(
const std::string& nme)
const {
2798 hm_method_t::const_iterator i = hm.find(nme);
2799 return (i != hm.end()) ? i->second :
nullptr;
2803 DLLLOCAL
const QoreMethod* parseFindAnyLocalMethod(
const char* nme)
const {
2804 const QoreMethod* m = parseFindLocalMethod(nme);
2805 return m ? m : parseFindLocalStaticMethod(nme);
2809 DLLLOCAL
QoreMethod* parseFindLocalStaticMethod(
const char* nme) {
2810 hm_method_t::iterator i = shm.find(nme);
2811 return (i != shm.end()) ? i->second :
nullptr;
2814 DLLLOCAL
const QoreMethod* parseFindLocalStaticMethod(
const char* nme)
const {
2815 hm_method_t::const_iterator i = shm.find(nme);
2816 return (i != shm.end()) ? i->second :
nullptr;
2819 DLLLOCAL
const QoreMethod* parseGetConstructor()
const {
2820 const_cast<qore_class_private*
>(
this)->initialize();
2824 return parseFindLocalMethod(
"constructor");
2827 DLLLOCAL
void unsetPublicMemberFlag() {
2828 assert(has_public_memdecl);
2829 has_public_memdecl =
false;
2836 DLLLOCAL
QoreMethod* findLocalCommittedMethod(
const char* nme);
2838 DLLLOCAL
const QoreMethod* findLocalCommittedMethod(
const char* nme)
const;
2841 DLLLOCAL
QoreMethod* findLocalCommittedStaticMethod(
const char* nme);
2843 DLLLOCAL
const QoreMethod* findLocalCommittedStaticMethod(
const char* nme)
const;
2845 DLLLOCAL
void finalizeBuiltin(
const char* nspath);
2846 DLLLOCAL
void generateBuiltinSignature(
const char* nspath);
2847 DLLLOCAL
void initializeBuiltin();
2853 DLLLOCAL
static const QoreMethod* doParseMethodAccess(
const QoreMethod* m,
const qore_class_private* class_ctx);
2855 DLLLOCAL
static const QoreMethod* doMethodAccess(
const QoreMethod* m, ClassAccess ma,
const qore_class_private* class_ctx) {
2857 return ((ma == Public) || ((ma == Private && class_ctx))) ? m :
nullptr;
2860 DLLLOCAL
static const QoreMethod* doMethodAccess(
const QoreMethod* m, ClassAccess& access, ClassAccess ma) {
2865 else if (access < ma)
2871 DLLLOCAL
const QoreMethod* doRuntimeMethodAccess(
const QoreMethod* m, ClassAccess& access, ClassAccess ma,
const qore_class_private* class_ctx)
const {
2874 if (ma >= Internal && (!class_ctx || !equal(*class_ctx)))
2876 else if (access < ma)
2883 DLLLOCAL
const QoreMethod* parseFindNormalMethod(
const char* mname,
const qore_class_private* class_ctx);
2886 DLLLOCAL
const QoreMethod* parseFindStaticMethod(
const char* mname,
const qore_class_private* class_ctx);
2889 DLLLOCAL
const QoreMethod* parseFindNormalMethodIntern(
const char* mname,
const qore_class_private* class_ctx);
2892 DLLLOCAL
const QoreMethod* parseFindStaticMethodIntern(
const char* mname,
const qore_class_private* class_ctx);
2894 DLLLOCAL
const QoreMethod* parseResolveSelfMethodIntern(
const QoreProgramLocation* loc,
const char* nme,
const qore_class_private* class_ctx);
2898 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethodIntern(
const char* nme, ClassAccess& access,
const qore_class_private* class_ctx)
const {
2899 const QoreMethod* m = findLocalCommittedStaticMethod(nme);
2901 (class_ctx ==
this || doRuntimeMethodAccess(m, access, m->
getAccess(), class_ctx))) {
2908 return scl->runtimeFindCommittedStaticMethod(nme, access, class_ctx, class_ctx ==
this);
2913 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethodIntern(
const char* nme, ClassAccess& access,
const qore_class_private* class_ctx)
const {
2914 const QoreMethod* m = findLocalCommittedMethod(nme);
2917 (class_ctx ==
this || doRuntimeMethodAccess(m, access, m->
getAccess(), class_ctx))) {
2924 return scl->runtimeFindCommittedMethod(nme, access, class_ctx, class_ctx ==
this);
2927 DLLLOCAL
const QoreMethod* runtimeFindCommittedStaticMethod(
const char* nme, ClassAccess& access,
2928 const qore_class_private* class_ctx)
const;
2930 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethod(
const char* nme, ClassAccess& access,
2931 const qore_class_private* class_ctx)
const;
2933 DLLLOCAL
const QoreMethod* runtimeFindCommittedMethodForEval(
const char* nme, ClassAccess& access,
2934 const qore_class_private* class_ctx)
const;
2936 DLLLOCAL
const QoreMethod* runtimeFindAnyCommittedMethod(
const char* nme)
const {
2937 ClassAccess access = Public;
2938 const qore_class_private* class_ctx =
this;
2939 const QoreMethod* m = runtimeFindCommittedMethodIntern(nme, access, class_ctx);
2942 if (!strcmp(nme,
"constructor"))
2944 if (!strcmp(nme,
"destructor"))
2946 if (!strcmp(nme,
"copy"))
2948 if (!strcmp(nme,
"methodGate"))
2950 if (!strcmp(nme,
"memberGate"))
2952 if (!strcmp(nme,
"memberNotification"))
2953 return memberNotification;
2958 DLLLOCAL
const QoreMethod* findMethod(
const char* nme, ClassAccess& access)
const {
2959 CurrentProgramRuntimeParseContextHelper pch;
2960 const qore_class_private* class_ctx = runtime_get_class();
2961 if (class_ctx && !runtimeCheckPrivateClassAccess(class_ctx))
2962 class_ctx =
nullptr;
2963 return runtimeFindCommittedMethod(nme, access, class_ctx);
2966 DLLLOCAL
bool runtimeHasCallableMethod(
const char* m,
int mask)
const;
2976 DLLLOCAL
int parseInit();
2977 DLLLOCAL
int parseResolveHierarchy();
2978 DLLLOCAL
void parseResolveClassMembers();
2979 DLLLOCAL
void parseResolveAbstract();
2980 DLLLOCAL
void parseCommit();
2982 DLLLOCAL
void parseRollback();
2983 DLLLOCAL
int addUserMethod(
const char* mname, MethodVariantBase* f,
bool n_static);
2984 DLLLOCAL
void addLocalMembersForInit();
2989 DLLLOCAL
QoreValue evalPseudoMethod(
const QoreMethod* m,
const AbstractQoreFunctionVariant* variant,
2996 const qore_class_private* class_ctx = runtime_get_class();
2997 if (class_ctx && !runtimeCheckPrivateClassAccess(class_ctx)) {
2998 class_ctx =
nullptr;
3001 if (!(w = runtimeFindCommittedMethod(nme, access, class_ctx))) {
3005 const char* cname = n.get<
const QoreObject>()->getClassName();
3006 xsink->
raiseException(
"METHOD-DOES-NOT-EXIST",
"no method %s::%s() or pseudo-method %s::%s() is " \
3007 "available", cname, nme, name.c_str(), nme);
3009 xsink->
raiseException(
"PSEUDO-METHOD-DOES-NOT-EXIST",
"no pseudo method <%s>::%s() has been defined",
3010 n.getTypeName(), nme);
3018 DLLLOCAL
bool parseCheckPrivateClassAccess(
const qore_class_private* qc = parse_get_class_priv())
const;
3019 DLLLOCAL
bool runtimeCheckPrivateClassAccess(
const qore_class_private* qc = runtime_get_class())
const;
3022 DLLLOCAL qore_type_result_e parseCheckCompatibleClass(
const qore_class_private& oc)
const {
3023 bool may_not_match =
false;
3024 qore_type_result_e rv = parseCheckCompatibleClass(oc, may_not_match);
3027 return QTI_NOT_EQUAL;
3031 DLLLOCAL qore_type_result_e parseCheckCompatibleClass(
const qore_class_private& oc,
bool& may_not_match)
const;
3032 DLLLOCAL qore_type_result_e parseCheckCompatibleClassIntern(
const qore_class_private& oc,
bool& may_not_match)
const;
3034 DLLLOCAL qore_type_result_e runtimeCheckCompatibleClass(
const qore_class_private& oc)
const;
3035 DLLLOCAL qore_type_result_e runtimeCheckCompatibleClassIntern(
const qore_class_private& oc)
const;
3038 DLLLOCAL
const QoreClass* findInHierarchy(
const qore_class_private& qc) {
3041 return scl ? scl->findInHierarchy(qc) :
nullptr;
3047 return scl ? scl->
getClass(cid, n_access, toplevel) :
nullptr;
3050 DLLLOCAL
const QoreClass* getClass(
const qore_class_private& qc, ClassAccess& n_access)
const {
3052 return getClassIntern(qc, n_access,
true);
3055 DLLLOCAL
const QoreClass* getClassIntern(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const {
3060 if (qc.name == name) {
3063 qc.hash.toString(rh);
3064 printd(0,
"qore_class_private::getClassIntern() this: %p '%s' != '%s' scl: %p (hash: %s qc.hash: %s)\n",
this, name.c_str(), qc.name.c_str(), scl, lh.
getBuffer(), rh.
getBuffer());
3068 return scl ? scl->getClass(qc, n_access, toplevel) :
nullptr;
3071 DLLLOCAL
const QoreClass* parseGetClassIntern(
const qore_class_private& qc, ClassAccess& n_access,
bool toplevel)
const {
3078 if (qc.name == name) {
3079 printd(5,
"qore_class_private::parseGetClassIntern() this: %p '%s' != '%s' scl: %p\n",
this, name.c_str(), qc.name.c_str(), scl);
3081 qc.parseShowHashes();
3085 return scl ? scl->parseGetClass(qc, n_access, toplevel) :
nullptr;
3088 DLLLOCAL
bool inHierarchy(
const qore_class_private& qc, ClassAccess& n_access)
const {
3093 return scl ? scl->
inHierarchy(qc, n_access) :
false;
3096 DLLLOCAL
bool inHierarchyStrict(
const qore_class_private& qc, ClassAccess& n_access)
const {
3097 if (strictEqual(qc)) {
3105 DLLLOCAL
void parseShowHash()
const {
3108 printd(5,
" + %p %s committed: %s\n",
this, name.c_str(), ch.
getBuffer());
3112 DLLLOCAL
bool parseCheckEqualHash(
const qore_class_private& qc)
const {
3114 printd(5,
"qore_class_private::parseCheckEqualHash() %s == %s\n", name.c_str(), qc.name.c_str());
3118 return hash == qc.hash;
3121 DLLLOCAL
bool strictEqual(
const qore_class_private& qc)
const {
3126 if (qc.classID == classID || (qc.name == name && qc.hash == hash)) {
3133 DLLLOCAL
bool equal(
const qore_class_private& qc)
const {
3137 if (qc.classID == classID || (qc.name == name && qc.hash == hash))
3140 if (injectedClass && injectedClass->equal(qc))
3143 if (qc.injectedClass && equal(*qc.injectedClass))
3149 DLLLOCAL
bool parseEqual(
const qore_class_private& qc)
const {
3153 if (qc.classID == classID || (qc.name == name && parseCheckEqualHash(qc)))
3156 if (injectedClass && injectedClass->parseEqual(qc))
3159 if (qc.injectedClass && parseEqual(*qc.injectedClass))
3165 DLLLOCAL
const QoreClass* parseGetClass(
const qore_class_private& qc, ClassAccess& n_access)
const;
3167 DLLLOCAL
int addBaseClassesToSubclass(
QoreClass* sc,
bool is_virtual);
3169 DLLLOCAL
void setPublic();
3171 DLLLOCAL
void parseSetBaseClassList(BCList* bcl) {
3175 if (!has_new_user_changes)
3176 has_new_user_changes =
true;
3177 if (!has_sig_changes)
3178 has_sig_changes =
true;
3182 DLLLOCAL
bool parseHasPendingChanges()
const {
3183 return has_new_user_changes;
3186 DLLLOCAL
bool parseCheckHierarchy(
const QoreClass* n_cls, ClassAccess& access)
const {
3188 return parseCheckHierarchyIntern(n_cls, access,
true);
3191 DLLLOCAL
bool parseCheckHierarchyIntern(
const QoreClass* n_cls, ClassAccess& access,
bool toplevel)
const {
3192 if (parseEqual(*n_cls->priv))
3195 return scl ? scl->parseCheckHierarchy(n_cls, access, toplevel) :
false;
3198 DLLLOCAL VRMutex* getGate()
const {
3203 DLLLOCAL
const QoreMethod* parseFindAnyMethod(
const char* nme,
const qore_class_private* class_ctx);
3206 DLLLOCAL
const QoreMethod* parseFindAnyMethodStaticFirst(
const char* nme,
const qore_class_private* class_ctx);
3209 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc,
const char* nme,
3210 const qore_class_private* class_ctx);
3211 DLLLOCAL
const QoreMethod* parseResolveSelfMethod(
const QoreProgramLocation* loc, NamedScope* nme);
3214 DLLLOCAL
const QoreMethod* parseFindSelfMethod(
const char* nme);
3216 DLLLOCAL
char* getHash()
const {
3217 return hash.getHash();
3221 assert(!serializer);
3226 assert(!deserializer);
3233 DLLLOCAL
static char* getHash(
const QoreClass& qc) {
3234 return qc.priv->getHash();
3237 DLLLOCAL
static void parseAddConstant(
QoreClass& qc,
const QoreProgramLocation* loc,
const std::string &cname,
QoreValue val, ClassAccess access) {
3238 qc.priv->parseAddConstant(loc, cname, val, access);
3241 DLLLOCAL
static LocalVar* getSelfId(
const QoreClass& qc) {
3242 return &qc.priv->selfid;
3245 DLLLOCAL
static QoreObject* execConstructor(
const QoreClass& qc,
const AbstractQoreFunctionVariant* variant,
3247 return qc.priv->execConstructor(xsink, variant, args);
3250 DLLLOCAL
static bool injected(
const QoreClass& qc) {
3251 return qc.priv->inject;
3255 const qore_class_private* injectedClass, qore_ns_private* ns, q_setpub_t set_pub) {
3256 qore_class_private* priv =
new qore_class_private(*qc.priv, ns, spgm, nme, inject, injectedClass, set_pub);
3261 DLLLOCAL
static const QoreMethod* runtimeFindCommittedStaticMethod(
const QoreClass& qc,
const char* nme,
3262 ClassAccess& access,
const qore_class_private* class_ctx) {
3263 return qc.priv->runtimeFindCommittedStaticMethod(nme, access, class_ctx);
3266 DLLLOCAL
static const QoreMethod* parseFindLocalMethod(
const QoreClass& qc,
const char* mname) {
3267 return qc.priv->parseFindLocalMethod(mname);
3270 DLLLOCAL
static bool parseHasPendingChanges(
const QoreClass& qc) {
3271 return qc.priv->parseHasPendingChanges();
3274 DLLLOCAL
static int parseCheckMemberAccess(
const QoreClass& qc,
const QoreProgramLocation* loc,
const char* mem,
3275 const QoreTypeInfo*& memberTypeInfo,
int pflag) {
3276 return qc.priv->parseCheckMemberAccess(loc, mem, memberTypeInfo, pflag);
3279 DLLLOCAL
static bool runtimeHasCallableMethod(
const QoreClass& qc,
const char* m) {
3280 return qc.priv->runtimeHasCallableMethod(m, QCCM_NORMAL | QCCM_STATIC);
3283 DLLLOCAL
static bool runtimeHasCallableNormalMethod(
const QoreClass& qc,
const char* m) {
3284 return qc.priv->runtimeHasCallableMethod(m, QCCM_NORMAL);
3287 DLLLOCAL
static bool runtimeHasCallableStaticMethod(
const QoreClass& qc,
const char* m) {
3288 return qc.priv->runtimeHasCallableMethod(m, QCCM_STATIC);
3292 return qc.priv->runtimeCheckInstantiateClass(xsink);
3295 DLLLOCAL
static int parseInitPartial(
QoreClass& qc) {
3296 return qc.priv->parseInitPartial();
3299 DLLLOCAL
static void parseCommit(
QoreClass& qc) {
3300 qc.priv->parseCommit();
3304 qc.priv->parseCommitRuntimeInit(xsink);
3307 DLLLOCAL
static void parseRollback(
QoreClass& qc) {
3308 qc.priv->parseRollback();
3311 DLLLOCAL
static void resolveCopy(
QoreClass& qc) {
3312 qc.priv->resolveCopy();
3315 DLLLOCAL
static int addUserMethod(
QoreClass& qc,
const char* mname, MethodVariantBase* f,
bool n_static) {
3316 return qc.priv->addUserMethod(mname, f, n_static);
3319 DLLLOCAL
static void initialize(
QoreClass& qc) {
3320 qc.priv->initialize();
3323 DLLLOCAL
static void parseSetBaseClassList(
QoreClass& qc, BCList* bcl) {
3324 qc.priv->parseSetBaseClassList(bcl);
3327 DLLLOCAL
static BCList* getBaseClassList(
const QoreClass& qc) {
3328 return qc.priv->scl;
3331 DLLLOCAL
static void parseAddStaticVar(
QoreClass* qc,
char* dname, ClassAccess access, QoreVarInfo* VarInfo) {
3332 qc->priv->parseAddStaticVar(dname, access, VarInfo);
3336 DLLLOCAL
static QoreValue parseFindLocalConstantValue(
QoreClass* qc,
const char* cname,
3337 const QoreTypeInfo*& typeInfo,
bool& found) {
3338 return qc->priv->parseFindLocalConstantValue(cname, typeInfo, found);
3342 DLLLOCAL
static QoreVarInfo* parseFindLocalStaticVar(
const QoreClass* qc,
const char* vname) {
3343 return qc->priv->parseFindLocalStaticVar(vname);
3347 DLLLOCAL
static QoreValue parseFindConstantValue(
QoreClass* qc,
const char* cname,
const QoreTypeInfo*& typeInfo,
3348 bool& found,
const qore_class_private* class_ctx) {
3349 return qc->priv->parseFindConstantValue(cname, typeInfo, found, class_ctx);
3354 DLLLOCAL
static QoreVarInfo* parseFindStaticVar(
const QoreClass* qc,
const char* vname,
const QoreClass*& nqc,
3355 ClassAccess& access,
bool check =
false) {
3356 return qc->priv->parseFindStaticVar(vname, nqc, access, check);
3359 DLLLOCAL
static int parseCheckInternalMemberAccess(
const QoreClass* qc,
const char* mem,
3360 const QoreTypeInfo*& memberTypeInfo,
const QoreProgramLocation* loc) {
3361 return qc->priv->parseCheckInternalMemberAccess(mem, memberTypeInfo, loc);
3364 DLLLOCAL
static int parseResolveInternalMemberAccess(
const QoreClass* qc,
const char* mem,
3365 const QoreTypeInfo*& memberTypeInfo) {
3366 return qc->priv->parseResolveInternalMemberAccess(mem, memberTypeInfo);
3370 return qc->priv->parseFindSelfMethod(mname);
3373 DLLLOCAL
static void parseAddMember(
QoreClass& qc,
char* nme, ClassAccess access, QoreMemberInfo* mInfo) {
3374 qc.priv->parseAddMember(nme, access, mInfo);
3378 return qc->priv->evalPseudoMethod(n, name, args, xsink);
3382 return qc->priv->evalPseudoMethod(m, variant, n, args, xsink);
3385 DLLLOCAL
static bool parseCheckPrivateClassAccess(
const QoreClass& qc,
const qore_class_private* oqc = parse_get_class_priv()) {
3386 return qc.priv->parseCheckPrivateClassAccess(oqc);
3389 DLLLOCAL
static bool runtimeCheckPrivateClassAccess(
const QoreClass& qc,
const qore_class_private* oqc = runtime_get_class()) {
3390 return qc.priv->runtimeCheckPrivateClassAccess(oqc);
3393 DLLLOCAL
static qore_type_result_e parseCheckCompatibleClass(
const QoreClass* qc,
const QoreClass* oc) {
3395 return QTI_NOT_EQUAL;
3396 return qc->priv->parseCheckCompatibleClass(*(oc->priv));
3399 DLLLOCAL
static qore_type_result_e runtimeCheckCompatibleClass(
const QoreClass& qc,
const QoreClass& oc) {
3400 return qc.priv->runtimeCheckCompatibleClass(*oc.priv);
3403 DLLLOCAL
static qore_class_private* get(
QoreClass& qc) {
3407 DLLLOCAL
static const qore_class_private* get(
const QoreClass& qc) {
3411 DLLLOCAL
static bool isPublic(
const QoreClass& qc) {
3412 return qc.priv->pub;
3415 DLLLOCAL
static bool isUserPublic(
const QoreClass& qc) {
3416 return qc.priv->pub && !qc.priv->sys;
3419 DLLLOCAL
static bool isFinal(
const QoreClass& qc) {
3420 return qc.priv->final;
3423 DLLLOCAL
static void setPublic(
QoreClass& qc) {
3424 qc.priv->setPublic();
3427 DLLLOCAL
static void setFinal(
QoreClass& qc) {
3428 assert(!qc.priv->final);
3429 qc.priv->final =
true;
3434 DLLLOCAL ~qore_class_private();
3437 class qore_class_private_holder {
3438 qore_class_private* c;
3441 DLLLOCAL qore_class_private_holder(
QoreClass* n_c) : c(qore_class_private::get(*n_c)) {
3444 DLLLOCAL qore_class_private_holder(qore_class_private* n_c) : c(n_c) {
3447 DLLLOCAL ~qore_class_private_holder() {
3449 c->deref(
true,
true);
3453 DLLLOCAL qore_class_private* operator*() {
3467 class qore_method_private {
3470 MethodFunctionBase* func;
3471 bool static_flag, all_user;
3473 DLLLOCAL qore_method_private(
const QoreClass* n_parent_class, MethodFunctionBase* n_func,
bool n_static) : parent_class(n_parent_class), func(n_func), static_flag(n_static), all_user(true) {
3474 assert(parent_class == n_func->getClass());
3477 DLLLOCAL ~qore_method_private() {
3481 DLLLOCAL
void setBuiltin() {
3486 DLLLOCAL
bool isUniquelyUser()
const {
3490 DLLLOCAL
bool isAbstract()
const {
3491 return func->isAbstract();
3494 DLLLOCAL
int addUserVariant(MethodVariantBase* variant) {
3495 return func->parseAddUserMethodVariant(variant);
3498 DLLLOCAL
void addBuiltinVariant(MethodVariantBase* variant) {
3500 func->addBuiltinMethodVariant(variant);
3503 DLLLOCAL MethodFunctionBase* getFunction()
const {
3504 return const_cast<MethodFunctionBase*
>(func);
3507 DLLLOCAL
const char* getName()
const {
3508 return func->getName();
3511 DLLLOCAL
const std::string& getNameStr()
const {
3512 return func->getNameStr();
3515 DLLLOCAL
int parseInit();
3517 DLLLOCAL
int parseInitStatic() {
3518 assert(static_flag);
3519 int err = func->parseInit();
3521 if (func->checkFinal() && !err) {
3527 DLLLOCAL
const QoreTypeInfo* getUniqueReturnTypeInfo()
const {
3528 return func->getUniqueReturnTypeInfo();
3532 CONMF(func)->evalConstructor(variant, *parent_class,
self, args, parent_class->priv->scl, bceal, xsink);
3536 COPYMF(func)->evalCopy(*parent_class,
self, old, parent_class->priv->scl, xsink);
3540 COPYMF(func)->evalCopy(*parent_class,
self, old,
nullptr, xsink);
3544 DESMF(func)->evalDestructor(*parent_class,
self, xsink);
3549 DESMF(func)->evalDestructor(*parent_class,
self, xsink);
3552 DLLLOCAL
void evalSystemConstructor(
QoreObject*
self,
int code, va_list args)
const {
3553 BSYSCONB(func)->eval(*parent_class,
self, code, args);
3559 return NMETHF(func)->evalMethod(xsink, 0,
self, args, cctx);
3561 return SMETHF(func)->evalMethod(xsink, 0, args, cctx);
3567 return NMETHF(func)->evalMethodTmpArgs(xsink,
nullptr,
self, args, cctx);
3569 return SMETHF(func)->evalMethodTmpArgs(xsink,
nullptr, args, cctx);
3573 QORE_TRACE(
"qore_method_private::evalPseudoMethod()");
3575 assert(!static_flag);
3577 QoreValue rv = NMETHF(func)->evalPseudoMethod(xsink, variant, n, args);
3578 printd(5,
"qore_method_private::evalPseudoMethod() %s::%s() returning type: %s\n", parent_class->
getName(), getName(), rv.getTypeName());
3585 DLLLOCAL ClassAccess getAccess()
const;
3588 DLLLOCAL
static ClassAccess getAccess(
const QoreMethod& m) {
3589 return m.priv->getAccess();
3593 return m.priv->evalNormalVariant(
self, ev, args, xsink);
3597 return m.priv->evalPseudoMethod(variant, n, args, xsink);
3601 return m.priv->eval(xsink,
self, args, cctx);
3605 return m.priv->evalTmpArgs(xsink,
self, args, cctx);
3608 DLLLOCAL
static qore_method_private* get(
QoreMethod& m) {
3612 DLLLOCAL
static const qore_method_private* get(
const QoreMethod& m) {
3618 class PrivateIteratorBase {
3620 DLLLOCAL PrivateIteratorBase(
const T& obj) : obj(obj), i(obj.end()) {
3623 DLLLOCAL
bool next() {
3624 if (i == obj.end()) {
3629 return (i != obj.end());
3633 DLLLOCAL
bool valid()
const {
3634 return i != obj.end();
3639 typename T::const_iterator i;
3642 template <
class T,
class U>
3643 class PrivateMemberIteratorBase :
public PrivateIteratorBase<typename T::member_list_t> {
3645 DLLLOCAL PrivateMemberIteratorBase(
const typename T::member_list_t& obj) : PrivateIteratorBase<typename T::member_list_t>(obj) {
3648 DLLLOCAL
const U& getMember()
const {
3649 assert(this->valid());
3650 return *
reinterpret_cast<const U*
>(this->i->second.get());
3653 DLLLOCAL
const char* getName()
const {
3654 assert(this->valid());
3655 return this->i->first;
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:324
#define QDOM_DEFAULT
the default domain (no domain)
Definition: Restrictions.h:159
#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
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:233
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:48
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:249
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 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 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 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:135
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 char * getName() const
returns the method's name
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:127
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
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT void clear()
reset string to zero length; memory is not deallocated; string encoding does not change
DLLEXPORT int sprintf(const char *fmt,...)
this will concatentate a formatted string to the existing string according to the format string and t...
DLLEXPORT const char * c_str() const
returns the string's buffer; this data should not be changed
DLLEXPORT const char * getBuffer() const
returns the string's buffer; this data should not be changed
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:476
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
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_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
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:275
DLLEXPORT void discard(ExceptionSink *xsink)
dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values