Qore Programming Language  0.9.16
CallReferenceNode.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  CallReferenceNode.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2020 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_INTERN_FUNCTIONREFERENCENODE_H
33 
34 #define _QORE_INTERN_FUNCTIONREFERENCENODE_H
35 
36 #include <string>
37 
39 
40 hashdecl CallReferenceNodeLocation {
41  const QoreProgramLocation* loc;
42 
43  DLLLOCAL CallReferenceNodeLocation(const QoreProgramLocation* loc) : loc(loc) {
44  }
45 };
46 
47 class AbstractCallReferenceNodeIntern : public AbstractCallReferenceNode, public CallReferenceNodeLocation {
48 public:
49  DLLLOCAL AbstractCallReferenceNodeIntern(const QoreProgramLocation* loc, bool n_needs_eval) :
50  AbstractCallReferenceNode(n_needs_eval), CallReferenceNodeLocation(loc) {
51  }
52 };
53 
54 class ResolvedCallReferenceNodeIntern : public ResolvedCallReferenceNode, public CallReferenceNodeLocation {
55 public:
56  DLLLOCAL ResolvedCallReferenceNodeIntern(const QoreProgramLocation* loc, bool n_needs_eval = false) :
57  ResolvedCallReferenceNode(n_needs_eval), CallReferenceNodeLocation(loc) {
58  }
59 };
60 
61 class AbstractUnresolvedCallReferenceNode : public AbstractCallReferenceNodeIntern {
62 public:
63  DLLLOCAL AbstractUnresolvedCallReferenceNode(const QoreProgramLocation* loc, bool n_needs_eval) : AbstractCallReferenceNodeIntern(loc, n_needs_eval) {
64  }
65 };
66 
68 class UnresolvedProgramCallReferenceNode : public AbstractUnresolvedCallReferenceNode {
69 public:
70  char* str;
71 
72  DLLLOCAL UnresolvedProgramCallReferenceNode(const QoreProgramLocation* loc, char* n_str);
73 
74  DLLLOCAL virtual ~UnresolvedProgramCallReferenceNode();
75 
76  DLLLOCAL virtual void parseInit(QoreValue& val, LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo);
77 };
78 
79 class UnresolvedCallReferenceNode : public UnresolvedProgramCallReferenceNode {
80 public:
81  DLLLOCAL UnresolvedCallReferenceNode(const QoreProgramLocation* loc, char* n_str) : UnresolvedProgramCallReferenceNode(loc, n_str) {
82  }
83 
84  DLLLOCAL virtual void parseInit(QoreValue& val, LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo);
85 };
86 
88 class LocalStaticMethodCallReferenceNode : public ResolvedCallReferenceNodeIntern {
89 protected:
90  const QoreMethod* method;
91 
92  // constructor for subclasses
93  DLLLOCAL LocalStaticMethodCallReferenceNode(const QoreProgramLocation* loc, const QoreMethod* n_method, bool n_needs_eval) : ResolvedCallReferenceNodeIntern(loc, n_needs_eval), method(n_method) {
94  }
95 
96  DLLLOCAL virtual QoreValue evalImpl(bool &needs_deref, ExceptionSink* xsink) const;
97 
98 public:
99  DLLLOCAL LocalStaticMethodCallReferenceNode(const QoreProgramLocation* loc, const QoreMethod* n_method) : ResolvedCallReferenceNodeIntern(loc, true), method(n_method) {
100  //printd(5, "LocalStaticMethodCallReferenceNode::LocalStaticMethodCallReferenceNode() this: %p %s::%s() pgm: %p\n", this, method->getClass()->getName(), method->getName(), pgm);
101  }
102 
103  DLLLOCAL virtual ~LocalStaticMethodCallReferenceNode() {
104  }
105 
106  DLLLOCAL virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const {
108  }
109 
110  DLLLOCAL virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
111 
112  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
113 
114  DLLLOCAL virtual QoreFunction* getFunction();
115 };
116 
117 class StaticMethodCallReferenceNode : public LocalStaticMethodCallReferenceNode {
118 protected:
119  QoreProgram* pgm;
120  const qore_class_private* class_ctx;
121 
122  DLLLOCAL virtual bool derefImpl(ExceptionSink* xsink);
123 
124 public:
125  DLLLOCAL StaticMethodCallReferenceNode(const QoreProgramLocation* loc, const QoreMethod *n_method, QoreProgram *n_pgm, const qore_class_private* n_class_ctx);
126 
127  DLLLOCAL ~StaticMethodCallReferenceNode() {
128  assert(!pgm);
129  }
130 
131  DLLLOCAL virtual QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const;
132 };
133 
136 protected:
137  DLLLOCAL virtual QoreValue evalImpl(bool &needs_deref, ExceptionSink* xsink) const;
138 
139  DLLLOCAL LocalMethodCallReferenceNode(const QoreProgramLocation* loc, const QoreMethod* n_method, bool n_needs_eval) : LocalStaticMethodCallReferenceNode(loc, n_method, n_needs_eval) {
140  //printd(5, "LocalMethodCallReferenceNode::LocalStaticMethodCallReferenceNode() this: %p %s::%s() pgm: %p\n", this, method->getClass()->getName(), method->getName(), pgm);
141  }
142 
143 public:
144  DLLLOCAL LocalMethodCallReferenceNode(const QoreProgramLocation* loc, const QoreMethod* n_method) : LocalStaticMethodCallReferenceNode(loc, n_method) {
145  //printd(5, "LocalMethodCallReferenceNode::LocalStaticMethodCallReferenceNode() this: %p %s::%s() pgm: %p\n", this, method->getClass()->getName(), method->getName(), pgm);
146  }
147 
148  DLLLOCAL virtual ~LocalMethodCallReferenceNode() {
149  }
150 
151  DLLLOCAL virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const {
153  }
154 
155  DLLLOCAL virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
156 
157  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
158 };
159 
160 class MethodCallReferenceNode : public LocalMethodCallReferenceNode {
161 protected:
162  QoreObject* obj;
163 
164  DLLLOCAL virtual bool derefImpl(ExceptionSink* xsink);
165 
166 public:
167  DLLLOCAL MethodCallReferenceNode(const QoreProgramLocation* loc, const QoreMethod* n_method, QoreProgram* n_pgm);
168 
169  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
170 };
171 
173 class LocalFunctionCallReferenceNode : public ResolvedCallReferenceNodeIntern {
174 public:
175  DLLLOCAL LocalFunctionCallReferenceNode(const QoreProgramLocation* loc, const QoreFunction* n_uf);
176 
177  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
178 
179  DLLLOCAL virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const {
181  }
182 
183  DLLLOCAL virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
184 
185  DLLLOCAL virtual QoreFunction* getFunction() {
186  return const_cast<QoreFunction*>(uf);
187  }
188 
189 protected:
190  const QoreFunction* uf;
191 
192  // constructor for subclasses
193  DLLLOCAL LocalFunctionCallReferenceNode(const QoreProgramLocation* loc, const QoreFunction* n_uf, bool n_needs_eval);
194 
195  DLLLOCAL virtual QoreValue evalImpl(bool &needs_deref, ExceptionSink* xsink) const;
196 };
197 
200 protected:
201  QoreProgram* pgm;
202 
203  DLLLOCAL virtual bool derefImpl(ExceptionSink* xsink);
204 
205 public:
206  DLLLOCAL FunctionCallReferenceNode(const QoreProgramLocation* loc, const QoreFunction* n_uf, QoreProgram* n_pgm) : LocalFunctionCallReferenceNode(loc, n_uf, false), pgm(n_pgm) {
207  assert(pgm);
208  // make a weak reference to the Program - a strong reference (QoreProgram::ref()) could cause a recursive reference
209  pgm->depRef();
210  }
211 
212  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
213 };
214 
216 class UnresolvedStaticMethodCallReferenceNode : public AbstractUnresolvedCallReferenceNode {
217 protected:
218  NamedScope* scope;
219 
220 public:
221  DLLLOCAL UnresolvedStaticMethodCallReferenceNode(const QoreProgramLocation* loc, NamedScope* n_scope);
222 
223  DLLLOCAL virtual ~UnresolvedStaticMethodCallReferenceNode();
224 
226  DLLLOCAL void deref() {
227  if (ROdereference())
228  delete this;
229  }
230 
231  DLLLOCAL virtual void parseInit(QoreValue& val, LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo);
232 };
233 
234 class ImportedFunctionEntry;
235 
237 class RunTimeObjectMethodReferenceNode : public ResolvedCallReferenceNodeIntern {
238 private:
239  QoreObject* obj;
240  std::string method;
241  const qore_class_private* qc;
242 
243  DLLLOCAL virtual ~RunTimeObjectMethodReferenceNode();
244 
245 public:
246  DLLLOCAL RunTimeObjectMethodReferenceNode(const QoreProgramLocation* loc, QoreObject* n_obj, const char* n_method);
247 
248  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
249 
250  DLLLOCAL virtual QoreProgram* getProgram() const;
251 
252  DLLLOCAL virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const {
254  }
255 
256  DLLLOCAL virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
257 
258  DLLLOCAL virtual QoreFunction* getFunction() {
259  // FIXME: implement type checking and method matching in ParseObjectMethodReferenceNode::parseInit()
260  return nullptr;
261  }
262 };
263 
265 // is known when the method reference node object is created
266 class RunTimeResolvedMethodReferenceNode : public ResolvedCallReferenceNodeIntern {
267 private:
268  QoreObject* obj;
269  const QoreMethod* method;
270  const qore_class_private* qc;
271 
272  DLLLOCAL virtual ~RunTimeResolvedMethodReferenceNode();
273 
274 public:
275  DLLLOCAL RunTimeResolvedMethodReferenceNode(const QoreProgramLocation* loc, QoreObject* n_obj,
276  const QoreMethod* n_method, const qore_class_private* ctx = runtime_get_class());
277 
278  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
279 
280  DLLLOCAL virtual QoreProgram* getProgram() const;
281 
282  DLLLOCAL virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const {
284  }
285 
286  DLLLOCAL virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
287 
288  DLLLOCAL virtual QoreFunction* getFunction();
289 };
290 
291 #endif
LocalStaticMethodCallReferenceNode::execValue
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
UnresolvedStaticMethodCallReferenceNode::parseInit
virtual DLLLOCAL void parseInit(QoreValue &val, LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&typeInfo)
for use by parse types to initialize them for execution during stage 1 parsing; not exported in the l...
QoreProgram
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:126
QoreValue
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:262
LocalMethodCallReferenceNode::is_equal_hard
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
RunTimeObjectMethodReferenceNode::is_equal_hard
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
LocalMethodCallReferenceNode
a call reference to a static user method
Definition: CallReferenceNode.h:135
RunTimeResolvedMethodReferenceNode::getProgram
virtual DLLLOCAL QoreProgram * getProgram() const
returns a pointer to the QoreProgram object associated with this reference (can be nullptr)
AbstractQoreNode::derefImpl
virtual DLLEXPORT bool derefImpl(ExceptionSink *xsink)
decrements the reference count
RunTimeObjectMethodReferenceNode
a run-time call reference to a method of a particular object
Definition: CallReferenceNode.h:237
LocalStaticMethodCallReferenceNode::is_equal_hard
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
FunctionCallReferenceNode::derefImpl
virtual DLLLOCAL bool derefImpl(ExceptionSink *xsink)
decrements the reference count
QoreListNode
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
UnresolvedStaticMethodCallReferenceNode
an unresolved static method call reference, only present temporarily in the parse tree
Definition: CallReferenceNode.h:216
LocalFunctionCallReferenceNode::evalImpl
virtual DLLLOCAL QoreValue evalImpl(bool &needs_deref, ExceptionSink *xsink) const
this function should never be called for function references; this function should never be called di...
LocalStaticMethodCallReferenceNode
a call reference to a static user method
Definition: CallReferenceNode.h:88
LocalMethodCallReferenceNode::execValue
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
LocalMethodCallReferenceNode::is_equal_soft
virtual DLLLOCAL bool is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
Definition: CallReferenceNode.h:151
RunTimeResolvedMethodReferenceNode::is_equal_hard
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
QoreReferenceCounter::ROdereference
DLLEXPORT bool ROdereference() const
atomically decrements the reference count
FunctionCallReferenceNode
a call reference to a user function
Definition: CallReferenceNode.h:199
LocalFunctionCallReferenceNode
a call reference to a user function from within the same QoreProgram object
Definition: CallReferenceNode.h:173
LocalFunctionCallReferenceNode::is_equal_soft
virtual DLLLOCAL bool is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
Definition: CallReferenceNode.h:179
RunTimeObjectMethodReferenceNode::execValue
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
LocalFunctionCallReferenceNode::is_equal_hard
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
QoreProgram::depRef
DLLEXPORT void depRef()
incremements the weak reference count for the program object
UnresolvedProgramCallReferenceNode::parseInit
virtual DLLLOCAL void parseInit(QoreValue &val, LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&typeInfo)
for use by parse types to initialize them for execution during stage 1 parsing; not exported in the l...
RunTimeObjectMethodReferenceNode::getProgram
virtual DLLLOCAL QoreProgram * getProgram() const
returns a pointer to the QoreProgram object associated with this reference (can be nullptr)
LocalFunctionCallReferenceNode::getFunction
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
Definition: CallReferenceNode.h:185
QoreObject
the implementation of Qore's object data type, reference counted, dynamically-allocated only
Definition: QoreObject.h:61
ExceptionSink
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
FunctionCallReferenceNode::execValue
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
RunTimeResolvedMethodReferenceNode::execValue
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
RunTimeObjectMethodReferenceNode::getFunction
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
Definition: CallReferenceNode.h:258
LocalStaticMethodCallReferenceNode::evalImpl
virtual DLLLOCAL QoreValue evalImpl(bool &needs_deref, ExceptionSink *xsink) const
this function should never be called for function references; this function should never be called di...
LocalMethodCallReferenceNode::evalImpl
virtual DLLLOCAL QoreValue evalImpl(bool &needs_deref, ExceptionSink *xsink) const
this function should never be called for function references; this function should never be called di...
UnresolvedProgramCallReferenceNode
an unresolved call reference, only present temporarily in the parse tree
Definition: CallReferenceNode.h:68
RunTimeResolvedMethodReferenceNode::is_equal_soft
virtual DLLLOCAL bool is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
Definition: CallReferenceNode.h:282
RunTimeResolvedMethodReferenceNode
a run-time call reference to a method of a particular object where the method's class
Definition: CallReferenceNode.h:266
RunTimeObjectMethodReferenceNode::is_equal_soft
virtual DLLLOCAL bool is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
Definition: CallReferenceNode.h:252
AbstractQoreNode::deref
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false,...
QoreMethod
a method in a QoreClass
Definition: QoreClass.h:125
RunTimeResolvedMethodReferenceNode::getFunction
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
ResolvedCallReferenceNode
base class for resolved call references
Definition: CallReferenceNode.h:105
LocalStaticMethodCallReferenceNode::is_equal_soft
virtual DLLLOCAL bool is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
Definition: CallReferenceNode.h:106
AbstractQoreNode
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
LocalFunctionCallReferenceNode::execValue
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
LocalStaticMethodCallReferenceNode::getFunction
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
AbstractCallReferenceNode
base class for call references, reference-counted, dynamically allocated only
Definition: CallReferenceNode.h:39