32#ifndef _QORE_LOCALVAR_H
34#define _QORE_LOCALVAR_H
36#include "qore/intern/qore_thread_intern.h"
37#include "qore/intern/QoreLValue.h"
38#include "qore/intern/RSection.h"
39#include "qore/intern/RSet.h"
40#include "qore/ReferenceNode.h"
41#include "qore/intern/WeakReferenceNode.h"
42#include "qore/intern/WeakHashReferenceNode.h"
43#include "qore/intern/WeakListReferenceNode.h"
48class LocalRefHelper :
public RuntimeReferenceHelper {
55 : RuntimeReferenceHelper(ref, xsink),
59 DLLLOCAL
operator bool()
const {
65class LValueRefHelper :
public LocalRefHelper<T> {
70 DLLLOCAL LValueRefHelper(T* val,
ExceptionSink* xsink) : LocalRefHelper<T>(val, xsink),
71 valp(this->valid ? new LValueHelper(*((
ReferenceNode*)val->v.n), xsink) : nullptr) {
74 DLLLOCAL ~LValueRefHelper() {
78 DLLLOCAL
operator bool()
const {
82 DLLLOCAL LValueHelper* operator->() {
91 xsink->
raiseException(
"DESTRUCTOR-ERROR",
"illegal variable assignment after second phase of variable "
99 QoreLValueGeneric val;
102 bool frame_boundary : 1;
104 DLLLOCAL VarValueBase(
const char* n_id, valtype_t t =
QV_Node) : val(t), id(n_id), finalized(false), frame_boundary(false) {
107 DLLLOCAL VarValueBase(
const char* n_id,
const QoreTypeInfo* varTypeInfo) : val(varTypeInfo), id(n_id), finalized(false), frame_boundary(false) {
110 DLLLOCAL VarValueBase() : val(
QV_Bool), id(nullptr), finalized(false), frame_boundary(false) {
113 DLLLOCAL
void setFrameBoundary() {
114 assert(!frame_boundary);
115 frame_boundary =
true;
119 val.removeValue(
true).discard(xsink);
122 DLLLOCAL
bool isRef()
const {
132 return val.removeValue(
true);
136class LocalVarValue :
public VarValueBase {
138 DLLLOCAL
void set(
const char* n_id,
const QoreTypeInfo* varTypeInfo,
QoreValue nval,
bool assign,
139 bool static_assignment) {
147 val.set(varTypeInfo);
152 discard(val.assignAssumeInitial(nval, static_assignment),
nullptr);
154 assert(!val.assigned);
163 DLLLOCAL
void uninstantiateSelf() {
164 val.unassignIgnore();
167 DLLLOCAL
int getLValue(LValueHelper& lvh,
bool for_remove,
const QoreTypeInfo* typeInfo,
168 const QoreTypeInfo* refTypeInfo)
const;
169 DLLLOCAL
void remove(LValueRemoveHelper& lvrh,
const QoreTypeInfo* typeInfo);
176 LocalRefHelper<LocalVarValue> helper(
this, *ref, xsink);
181 return erh.takeValue(needs_deref);
186 return val.get<WeakReferenceNode>()->get();
191 return val.get<WeakHashReferenceNode>()->get();
196 return val.get<WeakListReferenceNode>()->get();
199 return val.getReferencedValue(needs_deref);
205 LocalRefHelper<LocalVarValue> helper(
this, *ref, xsink);
210 return *xsink ?
QoreValue() : erh.takeReferencedValue();
214 return val.get<WeakReferenceNode>()->get()->refSelf();
218 return val.get<WeakHashReferenceNode>()->get()->refSelf();
222 return val.get<WeakListReferenceNode>()->get()->refSelf();
225 return val.getReferencedValue();
229hashdecl ClosureVarValue :
public VarValueBase,
public RObject {
231 const QoreTypeInfo* typeInfo =
nullptr;
232 const QoreTypeInfo* refTypeInfo;
234 mutable std::atomic_int references;
236 DLLLOCAL ClosureVarValue(
const char* n_id,
const QoreTypeInfo* varTypeInfo,
QoreValue& nval,
bool assign) : VarValueBase(n_id, varTypeInfo), RObject(references), typeInfo(varTypeInfo), refTypeInfo(QoreTypeInfo::getReferenceTarget(varTypeInfo)), references(1) {
241 val.set(varTypeInfo);
246 discard(val.assignAssumeInitial(nval),
nullptr);
249 assert(!val.assigned);
253 DLLLOCAL
virtual ~ClosureVarValue() {
257 DLLLOCAL
void ref()
const;
261 DLLLOCAL
const void* getLValueId()
const;
264 DLLLOCAL
virtual bool needsScan(
bool scan_now) {
265 return QoreTypeInfo::needsScan(typeInfo);
268 DLLLOCAL
virtual bool scanMembers(RSetHelper& rsh);
270 DLLLOCAL
int getLValue(LValueHelper& lvh,
bool for_remove)
const;
271 DLLLOCAL
void remove(LValueRemoveHelper& lvrh);
273 DLLLOCAL ClosureVarValue* refSelf()
const {
275 return const_cast<ClosureVarValue*
>(
this);
280 QoreSafeVarRWWriteLocker sl(rml);
281 return VarValueBase::finalize();
285 QoreSafeVarRWReadLocker sl(rml);
289 LocalRefHelper<ClosureVarValue> helper(
this, **ref, xsink);
290 return helper ? lvalue_ref::get(*ref)->vexp.eval(needs_deref, xsink) :
QoreValue();
295 return val.get<WeakReferenceNode>()->get();
300 return val.get<WeakHashReferenceNode>()->get();
305 return val.get<WeakListReferenceNode>()->get();
308 return val.getReferencedValue();
312 QoreSafeVarRWReadLocker sl(rml);
316 LocalRefHelper<ClosureVarValue> helper(
this, **ref, xsink);
317 return helper ? lvalue_ref::get(*ref)->vexp.eval(xsink) :
QoreValue();
321 return val.get<WeakReferenceNode>()->get()->refSelf();
325 return val.get<WeakHashReferenceNode>()->get();
329 return val.get<WeakListReferenceNode>()->get();
332 return val.getReferencedValue();
335 DLLLOCAL
AbstractQoreNode* getReference(
const QoreProgramLocation* loc,
const char* name,
const void*& lvalue_id);
338 DLLLOCAL
virtual void deleteObject() {
343 DLLLOCAL
virtual const char* getName()
const {
351 DLLLOCAL LocalVar(
const char* n_name,
const QoreTypeInfo* ti)
352 : name(n_name), typeInfo(ti), refTypeInfo(QoreTypeInfo::getReferenceTarget(ti)) {
355 DLLLOCAL LocalVar(
const LocalVar& old) : name(old.name), closure_use(old.closure_use),
356 parse_assigned(old.parse_assigned), is_self(old.is_self), typeInfo(old.typeInfo),
357 refTypeInfo(old.refTypeInfo) {
360 DLLLOCAL ~LocalVar() {
363 DLLLOCAL
void parseAssigned() {
364 if (!parse_assigned) {
365 parse_assigned =
true;
369 DLLLOCAL
void parseUnassigned() {
370 if (parse_assigned) {
371 parse_assigned =
false;
375 DLLLOCAL
bool isAssigned()
const {
376 return parse_assigned;
379 DLLLOCAL
void instantiate(
int64 parse_options) {
383 instantiateIntern(QoreTypeInfo::getDefaultQoreValue(typeInfo),
true);
391 DLLLOCAL
void instantiate(
QoreValue nval) {
392 instantiateIntern(nval,
true);
395 DLLLOCAL
void instantiateIntern(
QoreValue nval,
bool assign) {
402 LocalVarValue* val = thread_instantiate_lvar();
403 val->set(name.c_str(), typeInfo, nval, assign,
false);
405 thread_instantiate_closure_var(name.c_str(), typeInfo, nval, assign);
409 DLLLOCAL
void instantiateSelf(
QoreObject* value)
const {
410 printd(5,
"LocalVar::instantiateSelf(%p) this: %p '%s'\n", value,
this, name.c_str());
412 LocalVarValue* val = thread_instantiate_lvar();
413 val->set(name.c_str(), typeInfo, value,
true,
true);
416 thread_instantiate_closure_var(name.c_str(), typeInfo, val,
true);
425 thread_uninstantiate_lvar(xsink);
427 thread_uninstantiate_closure_var(xsink);
431 DLLLOCAL
void uninstantiateSelf()
const {
433 thread_uninstantiate_self();
435 thread_uninstantiate_closure_var(
nullptr);
441 LocalVarValue* val = get_var();
444 return val->eval(needs_deref, xsink);
447 ClosureVarValue* val = thread_find_closure_var(name.c_str());
448 return val->eval(needs_deref, xsink);
452 DLLLOCAL
bool needsScan()
const {
453 return QoreTypeInfo::needsScan(typeInfo);
456 DLLLOCAL
const char* getName()
const {
460 DLLLOCAL
const std::string& getNameStr()
const {
464 DLLLOCAL
void setClosureUse() {
468 DLLLOCAL
bool closureUse()
const {
472 DLLLOCAL
bool isRef()
const {
473 return !closure_use ? get_var()->isRef() : thread_find_closure_var(name.c_str())->isRef();
476 DLLLOCAL
int getLValue(LValueHelper& lvh,
bool for_remove,
bool initial_assignment)
const {
480 return get_var()->getLValue(lvh, for_remove, typeInfo, refTypeInfo);
483 return thread_find_closure_var(name.c_str())->getLValue(lvh, for_remove);
486 DLLLOCAL
void remove(LValueRemoveHelper& lvrh) {
488 return get_var()->remove(lvrh, typeInfo);
491 return thread_find_closure_var(name.c_str())->remove(lvrh);
494 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
498 DLLLOCAL
const QoreTypeInfo* parseGetTypeInfo()
const {
499 return parse_assigned && refTypeInfo ? refTypeInfo : typeInfo;
502 DLLLOCAL
const QoreTypeInfo* parseGetTypeInfoForInitialAssignment()
const {
507 return !closure_use ? get_var()->val.getType() : thread_find_closure_var(name.c_str())->val.getType();
510 DLLLOCAL
const char* getValueTypeName()
const {
511 return !closure_use ? get_var()->val.getTypeName() : thread_find_closure_var(name.c_str())->val.getTypeName();
514 DLLLOCAL
bool isSelf()
const {
518 DLLLOCAL
void setSelf() {
520 assert(name ==
"self");
526 bool closure_use =
false,
527 parse_assigned =
false,
529 const QoreTypeInfo* typeInfo =
nullptr;
530 const QoreTypeInfo* refTypeInfo =
nullptr;
532 DLLLOCAL LocalVarValue* get_var()
const {
533 return thread_find_lvar(name.c_str());
537typedef LocalVar* lvar_ptr_t;
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
DLLEXPORT AbstractQoreNode * refSelf() const
returns "this" with an incremented reference count
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
the implementation of Qore's object data type, reference counted, dynamically-allocated only
Definition QoreObject.h:61
a templated class to manage a reference count of an object that can throw a Qore-language exception w...
Definition ReferenceHolder.h:52
parse type: reference to a lvalue expression
Definition ReferenceNode.h:45
DLLEXPORT ReferenceNode * refRefSelf() const
returns a reference to itself
evaluates an AbstractQoreNode and dereferences the stored value in the destructor
Definition QoreValue.h:672
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode)
Definition common.h:76
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition common.h:266
#define QV_Node
for heap-allocated values
Definition QoreValue.h:46
#define QV_Bool
for boolean values
Definition QoreValue.h:43
const qore_type_t NT_WEAKREF_LIST
type value for WeakListReferenceNode
Definition node_types.h:91
const qore_type_t NT_WEAKREF
type value for WeakReferenceNode
Definition node_types.h:87
const qore_type_t NT_WEAKREF_HASH
type value for WeakHashReferenceNode
Definition node_types.h:90
const qore_type_t NT_REFERENCE
type value for ReferenceNode
Definition node_types.h:64
The main value class in Qore, designed to be passed by value.
Definition QoreValue.h:279