Qore Programming Language  1.12.0
CallReferenceNode.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  CallReferenceNode.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2022 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 int parseInit(QoreValue& val, QoreParseContext& parse_context);
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 int parseInit(QoreValue& val, QoreParseContext& parse_context);
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,
194  bool n_needs_eval);
195 
196  DLLLOCAL virtual QoreValue evalImpl(bool &needs_deref, ExceptionSink* xsink) const;
197 };
198 
201 protected:
202  QoreProgram* pgm;
203 
204  DLLLOCAL virtual bool derefImpl(ExceptionSink* xsink);
205 
206 public:
207  DLLLOCAL FunctionCallReferenceNode(const QoreProgramLocation* loc, const QoreFunction* n_uf,
208  QoreProgram* n_pgm) : LocalFunctionCallReferenceNode(loc, n_uf, false), pgm(n_pgm) {
209  assert(pgm);
210  // make a weak reference to the Program - a strong reference (QoreProgram::ref()) could cause a recursive
211  // reference
212  pgm->depRef();
213  }
214 
215  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
216 };
217 
219 class UnresolvedStaticMethodCallReferenceNode : public AbstractUnresolvedCallReferenceNode {
220 protected:
221  NamedScope* scope;
222 
223 public:
224  DLLLOCAL UnresolvedStaticMethodCallReferenceNode(const QoreProgramLocation* loc, NamedScope* n_scope);
225 
226  DLLLOCAL virtual ~UnresolvedStaticMethodCallReferenceNode();
227 
229  DLLLOCAL void deref() {
230  if (ROdereference())
231  delete this;
232  }
233 
234  DLLLOCAL virtual int parseInit(QoreValue& val, QoreParseContext& parse_context);
235 };
236 
237 class ImportedFunctionEntry;
238 
240 class RunTimeObjectMethodReferenceNode : public ResolvedCallReferenceNodeIntern {
241 private:
242  QoreObject* obj;
243  std::string method;
244  const qore_class_private* qc;
245 
246  DLLLOCAL virtual ~RunTimeObjectMethodReferenceNode();
247 
248 public:
249  DLLLOCAL RunTimeObjectMethodReferenceNode(const QoreProgramLocation* loc, QoreObject* n_obj,
250  const char* n_method);
251 
252  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
253 
254  DLLLOCAL virtual QoreProgram* getProgram() const;
255 
256  DLLLOCAL virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const {
258  }
259 
260  DLLLOCAL virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
261 
262  DLLLOCAL virtual QoreFunction* getFunction() {
263  // FIXME: implement type checking and method matching in ParseObjectMethodReferenceNode::parseInit()
264  return nullptr;
265  }
266 };
267 
269 // is known when the method reference node object is created
270 class RunTimeResolvedMethodReferenceNode : public ResolvedCallReferenceNodeIntern {
271 private:
272  QoreObject* obj;
273  const QoreMethod* method;
274  const qore_class_private* qc;
275 
276  DLLLOCAL virtual ~RunTimeResolvedMethodReferenceNode();
277 
278 public:
279  DLLLOCAL RunTimeResolvedMethodReferenceNode(const QoreProgramLocation* loc, QoreObject* n_obj,
280  const QoreMethod* n_method, const qore_class_private* ctx = runtime_get_class());
281 
282  DLLLOCAL virtual QoreValue execValue(const QoreListNode* args, ExceptionSink* xsink) const;
283 
284  DLLLOCAL virtual QoreProgram* getProgram() const;
285 
286  DLLLOCAL virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const {
288  }
289 
290  DLLLOCAL virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const;
291 
292  DLLLOCAL virtual QoreFunction* getFunction();
293 };
294 
295 #endif
base class for call references, reference-counted, dynamically allocated only
Definition: CallReferenceNode.h:39
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
virtual DLLEXPORT bool derefImpl(ExceptionSink *xsink)
decrements the reference count
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false,...
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
a call reference to a user function
Definition: CallReferenceNode.h:200
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
virtual DLLLOCAL bool derefImpl(ExceptionSink *xsink)
decrements the reference count
a call reference to a user function from within the same QoreProgram object
Definition: CallReferenceNode.h:173
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
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...
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
Definition: CallReferenceNode.h:185
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
a call reference to a static user method
Definition: CallReferenceNode.h:135
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
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
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...
a call reference to a static user method
Definition: CallReferenceNode.h:88
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...
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
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
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
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
DLLEXPORT void depRef()
incremements the weak reference count for the program object
DLLEXPORT bool ROdereference() const
atomically decrements the reference count
base class for resolved call references
Definition: CallReferenceNode.h:109
a run-time call reference to a method of a particular object
Definition: CallReferenceNode.h:240
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
Definition: CallReferenceNode.h:262
virtual DLLLOCAL QoreProgram * getProgram() const
returns a pointer to the QoreProgram object associated with this reference (can be nullptr)
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:256
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
a run-time call reference to a method of a particular object where the method's class
Definition: CallReferenceNode.h:270
virtual DLLLOCAL QoreProgram * getProgram() const
returns a pointer to the QoreProgram object associated with this reference (can be nullptr)
virtual DLLLOCAL QoreValue execValue(const QoreListNode *args, ExceptionSink *xsink) const
pure virtual function for executing the function reference
virtual DLLLOCAL QoreFunction * getFunction()
Returns the internal function object, if any; can return nullptr.
virtual DLLLOCAL bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const
returns true if the other node is the same value
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:286
an unresolved call reference, only present temporarily in the parse tree
Definition: CallReferenceNode.h:68
virtual DLLLOCAL int parseInit(QoreValue &val, QoreParseContext &parse_context)
for use by parse types to initialize them for execution during stage 1 parsing
an unresolved static method call reference, only present temporarily in the parse tree
Definition: CallReferenceNode.h:219
virtual DLLLOCAL int parseInit(QoreValue &val, QoreParseContext &parse_context)
for use by parse types to initialize them for execution during stage 1 parsing
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:275