32 #ifndef _QORE_VARIABLE_H 33 #define _QORE_VARIABLE_H 44 #include "qore/intern/RSet.h" 45 #include "qore/intern/VRMutex.h" 46 #include "qore/intern/QoreLValue.h" 47 #include "qore/intern/qore_var_rwlock_priv.h" 48 #include "qore/vector_set" 58 class ScopedObjectCallNode;
59 class QoreSquareBracketsOperatorNode;
60 class QoreSquareBracketsRangeOperatorNode;
61 class QoreHashObjectDereferenceOperatorNode;
63 union qore_gvar_ref_u {
71 DLLLOCAL
void setPtr(Var* refptr,
bool readonly =
false) {
72 _refptr = (size_t)refptr;
77 DLLLOCAL Var* getPtr()
const {
78 #ifndef HAVE_LLVM_BUG_22050 81 return (Var*)((_refptr & 1L) ? (_refptr ^ 1L) : _refptr);
83 return (Var*)(_refptr & (~1L));
87 DLLLOCAL
bool isReadOnly()
const {
96 class LValueRemoveHelper;
102 const QoreProgramLocation* loc;
103 QoreLValue<qore_gvar_ref_u> val;
105 mutable QoreVarRWLock rwl;
106 QoreParseTypeInfo* parseTypeInfo;
107 const QoreTypeInfo* typeInfo;
108 const QoreTypeInfo* refTypeInfo =
nullptr;
115 Var(
const Var&) =
delete;
118 bool builtin =
false;
120 DLLLOCAL ~Var() {
delete parseTypeInfo; }
124 xsink->
raiseException(
"DESTRUCTOR-ERROR",
"illegal variable assignment after second phase of variable destruction");
131 DLLLOCAL Var(
const QoreProgramLocation* loc,
const char* n_name) : loc(loc), val(
QV_Node), name(n_name), parseTypeInfo(nullptr), typeInfo(nullptr), pub(false), finalized(false) {
134 DLLLOCAL Var(
const QoreProgramLocation* loc,
const char* n_name, QoreParseTypeInfo *n_parseTypeInfo) : loc(loc), val(
QV_Node), name(n_name), parseTypeInfo(n_parseTypeInfo), typeInfo(0), pub(false), finalized(false) {
137 DLLLOCAL Var(
const QoreProgramLocation* loc,
const char* n_name,
const QoreTypeInfo *n_typeInfo,
bool builtin =
false) : loc(loc), val(n_typeInfo), name(n_name), parseTypeInfo(nullptr), typeInfo(n_typeInfo), pub(false), finalized(false), builtin(builtin) {
140 DLLLOCAL Var(Var* ref,
bool ro =
false) : loc(ref->loc), val(
QV_Ref), name(ref->name), parseTypeInfo(nullptr), typeInfo(ref->typeInfo), pub(false), finalized(false) {
142 val.v.setPtr(ref, ro);
145 DLLLOCAL
const char* getName()
const;
147 DLLLOCAL
const std::string& getNameStr()
const {
151 DLLLOCAL
bool isBuiltin()
const {
155 DLLLOCAL
int getLValue(LValueHelper& lvh,
bool for_remove)
const;
156 DLLLOCAL
void remove(LValueRemoveHelper& lvrh);
161 QoreAutoVarRWWriteLocker al(rwl);
164 printd(5,
"Var::clearLocal() clearing '%s' %p\n", name.c_str(),
this);
165 #ifdef QORE_ENFORCE_DEFAULT_LVALUE 166 h = val.assign(QoreTypeInfo::getDefaultQoreValue(typeInfo));
168 h = val.removeValue(
true);
173 printd(5,
"Var::clearLocal() skipping imported var '%s' %p\n", name.c_str(),
this);
181 discard(val.assignInitial(v),
nullptr);
184 DLLLOCAL
const Var* parseGetVar()
const {
185 return (val.type ==
QV_Ref) ? val.v.getPtr()->parseGetVar() :
this;
188 DLLLOCAL
bool isImported()
const;
194 DLLLOCAL
void doDoubleDeclarationError(
const QoreProgramLocation* loc) {
197 parse_error(*loc,
"global variable '%s' previously declared with type '%s'", name.c_str(), QoreParseTypeInfo::getName(parseTypeInfo));
201 parse_error(*loc,
"global variable '%s' previously declared with type '%s'", name.c_str(), QoreTypeInfo::getName(typeInfo));
202 assert(!parseTypeInfo);
206 DLLLOCAL
void checkAssignType(
const QoreProgramLocation* loc,
const QoreTypeInfo *n_typeInfo) {
208 if (!QoreTypeInfo::hasType(n_typeInfo))
212 val.v.getPtr()->checkAssignType(loc, n_typeInfo);
218 if (parseTypeInfo || typeInfo) {
219 doDoubleDeclarationError(loc);
223 typeInfo = n_typeInfo;
224 refTypeInfo = QoreTypeInfo::getReferenceTarget(typeInfo);
226 assert(!val.removeValue(
true));
229 DLLLOCAL
void parseInit() {
234 typeInfo = QoreParseTypeInfo::resolveAndDelete(parseTypeInfo, loc);
235 refTypeInfo = QoreTypeInfo::getReferenceTarget(typeInfo);
236 parseTypeInfo =
nullptr;
241 #ifdef QORE_ENFORCE_DEFAULT_LVALUE 243 discard(val.assignInitial(QoreTypeInfo::getDefaultQoreValue(typeInfo)),
nullptr);
247 DLLLOCAL QoreParseTypeInfo* copyParseTypeInfo()
const {
248 return parseTypeInfo ? parseTypeInfo->copy() :
nullptr;
251 DLLLOCAL
const QoreTypeInfo* parseGetTypeInfoForInitialAssignment() {
254 return val.v.getPtr()->getTypeInfo();
260 DLLLOCAL
const QoreTypeInfo* parseGetTypeInfo() {
263 return val.v.getPtr()->getTypeInfo();
266 return refTypeInfo ? refTypeInfo : typeInfo;
269 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
270 assert(!parseTypeInfo);
272 return val.v.getPtr()->getTypeInfo();
277 DLLLOCAL
bool hasTypeInfo()
const {
279 return val.v.getPtr()->hasTypeInfo();
281 return parseTypeInfo || typeInfo;
284 DLLLOCAL
bool isRef()
const {
285 return val.type ==
QV_Ref;
289 DLLLOCAL
const char* getClassName()
const {
291 return val.v.getPtr()->getClassName();
294 assert(QoreTypeInfo::getUniqueReturnClass(typeInfo));
295 return QoreTypeInfo::getUniqueReturnClass(typeInfo)->getName();
297 assert(parseTypeInfo);
298 assert(parseTypeInfo->cscope);
299 return parseTypeInfo->cscope->getIdentifier();
302 DLLLOCAL
bool isPublic()
const {
306 DLLLOCAL
void setPublic() {
311 DLLLOCAL
const QoreProgramLocation* getParseLocation()
const {
316 DLLLOCAL
void delete_global_variables();
321 typedef vector_set_t<const void*> lvid_set_t;
324 hashdecl ObjCountRec {
333 DLLLOCAL
int getDifference();
336 typedef std::vector<ObjCountRec> ocvec_t;
341 friend class LValueRemoveHelper;
342 friend class LValueLockHandoffHelper;
346 DLLLOCAL LValueHelper(
const LValueHelper&) =
delete;
347 DLLLOCAL LValueHelper& operator=(
const LValueHelper&) =
delete;
360 DLLLOCAL
int doListLValue(
const QoreSquareBracketsOperatorNode* op,
bool for_remove);
361 DLLLOCAL
int doHashLValue(
qore_type_t t,
const char* mem,
bool for_remove);
362 DLLLOCAL
int doHashObjLValue(
const QoreHashObjectDereferenceOperatorNode* op,
bool for_remove);
364 DLLLOCAL
int makeInt(
const char* desc);
365 DLLLOCAL
int makeFloat(
const char* desc);
366 DLLLOCAL
int makeNumber(
const char* desc);
368 DLLLOCAL
int doRecursiveException() {
369 vl.xsink->raiseException(
"REFERENCE-ERROR",
"recursive reference detected in assignment");
378 typedef std::vector<AbstractQoreNode*> nvec_t;
380 lvid_set_t* lvid_set =
nullptr;
390 RObject* robj =
nullptr;
393 QoreLValueGeneric* val =
nullptr;
395 const QoreTypeInfo* typeInfo =
nullptr;
402 DLLLOCAL LValueHelper(LValueHelper&& o);
407 DLLLOCAL ~LValueHelper();
409 DLLLOCAL
void setClosure(RObject* c) {
417 return tvec[tvec.size() - 1];
420 DLLLOCAL
int doLValue(
const QoreValue exp,
bool for_remove);
422 DLLLOCAL
int doLValue(
const ReferenceNode* ref,
bool for_remove);
424 DLLLOCAL
void setAndLock(QoreVarRWLock& rwl);
425 DLLLOCAL
void set(QoreVarRWLock& rwl);
431 DLLLOCAL
void setTypeInfo(
const QoreTypeInfo* ti) {
435 DLLLOCAL
void setValue(QoreLValueGeneric& nv,
const QoreTypeInfo* ti =
nullptr) {
442 before = nv.assigned && nv.type ==
QV_Node ? needs_scan(nv.v.n) : false;
447 DLLLOCAL
void setValue(
QoreValue& nqv,
const QoreTypeInfo* ti =
nullptr) {
453 before = needs_scan(nqv);
458 DLLLOCAL
void resetValue(QoreLValueGeneric& nv,
const QoreTypeInfo* ti =
nullptr) {
468 before = nv.assigned && nv.type ==
QV_Node ? needs_scan(nv.v.n) : false;
473 DLLLOCAL
void resetValue(
QoreValue& nqv,
const QoreTypeInfo* ti =
nullptr) {
483 before = needs_scan(nqv);
488 DLLLOCAL
void clearPtr() {
497 DLLLOCAL
operator bool()
const {
501 DLLLOCAL
bool isOptimized()
const {
502 return val && val->optimized();
505 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
510 return val ? val->getType() : qv->getType();
513 DLLLOCAL
const QoreValue getValue()
const {
514 return val ? val->getValue() : *qv;
518 return val ? val->getValue() : *qv;
522 assert((val && val->getInternalNode()) || (qv && qv->getInternalNode()));
523 return val ? val->getInternalNode() : qv->getInternalNode();
526 DLLLOCAL
const char* getTypeName()
const {
527 return val ? val->getTypeName() : qv->getTypeName();
530 DLLLOCAL
bool checkType(
const qore_type_t t)
const {
531 return getType() == t;
534 DLLLOCAL
bool isNothing()
const {
538 DLLLOCAL
void setObjectContext(qore_object_private* obj);
540 DLLLOCAL
QoreValue getReferencedValue()
const;
544 DLLLOCAL
void ensureUnique() {
551 assignNodeIntern(current_value->
realCopy());
556 DLLLOCAL
int64 getAsBigInt()
const;
557 DLLLOCAL
bool getAsBool()
const;
558 DLLLOCAL
double getAsFloat()
const;
560 DLLLOCAL
int64 plusEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
561 DLLLOCAL
int64 minusEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
562 DLLLOCAL
int64 multiplyEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
563 DLLLOCAL
int64 divideEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
564 DLLLOCAL
int64 orEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
565 DLLLOCAL
int64 andEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
566 DLLLOCAL
int64 xorEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
567 DLLLOCAL
int64 modulaEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
568 DLLLOCAL
int64 shiftLeftEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
569 DLLLOCAL
int64 shiftRightEqualsBigInt(
int64 v,
const char* desc =
"<lvalue>");
570 DLLLOCAL
int64 preIncrementBigInt(
const char* desc =
"<lvalue>");
571 DLLLOCAL
int64 preDecrementBigInt(
const char* desc =
"<lvalue>");
572 DLLLOCAL
int64 postIncrementBigInt(
const char* desc =
"<lvalue>");
573 DLLLOCAL
int64 postDecrementBigInt(
const char* desc =
"<lvalue>");
575 DLLLOCAL
double plusEqualsFloat(
double v,
const char* desc =
"<lvalue>");
576 DLLLOCAL
double minusEqualsFloat(
double v,
const char* desc =
"<lvalue>");
577 DLLLOCAL
double multiplyEqualsFloat(
double v,
const char* desc =
"<lvalue>");
578 DLLLOCAL
double divideEqualsFloat(
double v,
const char* desc =
"<lvalue>");
579 DLLLOCAL
double preIncrementFloat(
const char* desc =
"<lvalue>");
580 DLLLOCAL
double preDecrementFloat(
const char* desc =
"<lvalue>");
581 DLLLOCAL
double postIncrementFloat(
const char* desc =
"<lvalue>");
582 DLLLOCAL
double postDecrementFloat(
const char* desc =
"<lvalue>");
584 DLLLOCAL
void plusEqualsNumber(
QoreValue r,
const char* desc =
"<lvalue>");
585 DLLLOCAL
void minusEqualsNumber(
QoreValue r,
const char* desc =
"<lvalue>");
586 DLLLOCAL
void multiplyEqualsNumber(
QoreValue r,
const char* desc =
"<lvalue>");
587 DLLLOCAL
void divideEqualsNumber(
QoreValue r,
const char* desc =
"<lvalue>");
588 DLLLOCAL
void preIncrementNumber(
const char* desc =
"<lvalue>");
589 DLLLOCAL
void preDecrementNumber(
const char* desc =
"<lvalue>");
590 DLLLOCAL
QoreNumberNode* postIncrementNumber(
bool ref_rv,
const char* desc =
"<lvalue>");
591 DLLLOCAL
QoreNumberNode* postDecrementNumber(
bool ref_rv,
const char* desc =
"<lvalue>");
593 DLLLOCAL
QoreNumberNode* ensureUniqueNumber(
const char* desc =
"<lvalue>") {
596 if (makeNumber(desc))
602 if (makeNumber(desc))
608 if (!(*p)->is_unique()) {
616 DLLLOCAL
int assign(
QoreValue val,
const char* desc =
"<lvalue>",
bool check_types =
true,
bool weak_assignment =
false);
618 DLLLOCAL
QoreValue removeValue(
bool for_del);
619 DLLLOCAL
QoreValue remove(
bool& static_assignment);
621 DLLLOCAL
void setDelta(
int dt) {
627 class LValueRemoveHelper {
630 LValueRemoveHelper(
const LValueRemoveHelper&) =
delete;
631 LValueRemoveHelper& operator=(
const LValueRemoveHelper&) =
delete;
632 void*
operator new(size_t) =
delete;
634 DLLLOCAL
void doRemove(
const QoreSquareBracketsOperatorNode* op);
635 DLLLOCAL
void doRemove(
const QoreSquareBracketsOperatorNode* op,
const QoreParseListNode* l);
636 DLLLOCAL
void doRemove(
const QoreSquareBracketsRangeOperatorNode* op);
640 QoreLValueGeneric rv;
650 DLLLOCAL
operator bool()
const {
658 DLLLOCAL
bool forDel()
const {
662 DLLLOCAL
void doRemove(QoreLValueGeneric& qv,
const QoreTypeInfo* ti) {
663 #ifdef QORE_ENFORCE_DEFAULT_LVALUE 664 rv.assignSetInitialSwap(qv, QoreTypeInfo::getDefaultQoreValue(ti));
666 rv.assignSetTakeInitial(qv);
671 DLLLOCAL
QoreValue remove(
bool& static_assignment);
673 DLLLOCAL
void deleteLValue();
676 #endif // _QORE_VARIABLE_H Qore's arbitrary-precision number value type, dynamically-allocated only, reference counted...
Definition: QoreNumberNode.h:51
AutoVLock is a container for safely managing global variable and object lock handovers, required for functions accessing global variables and object data where locking is necessary.
Definition: AutoVLock.h:80
DLLLOCAL qore_type_t getType() const
returns the data type
Definition: AbstractQoreNode.h:172
This is the hash or associative list container type in Qore, dynamically allocated only...
Definition: QoreHashNode.h:50
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
const qore_type_t NT_NOTHING
type value for QoreNothingNode
Definition: node_types.h:42
const qore_type_t NT_OBJECT
type value for QoreObject
Definition: node_types.h:52
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:326
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
#define QV_Node
for heap-allocated values
Definition: QoreValue.h:46
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
provides atomic reference counting to Qore objects
Definition: QoreReferenceCounter.h:44
parse type: reference to a lvalue expression
Definition: ReferenceNode.h:45
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:262
virtual DLLEXPORT AbstractQoreNode * realCopy() const =0
returns a copy of the object; the caller owns the reference count
the implementation of Qore's object data type, reference counted, dynamically-allocated only ...
Definition: QoreObject.h:61
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
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
DLLEXPORT bool is_unique() const
returns true if the reference count is 1
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode) ...
Definition: common.h:70
#define QV_Ref
for references (when used with lvalues)
Definition: QoreValue.h:47
const qore_type_t NT_NUMBER
type value for QoreNumberNode
Definition: node_types.h:53
holds an object and dereferences it in the destructor
Definition: QoreValue.h:452