Qore Programming Language 1.19.5
Loading...
Searching...
No Matches
Variable.h
1/* -*- mode: c++; indent-tabs-mode: nil -*- */
2/*
3 Variable.h
4
5 Qore Programming Language
6
7 Copyright (C) 2003 - 2023 Qore Technologies, s.r.o.
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26
27 Note that the Qore library is released under a choice of three open-source
28 licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29 information.
30*/
31
32#ifndef _QORE_VARIABLE_H
33#define _QORE_VARIABLE_H
34
35enum qore_var_t {
36 VT_UNRESOLVED = 1,
37 VT_LOCAL = 2,
38 VT_GLOBAL = 3,
39 VT_CLOSURE = 4,
40 VT_LOCAL_TS = 5, // thread-safe variables, not closure-bound
41 VT_IMMEDIATE = 6, // used in references with immediate variable storage
42 VT_THREAD_LOCAL = 7
43};
44
45#include "qore/intern/RSet.h"
46#include "qore/intern/VRMutex.h"
47#include "qore/intern/QoreLValue.h"
48#include "qore/intern/qore_var_rwlock_priv.h"
49#include "qore/vector_set"
50
51#include <cstdlib>
52#include <cstring>
53#include <memory>
54#include <set>
55#include <string>
56
57// forward references
58class Var;
59class ScopedObjectCallNode;
60class QoreSquareBracketsOperatorNode;
61class QoreSquareBracketsRangeOperatorNode;
62class QoreHashObjectDereferenceOperatorNode;
63
64union qore_gvar_ref_u {
65 bool b;
66 int64 i;
67 double f;
69 // note that the "readonly" flag is stored in bit 0 of this pointer - do not read directly
70 size_t _refptr;
71
72 DLLLOCAL void setPtr(Var* refptr, bool readonly = false) {
73 _refptr = (size_t)refptr;
74 if (readonly)
75 _refptr |= 1;
76 }
77
78 DLLLOCAL Var* getPtr() const {
79#ifndef HAVE_LLVM_BUG_22050
80 // there is a bug in clang++ 3.5.[0|1] where the conditional expression below is executed with the opposite expressions
81 // when compiled with -O1 or greater: http://llvm.org/bugs/show_bug.cgi?id=22050
82 return (Var*)((_refptr & 1L) ? (_refptr ^ 1L) : _refptr);
83#else
84 return (Var*)(_refptr & (~1L));
85#endif
86 }
87
88 DLLLOCAL bool isReadOnly() const {
89 return _refptr & 1;
90 }
91
92 // checks if the reference can be written to, returns -1 if an exception was thrown
93 DLLLOCAL int write(ExceptionSink* xsink) const;
94};
95
96DLLLOCAL void get_thread_local_lvalue(void* ptr, QoreLValue<qore_gvar_ref_u>*& lvar, bool& is_new, bool& finalized);
97
98class LValueHelper;
99class LValueRemoveHelper;
100class RSetHelper;
101
102// structure for global variables
103class Var : protected QoreReferenceCounter {
104private:
105 const QoreProgramLocation* loc; // location of the initial definition
106 QoreLValue<qore_gvar_ref_u> val;
107 std::string name;
108 mutable QoreVarRWLock rwl;
109 QoreParseTypeInfo* parseTypeInfo = nullptr;
110 const QoreTypeInfo* typeInfo = nullptr;
111 const QoreTypeInfo* refTypeInfo = nullptr;
112 bool pub; // is this global var public (valid and set for modules only)
113 mutable bool finalized; // has this var already been cleared during Program destruction?
114 bool is_thread_local; // is this a thread_local var?
115 DLLLOCAL void del(ExceptionSink* xsink);
116
117 // not implemented
118 Var(const Var&) = delete;
119
120protected:
121 bool builtin = false;
122
123 DLLLOCAL ~Var() { delete parseTypeInfo; }
124
125 DLLLOCAL int checkFinalized(ExceptionSink* xsink) const {
126 if (finalized) {
127 xsink->raiseException("DESTRUCTOR-ERROR", "illegal variable assignment after second phase of variable " \
128 "destruction");
129 return -1;
130 }
131 return 0;
132 }
133
134 QoreLValue<qore_gvar_ref_u>& getVal() const {
135 if (is_thread_local) {
136 QoreLValue<qore_gvar_ref_u>* lvar;
137 bool is_new;
138 get_thread_local_lvalue((void*)this, lvar, is_new, finalized);
139 if (is_new) {
140 if (val.type == QV_Ref) {
141 lvar->set(QV_Ref);
142 lvar->v.setPtr(val.v.getPtr(), val.v.isReadOnly());
143 } else if (typeInfo) {
144 lvar->set(typeInfo);
145 }
146 }
147 return *lvar;
148 }
149 return const_cast<QoreLValue<qore_gvar_ref_u>&>(val);
150 }
151
152public:
153 DLLLOCAL Var(const QoreProgramLocation* loc, const char* n_name, bool is_thread_local = false)
154 : loc(loc), name(n_name), pub(false), finalized(false), is_thread_local(is_thread_local) {
155 }
156
157 DLLLOCAL Var(const QoreProgramLocation* loc, const char* n_name, QoreParseTypeInfo* n_parseTypeInfo,
158 bool is_thread_local = false) : loc(loc), name(n_name), parseTypeInfo(n_parseTypeInfo),
159 pub(false), finalized(false), is_thread_local(is_thread_local) {
160 }
161
162 DLLLOCAL Var(const QoreProgramLocation* loc, const char* n_name, const QoreTypeInfo* n_typeInfo,
163 bool builtin = false, bool is_thread_local = false) : loc(loc), val(n_typeInfo), name(n_name),
164 typeInfo(n_typeInfo), pub(false), finalized(false), is_thread_local(is_thread_local), builtin(builtin) {
165 }
166
167 DLLLOCAL Var(Var* ref, bool ro = false, bool is_thread_local = false);
168
169 DLLLOCAL const char* getName() const;
170
171 DLLLOCAL const std::string& getNameStr() const {
172 return name;
173 }
174
175 DLLLOCAL bool isBuiltin() const {
176 return builtin;
177 }
178
179 DLLLOCAL bool isThreadLocal() const {
180 return is_thread_local;
181 }
182
183 DLLLOCAL bool isGlobal() const {
184 return !is_thread_local;
185 }
186
187 DLLLOCAL int getLValue(LValueHelper& lvh, bool for_remove) const;
188 DLLLOCAL void remove(LValueRemoveHelper& lvrh);
189
190 DLLLOCAL void clearLocal(ExceptionSink* xsink) {
191 QoreLValue<qore_gvar_ref_u>& val = getVal();
192 if (val.type != QV_Ref) {
193 ValueHolder h(xsink);
194 QoreAutoVarRWWriteLocker al(rwl);
195 if (!finalized)
196 finalized = true;
197 printd(5, "Var::clearLocal() clearing '%s' %p\n", name.c_str(), this);
198 {
199 QoreProgram* pgm = getProgram();
200 // when Qore is terminating, this may be nullptr
201 if (pgm && (pgm->getParseOptions64() & PO_STRICT_TYPES)) {
202 h = val.assign(QoreTypeInfo::getDefaultQoreValue(typeInfo));
203 } else {
204 h = val.removeValue(true);
205 }
206 }
207 }
208#ifdef DEBUG
209 else
210 printd(5, "Var::clearLocal() skipping imported var '%s' %p\n", name.c_str(), this);
211#endif
212 }
213
214 DLLLOCAL void setInitial(AbstractQoreNode* v) {
215 QoreLValue<qore_gvar_ref_u>& val = getVal();
216 assert(val.type == QV_Node);
217 // try to set an optimized value type for the value holder if possible
218 val.set(typeInfo);
219 discard(val.assignInitial(v), nullptr);
220 }
221
222 DLLLOCAL const Var* parseGetVar() const;
223
224 DLLLOCAL bool isImported() const;
225
226 DLLLOCAL void deref(ExceptionSink* xsink);
227
228 DLLLOCAL QoreValue eval() const;
229
230 DLLLOCAL void doDoubleDeclarationError(const QoreProgramLocation* loc) {
231 // make sure types are identical or throw an exception
232 if (parseTypeInfo) {
233 parse_error(*loc, "global variable '%s' previously declared with type '%s'", name.c_str(), QoreParseTypeInfo::getName(parseTypeInfo));
234 assert(!typeInfo);
235 }
236 if (typeInfo) {
237 parse_error(*loc, "global variable '%s' previously declared with type '%s'", name.c_str(), QoreTypeInfo::getName(typeInfo));
238 assert(!parseTypeInfo);
239 }
240 }
241
242 DLLLOCAL void checkAssignType(const QoreProgramLocation* loc, const QoreTypeInfo *n_typeInfo);
243
244 DLLLOCAL int parseInit() {
245 QoreLValue<qore_gvar_ref_u>& val = getVal();
246
247 if (val.type == QV_Ref)
248 return 0;
249
250 int err = 0;
251
252 if (parseTypeInfo) {
253 typeInfo = QoreParseTypeInfo::resolveAndDelete(parseTypeInfo, loc, err);
254 refTypeInfo = QoreTypeInfo::getReferenceTarget(typeInfo);
255 parseTypeInfo = nullptr;
256
257 val.set(typeInfo);
258 }
259
260 if ((getProgram()->getParseOptions64() & PO_STRICT_TYPES) && !val.hasValue()) {
261 discard(val.assignInitial(QoreTypeInfo::getDefaultQoreValue(typeInfo)), nullptr);
262 }
263
264 return err;
265 }
266
267 DLLLOCAL QoreParseTypeInfo* copyParseTypeInfo() const {
268 return parseTypeInfo ? parseTypeInfo->copy() : nullptr;
269 }
270
271 DLLLOCAL const QoreTypeInfo* parseGetTypeInfoForInitialAssignment();
272
273 DLLLOCAL const QoreTypeInfo* parseGetTypeInfo();
274
275 DLLLOCAL const QoreTypeInfo* getTypeInfo() const;
276
277 DLLLOCAL bool hasTypeInfo() const;
278
279 DLLLOCAL bool isRef() const;
280
281 // only called with a new object declaration expression (ie our <class> $x())
282 DLLLOCAL const char* getClassName() const;
283
284 DLLLOCAL bool isPublic() const {
285 return pub;
286 }
287
288 DLLLOCAL void setPublic() {
289 assert(!pub);
290 pub = true;
291 }
292
293 DLLLOCAL const QoreProgramLocation* getParseLocation() const {
294 return loc;
295 }
296};
297
298DLLLOCAL void delete_global_variables();
299
300DLLLOCAL extern QoreHashNode* ENV;
301
302//typedef std::set<const void*> lvid_set_t;
303typedef vector_set_t<const void*> lvid_set_t;
304
305// track obj count changes
306hashdecl ObjCountRec {
307 // container
308 const AbstractQoreNode* con;
309 // initial count (true = possible recursive cycle, false = no cycle possible)
310 bool before;
311
312 DLLLOCAL ObjCountRec(const QoreListNode* c);
313 DLLLOCAL ObjCountRec(const QoreHashNode* c);
314 DLLLOCAL ObjCountRec(const QoreObject* c);
315 DLLLOCAL int getDifference();
316};
317
318typedef std::vector<ObjCountRec> ocvec_t;
319
320// this class grabs global variable or object locks for the duration of the scope of the object
321// no evaluations can be done while this object is in scope or a deadlock may result
322class LValueHelper {
323 friend class LValueRemoveHelper;
324 friend class LValueLockHandoffHelper;
325
326private:
327 // not implemented
328 DLLLOCAL LValueHelper(const LValueHelper&) = delete;
329 DLLLOCAL LValueHelper& operator=(const LValueHelper&) = delete;
330
331protected:
332 DLLLOCAL void assignNodeIntern(AbstractQoreNode* n) {
333 //printd(5, "LValueHelper::assignNodeIntern() this: %p n: %p '%s'\n", this, n, get_type_name(n));
334
335 assert(val || qv);
336 if (val)
337 val->assign(n);
338 else
339 *qv = n;
340 }
341
342 DLLLOCAL int doListLValue(const QoreSquareBracketsOperatorNode* op, bool for_remove);
343 DLLLOCAL int doHashLValue(qore_type_t t, const char* mem, bool for_remove);
344 DLLLOCAL int doObjLValue(QoreObject* o, const char* mem, bool for_remove);
345 DLLLOCAL int doHashObjLValue(const QoreHashObjectDereferenceOperatorNode* op, bool for_remove);
346
347 DLLLOCAL int makeIntQv(const char* desc);
348 DLLLOCAL int makeIntVal(const char* desc);
349
350 DLLLOCAL int makeFloat(const char* desc);
351 DLLLOCAL int makeNumber(const char* desc);
352
353 DLLLOCAL int doRecursiveException() {
354 vl.xsink->raiseException("REFERENCE-ERROR", "recursive reference detected in assignment");
355 return -1;
356 }
357
358public:
359 AutoVLock vl;
360
361private:
362 typedef std::vector<AbstractQoreNode*> nvec_t;
363 nvec_t tvec;
364 lvid_set_t* lvid_set = nullptr;
365 // to track object count changes
366 ocvec_t ocvec;
367
368 // flag if the changed value was a container before the assignment
369 bool before = false;
370
371 // recursive delta: change to recursive reference count
372 int rdt = 0;
373
374 RObject* robj = nullptr;
375
376public:
377 QoreLValueGeneric* val = nullptr;
378 QoreValue* qv = nullptr;
379 const QoreTypeInfo* typeInfo = nullptr;
380
381 DLLLOCAL LValueHelper(const ReferenceNode& ref, ExceptionSink* xsink, bool for_remove = false);
382 DLLLOCAL LValueHelper(const QoreValue& exp, ExceptionSink* xsink, bool for_remove = false);
383
384 DLLLOCAL LValueHelper(ExceptionSink* xsink);
385
386 DLLLOCAL LValueHelper(LValueHelper&& o);
387
388 // to scan objects after initialization
389 DLLLOCAL LValueHelper(QoreObject& obj, ExceptionSink* xsink);
390
391 DLLLOCAL ~LValueHelper();
392
393 DLLLOCAL int set(const ReferenceNode& ref, bool for_remove = false);
394
395 DLLLOCAL void setClosure(RObject* c) {
396 robj = c;
397 }
398
399 DLLLOCAL void saveTemp(QoreValue n);
400
401 DLLLOCAL void saveTempRef(QoreValue& n);
402
403 DLLLOCAL int doLValue(const QoreValue& exp, bool for_remove);
404
405 DLLLOCAL int doLValue(const ReferenceNode* ref, bool for_remove);
406
407 DLLLOCAL void setAndLock(QoreVarRWLock& rwl);
408 DLLLOCAL void set(QoreVarRWLock& rwl);
409
410 DLLLOCAL AutoVLock& getAutoVLock() {
411 return vl;
412 }
413
414 DLLLOCAL void setTypeInfo(const QoreTypeInfo* ti) {
415 typeInfo = ti;
416 }
417
418 DLLLOCAL void setValue(QoreLValueGeneric& nv, const QoreTypeInfo* ti = nullptr) {
419 //printd(5, "LValueHelper::setValue() this: %p new val: %p\n", this, &nv);
420 assert(!val);
421 assert(!qv);
422 val = &nv;
423
424 before = nv.assigned && nv.type == QV_Node ? needs_scan(nv.v.n) : false;
425
426 typeInfo = ti;
427 }
428
429 DLLLOCAL void setValue(QoreValue& nqv, const QoreTypeInfo* ti = nullptr) {
430 //printd(5, "LValueHelper::setValue() this: %p new qv: %p\n", this, &nqv);
431 assert(!val);
432 assert(!qv);
433 qv = &nqv;
434
435 before = needs_scan(nqv);
436
437 typeInfo = ti;
438 }
439
440 DLLLOCAL void resetValue(QoreLValueGeneric& nv, const QoreTypeInfo* ti = nullptr) {
441 //printd(5, "LValueHelper::resetValue() this: %p new val: %p\n", this, &nv);
442 if (qv) {
443 qv = nullptr;
444 } else {
445 assert(val);
446 }
447 val = &nv;
448
449 before = nv.assigned && nv.type == QV_Node ? needs_scan(nv.v.n) : false;
450
451 typeInfo = ti;
452 }
453
454 DLLLOCAL void resetValue(QoreValue& nqv, const QoreTypeInfo* ti = nullptr) {
455 //printd(5, "LValueHelper::resetValue() this: %p new qv: %p\n", this, &nqv);
456 if (val) {
457 val = nullptr;
458 } else {
459 assert(qv);
460 }
461 qv = &nqv;
462
463 before = needs_scan(nqv);
464
465 typeInfo = ti;
466 }
467
468 DLLLOCAL void clearPtr() {
469 if (val) {
470 val = nullptr;
471 } else if (qv) {
472 qv = nullptr;
473 }
474 typeInfo = nullptr;
475 before = false;
476 }
477
478 DLLLOCAL operator bool() const {
479 return val || qv;
480 }
481
482 DLLLOCAL bool isOptimized() const {
483 return val && val->optimized();
484 }
485
486 DLLLOCAL const QoreTypeInfo* getTypeInfo() const {
487 return typeInfo;
488 }
489
490 DLLLOCAL qore_type_t getType() const {
491 return val ? val->getType() : qv->getType();
492 }
493
494 DLLLOCAL const ReferenceNode* getReference() const {
495 if (val) {
496 return val->getReference();
497 }
498 assert(qv);
499 return qv->getType() == NT_REFERENCE ? qv->get<const ReferenceNode>() : nullptr;
500 }
501
502 DLLLOCAL const QoreValue getValue() const {
503 return val ? val->getValue() : *qv;
504 }
505
506 DLLLOCAL QoreValue getValue() {
507 return val ? val->getValue() : *qv;
508 }
509
510 DLLLOCAL AbstractQoreNode* getNodeValue() {
511 assert((val && val->getInternalNode()) || (qv && qv->getInternalNode()));
512 return val ? val->getInternalNode() : qv->getInternalNode();
513 }
514
515 DLLLOCAL const char* getTypeName() const {
516 return val ? val->getTypeName() : qv->getTypeName();
517 }
518
519 DLLLOCAL bool checkType(const qore_type_t t) const {
520 return getType() == t;
521 }
522
523 DLLLOCAL bool isNothing() const {
524 return checkType(NT_NOTHING);
525 }
526
527 DLLLOCAL void setObjectContext(qore_object_private* obj);
528
529 DLLLOCAL QoreValue getReferencedValue() const;
530
531 // only call if there is a reference-counted AbstractQoreNode value in place
532 // FIXME: port operators to LValueHelper instead and remove this function
533 DLLLOCAL void ensureUnique() {
534 AbstractQoreNode* current_value = getNodeValue();
535 assert(current_value && current_value->getType() != NT_OBJECT);
536
537 if (!current_value->is_unique()) {
538 //printd(5, "LValueHelper::ensureUnique() this: %p saving old value: %p '%s'\n", this, current_value, get_type_name(current_value));
539 AbstractQoreNode* old = current_value;
540 assignNodeIntern(current_value->realCopy());
541 saveTemp(old);
542 }
543 }
544
545 DLLLOCAL int64 getAsBigInt() const;
546 DLLLOCAL bool getAsBool() const;
547 DLLLOCAL double getAsFloat() const;
548
549 DLLLOCAL int64 plusEqualsBigInt(int64 v, const char* desc = "<lvalue>");
550 DLLLOCAL int64 minusEqualsBigInt(int64 v, const char* desc = "<lvalue>");
551 DLLLOCAL int64 multiplyEqualsBigInt(int64 v, const char* desc = "<lvalue>");
552 DLLLOCAL int64 divideEqualsBigInt(int64 v, const char* desc = "<lvalue>");
553 DLLLOCAL int64 orEqualsBigInt(int64 v, const char* desc = "<lvalue>");
554 DLLLOCAL int64 andEqualsBigInt(int64 v, const char* desc = "<lvalue>");
555 DLLLOCAL int64 xorEqualsBigInt(int64 v, const char* desc = "<lvalue>");
556 DLLLOCAL int64 modulaEqualsBigInt(int64 v, const char* desc = "<lvalue>");
557 DLLLOCAL int64 shiftLeftEqualsBigInt(int64 v, const char* desc = "<lvalue>");
558 DLLLOCAL int64 shiftRightEqualsBigInt(int64 v, const char* desc = "<lvalue>");
559 DLLLOCAL int64 preIncrementBigInt(const char* desc = "<lvalue>");
560 DLLLOCAL int64 preDecrementBigInt(const char* desc = "<lvalue>");
561 DLLLOCAL int64 postIncrementBigInt(const char* desc = "<lvalue>");
562 DLLLOCAL int64 postDecrementBigInt(const char* desc = "<lvalue>");
563
564 DLLLOCAL double plusEqualsFloat(double v, const char* desc = "<lvalue>");
565 DLLLOCAL double minusEqualsFloat(double v, const char* desc = "<lvalue>");
566 DLLLOCAL double multiplyEqualsFloat(double v, const char* desc = "<lvalue>");
567 DLLLOCAL double divideEqualsFloat(double v, const char* desc = "<lvalue>");
568 DLLLOCAL double preIncrementFloat(const char* desc = "<lvalue>");
569 DLLLOCAL double preDecrementFloat(const char* desc = "<lvalue>");
570 DLLLOCAL double postIncrementFloat(const char* desc = "<lvalue>");
571 DLLLOCAL double postDecrementFloat(const char* desc = "<lvalue>");
572
573 DLLLOCAL void plusEqualsNumber(QoreValue r, const char* desc = "<lvalue>");
574 DLLLOCAL void minusEqualsNumber(QoreValue r, const char* desc = "<lvalue>");
575 DLLLOCAL void multiplyEqualsNumber(QoreValue r, const char* desc = "<lvalue>");
576 DLLLOCAL void divideEqualsNumber(QoreValue r, const char* desc = "<lvalue>");
577 DLLLOCAL void preIncrementNumber(const char* desc = "<lvalue>");
578 DLLLOCAL void preDecrementNumber(const char* desc = "<lvalue>");
579 DLLLOCAL QoreNumberNode* postIncrementNumber(bool ref_rv, const char* desc = "<lvalue>");
580 DLLLOCAL QoreNumberNode* postDecrementNumber(bool ref_rv, const char* desc = "<lvalue>");
581
582 DLLLOCAL QoreNumberNode* ensureUniqueNumber(const char* desc = "<lvalue>") {
584 if (val) {
585 if (makeNumber(desc))
586 return nullptr;
587 p = &val->v.n;
588 }
589 else {
590 assert(qv);
591 if (makeNumber(desc))
592 return nullptr;
593 p = &qv->v.n;
594 }
595
596 assert(get_node_type(*p) == NT_NUMBER);
597 if (!(*p)->is_unique()) {
598 AbstractQoreNode* old = (*p);
599 (*p) = (*p)->realCopy();
600 saveTemp(old);
601 }
602 return reinterpret_cast<QoreNumberNode*>(*p);
603 }
604
605 DLLLOCAL int assign(QoreValue val, const char* desc = "<lvalue>", bool check_types = true, bool weak_assignment = false);
606
607 DLLLOCAL QoreValue removeValue(bool for_del);
608 DLLLOCAL QoreValue remove(bool& static_assignment);
609
610 DLLLOCAL void setDelta(int dt) {
611 assert(!rdt);
612 rdt = dt;
613 }
614};
615
616class LValueRemoveHelper {
617private:
618 // not implemented
619 LValueRemoveHelper(const LValueRemoveHelper&) = delete;
620 LValueRemoveHelper& operator=(const LValueRemoveHelper&) = delete;
621 void* operator new(size_t) = delete;
622
623 DLLLOCAL void doRemove(const QoreSquareBracketsOperatorNode* op);
624 DLLLOCAL void doRemove(const QoreSquareBracketsOperatorNode* op, const QoreParseListNode* l);
625 DLLLOCAL void doRemove(const QoreSquareBracketsRangeOperatorNode* op);
626
627protected:
628 ExceptionSink* xsink;
629 QoreLValueGeneric rv;
630 bool for_del,
631 direct_list = false;
632
633public:
634 DLLLOCAL LValueRemoveHelper(const ReferenceNode& ref, ExceptionSink* n_xsink, bool fd);
635 DLLLOCAL LValueRemoveHelper(const QoreValue& exp, ExceptionSink* n_xsink, bool fd);
636
637 DLLLOCAL void doRemove(QoreValue exp);
638
639 DLLLOCAL operator bool() const {
640 return !*xsink;
641 }
642
643 DLLLOCAL ExceptionSink* getExceptionSink() const {
644 return xsink;
645 }
646
647 DLLLOCAL bool forDel() const {
648 return for_del;
649 }
650
651 DLLLOCAL void doRemove(QoreLValueGeneric& qv, const QoreTypeInfo* ti) {
652 QoreProgram* pgm = getProgram();
653 // when Qore is terminating, this may be nullptr
654 if (pgm && (pgm->getParseOptions64() & PO_STRICT_TYPES)) {
655 rv.assignSetTakeInitial(qv, QoreTypeInfo::getDefaultQoreValue(ti));
656 } else {
657 rv.assignSetTakeInitial(qv);
658 }
659 }
660
661 DLLLOCAL QoreValue removeValue();
662 DLLLOCAL QoreValue remove(bool& static_assignment);
663
664 DLLLOCAL void deleteLValue();
665};
666
667hashdecl lvinfo {
668 QoreLValueGeneric* val;
669 const QoreTypeInfo* typeInfo;
670
671 DLLLOCAL lvinfo(QoreLValueGeneric* val, const QoreTypeInfo* typeInfo) : val(val), typeInfo(typeInfo) {
672 }
673};
674
675#endif // _QORE_VARIABLE_H
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:324
#define PO_STRICT_TYPES
enforce strict type checking and setting default values
Definition: Restrictions.h:98
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
virtual DLLEXPORT AbstractQoreNode * realCopy() const =0
returns a copy of the object; the caller owns the reference count
DLLLOCAL qore_type_t getType() const
returns the data type
Definition: AbstractQoreNode.h:175
AutoVLock is a container for safely managing global variable and object lock handovers,...
Definition: AutoVLock.h:80
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
This is the hash or associative list container type in Qore, dynamically allocated only,...
Definition: QoreHashNode.h:51
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
Qore's arbitrary-precision number value type, dynamically-allocated only, reference counted.
Definition: QoreNumberNode.h:51
the implementation of Qore's object data type, reference counted, dynamically-allocated only
Definition: QoreObject.h:61
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:128
DLLEXPORT int64 getParseOptions64() const
returns the parse options currently set for this program
provides atomic reference counting to Qore objects
Definition: QoreReferenceCounter.h:44
DLLEXPORT bool is_unique() const
returns true if the reference count is 1
qore_value_u v
the actual value is stored here
Definition: QoreValue.h:116
DLLLOCAL detail::QoreValueCastHelper< T >::Result get()
returns the value as the given type
Definition: QoreValue.h:214
DLLEXPORT AbstractQoreNode * getInternalNode()
returns any AbstractQoreNode value held; if type != QV_Node, returns nullptr
DLLEXPORT qore_type_t getType() const
returns the type of value contained
DLLEXPORT const char * getTypeName() const
returns a string type description of the value contained (ex: "nothing" for a null AbstractQoreNode p...
parse type: reference to a lvalue expression
Definition: ReferenceNode.h:45
holds an object and dereferences it in the destructor
Definition: QoreValue.h:487
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode)
Definition: common.h:70
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
#define QV_Node
for heap-allocated values
Definition: QoreValue.h:46
#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
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
const qore_type_t NT_REFERENCE
type value for ReferenceNode
Definition: node_types.h:64
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:279
AbstractQoreNode * n
for all heap-allocated values
Definition: QoreValue.h:60