Qore Programming Language  1.12.0
FunctionList.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  FunctionList.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_FUNCTIONLIST_H
33 
34 #define _QORE_FUNCTIONLIST_H
35 
36 #include <qore/common.h>
37 
38 #include "qore/intern/Function.h"
39 
40 #include <map>
41 #include <string>
42 
43 class qore_ns_private;
44 
45 // function calls are handled with FunctionCallNode
46 class FunctionEntry : public QoreReferenceCounter {
47  friend class FunctionList;
48 
49 private:
50  // not implemented
51  FunctionEntry(const FunctionEntry& old) = delete;
52 
53 protected:
54  QoreFunction* func;
55  std::string name;
56  qore_ns_private* ns;
57 
58  DLLLOCAL ~FunctionEntry() {
59  func->deref();
60  }
61 
62 public:
63  DLLLOCAL FunctionEntry(QoreFunction* u, qore_ns_private* ns) : func(u), ns(ns) {
64  }
65 
66  DLLLOCAL FunctionEntry(const char* new_name, QoreFunction* u, qore_ns_private* ns)
67  : func(u), name(new_name), ns(ns) {
68  }
69 
70  DLLLOCAL void ref() {
71  ROreference();
72  }
73 
74  DLLLOCAL bool deref() {
75  if (ROdereference()) {
76  delete this;
77  return true;
78  }
79  return false;
80  }
81 
82  DLLLOCAL qore_ns_private* getNamespace() const {
83  return ns;
84  }
85 
86  DLLLOCAL QoreFunction* getFunction() const {
87  return func;
88  }
89 
90  DLLLOCAL QoreFunction* getFunction(bool runtime) const {
91  if (runtime && func->committedEmpty())
92  return nullptr;
93  return func;
94  }
95 
96  DLLLOCAL const char* getName() const {
97  return name.empty() ? func->getName() : name.c_str();
98  }
99 
100  DLLLOCAL int parseInit() {
101  return func->parseInit(ns);
102  }
103 
104  DLLLOCAL void parseCommit() {
105  func->parseCommit();
106  }
107 
108  // returns -1 if the entry can be deleted
109  DLLLOCAL int parseRollback() {
110  // if there are no committed variants, then return -1 to erase the function entry entirely
111  if (func->committedEmpty())
112  return -1;
113 
114  // otherwise just roll back the pending variants
115  func->parseRollback();
116  return 0;
117  }
118 
119  DLLLOCAL ResolvedCallReferenceNode* makeCallReference(const QoreProgramLocation* loc) const;
120 
121  DLLLOCAL bool isPublic() const {
122  return func->hasPublic();
123  }
124 
125  DLLLOCAL bool isUserPublic() const {
126  return func->hasUserPublic();
127  }
128 
129  DLLLOCAL bool hasBuiltin() const {
130  return func->hasBuiltin();
131  }
132 
133  DLLLOCAL void updateNs(qore_ns_private* ns) {
134  this->ns = ns;
135  }
136 };
137 
138 class ModuleImportedFunctionEntry : public FunctionEntry {
139 public:
140  DLLLOCAL ModuleImportedFunctionEntry(const FunctionEntry& old, qore_ns_private* ns);
141 };
142 
143 #ifdef HAVE_QORE_HASH_MAP
144 //#warning compiling with hash_map
145 #include <qore/hash_map_include.h>
146 #include "qore/intern/xxhash.h"
147 
148 typedef HASH_MAP<const char*, FunctionEntry*, qore_hash_str, eqstr> fl_map_t;
149 #else
150 typedef std::map<const char*, FunctionEntry*> fl_map_t;
151 #endif
152 
153 class FunctionList : public fl_map_t {
154 public:
155  DLLLOCAL FunctionList() {
156  }
157 
158  DLLLOCAL FunctionList(const FunctionList& old, qore_ns_private* ns, int64 po);
159 
160  DLLLOCAL ~FunctionList() {
161  del();
162  }
163 
164  DLLLOCAL FunctionEntry* add(QoreFunction* func, qore_ns_private* ns);
165  DLLLOCAL FunctionEntry* import(QoreFunction* func, qore_ns_private* ns);
166  DLLLOCAL FunctionEntry* import(const char* new_name, QoreFunction* func, qore_ns_private* ns, bool inject);
167  DLLLOCAL QoreFunction* find(const char* name, bool runtime) const;
168  DLLLOCAL FunctionEntry* findNode(const char* name, bool runtime = false) const;
169 
170  DLLLOCAL void mergeUserPublic(const FunctionList& src, qore_ns_private* ns) {
171  for (fl_map_t::const_iterator i = src.begin(), e = src.end(); i != e; ++i) {
172  if (!i->second->isUserPublic()) {
173  //printd(5, "FunctionList::mergePublic() this: %p SKIPPING %s!\n", this, i->first);
174  continue;
175  }
176 
177  assert(!findNode(i->first));
178  FunctionEntry* fe = new ModuleImportedFunctionEntry(*i->second, ns);
179  //printd(5, "FunctionList::mergePublic() this: %p merging in %s (%p)\n", this, i->first, fe);
180  assert(!fe->isUserPublic());
181  insert(fl_map_t::value_type(fe->getName(), fe));
182  }
183  }
184 
185  // returns the number of functions imported
186  DLLLOCAL int importSystemFunctions(const FunctionList& src, qore_ns_private* ns, ExceptionSink* xsink);
187 
188  DLLLOCAL void del();
189  DLLLOCAL int parseInit();
190  DLLLOCAL void parseRollback();
191  DLLLOCAL void parseCommit();
192  DLLLOCAL QoreListNode* getList();
193  DLLLOCAL void assimilate(FunctionList& fl, qore_ns_private* ns);
194 };
195 
196 #endif
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
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
DLLEXPORT void ROreference() const
atomically increments the reference count
DLLEXPORT bool ROdereference() const
atomically decrements the reference count
base class for resolved call references
Definition: CallReferenceNode.h:109
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