jpayne@69
|
1 /*
|
jpayne@69
|
2 * tclOOInt.h --
|
jpayne@69
|
3 *
|
jpayne@69
|
4 * This file contains the structure definitions and some of the function
|
jpayne@69
|
5 * declarations for the object-system (NB: not Tcl_Obj, but ::oo).
|
jpayne@69
|
6 *
|
jpayne@69
|
7 * Copyright (c) 2006-2012 by Donal K. Fellows
|
jpayne@69
|
8 *
|
jpayne@69
|
9 * See the file "license.terms" for information on usage and redistribution of
|
jpayne@69
|
10 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
jpayne@69
|
11 */
|
jpayne@69
|
12
|
jpayne@69
|
13 #ifndef TCL_OO_INTERNAL_H
|
jpayne@69
|
14 #define TCL_OO_INTERNAL_H 1
|
jpayne@69
|
15
|
jpayne@69
|
16 #include "tclInt.h"
|
jpayne@69
|
17 #include "tclOO.h"
|
jpayne@69
|
18
|
jpayne@69
|
19 /*
|
jpayne@69
|
20 * Hack to make things work with Objective C. Note that ObjC isn't really
|
jpayne@69
|
21 * supported, but we don't want to to be actively hostile to it. [Bug 2163447]
|
jpayne@69
|
22 */
|
jpayne@69
|
23
|
jpayne@69
|
24 #ifdef __OBJC__
|
jpayne@69
|
25 #define Class TclOOClass
|
jpayne@69
|
26 #define Object TclOOObject
|
jpayne@69
|
27 #endif /* __OBJC__ */
|
jpayne@69
|
28
|
jpayne@69
|
29 /*
|
jpayne@69
|
30 * Forward declarations.
|
jpayne@69
|
31 */
|
jpayne@69
|
32
|
jpayne@69
|
33 struct CallChain;
|
jpayne@69
|
34 struct Class;
|
jpayne@69
|
35 struct Foundation;
|
jpayne@69
|
36 struct Object;
|
jpayne@69
|
37
|
jpayne@69
|
38 /*
|
jpayne@69
|
39 * The data that needs to be stored per method. This record is used to collect
|
jpayne@69
|
40 * information about all sorts of methods, including forwards, constructors
|
jpayne@69
|
41 * and destructors.
|
jpayne@69
|
42 */
|
jpayne@69
|
43
|
jpayne@69
|
44 typedef struct Method {
|
jpayne@69
|
45 const Tcl_MethodType *typePtr;
|
jpayne@69
|
46 /* The type of method. If NULL, this is a
|
jpayne@69
|
47 * special flag record which is just used for
|
jpayne@69
|
48 * the setting of the flags field. */
|
jpayne@69
|
49 int refCount;
|
jpayne@69
|
50 void *clientData; /* Type-specific data. */
|
jpayne@69
|
51 Tcl_Obj *namePtr; /* Name of the method. */
|
jpayne@69
|
52 struct Object *declaringObjectPtr;
|
jpayne@69
|
53 /* The object that declares this method, or
|
jpayne@69
|
54 * NULL if it was declared by a class. */
|
jpayne@69
|
55 struct Class *declaringClassPtr;
|
jpayne@69
|
56 /* The class that declares this method, or
|
jpayne@69
|
57 * NULL if it was declared directly on an
|
jpayne@69
|
58 * object. */
|
jpayne@69
|
59 int flags; /* Assorted flags. Includes whether this
|
jpayne@69
|
60 * method is public/exported or not. */
|
jpayne@69
|
61 } Method;
|
jpayne@69
|
62
|
jpayne@69
|
63 /*
|
jpayne@69
|
64 * Pre- and post-call callbacks, to allow procedure-like methods to be fine
|
jpayne@69
|
65 * tuned in their behaviour.
|
jpayne@69
|
66 */
|
jpayne@69
|
67
|
jpayne@69
|
68 typedef int (TclOO_PreCallProc)(void *clientData, Tcl_Interp *interp,
|
jpayne@69
|
69 Tcl_ObjectContext context, Tcl_CallFrame *framePtr, int *isFinished);
|
jpayne@69
|
70 typedef int (TclOO_PostCallProc)(void *clientData, Tcl_Interp *interp,
|
jpayne@69
|
71 Tcl_ObjectContext context, Tcl_Namespace *namespacePtr, int result);
|
jpayne@69
|
72 typedef void (TclOO_PmCDDeleteProc)(void *clientData);
|
jpayne@69
|
73 typedef void *(TclOO_PmCDCloneProc)(void *clientData);
|
jpayne@69
|
74
|
jpayne@69
|
75 /*
|
jpayne@69
|
76 * Procedure-like methods have the following extra information.
|
jpayne@69
|
77 */
|
jpayne@69
|
78
|
jpayne@69
|
79 typedef struct ProcedureMethod {
|
jpayne@69
|
80 int version; /* Version of this structure. Currently must
|
jpayne@69
|
81 * be 0. */
|
jpayne@69
|
82 Proc *procPtr; /* Core of the implementation of the method;
|
jpayne@69
|
83 * includes the argument definition and the
|
jpayne@69
|
84 * body bytecodes. */
|
jpayne@69
|
85 int flags; /* Flags to control features. */
|
jpayne@69
|
86 int refCount;
|
jpayne@69
|
87 void *clientData;
|
jpayne@69
|
88 TclOO_PmCDDeleteProc *deleteClientdataProc;
|
jpayne@69
|
89 TclOO_PmCDCloneProc *cloneClientdataProc;
|
jpayne@69
|
90 ProcErrorProc *errProc; /* Replacement error handler. */
|
jpayne@69
|
91 TclOO_PreCallProc *preCallProc;
|
jpayne@69
|
92 /* Callback to allow for additional setup
|
jpayne@69
|
93 * before the method executes. */
|
jpayne@69
|
94 TclOO_PostCallProc *postCallProc;
|
jpayne@69
|
95 /* Callback to allow for additional cleanup
|
jpayne@69
|
96 * after the method executes. */
|
jpayne@69
|
97 GetFrameInfoValueProc *gfivProc;
|
jpayne@69
|
98 /* Callback to allow for fine tuning of how
|
jpayne@69
|
99 * the method reports itself. */
|
jpayne@69
|
100 } ProcedureMethod;
|
jpayne@69
|
101
|
jpayne@69
|
102 #define TCLOO_PROCEDURE_METHOD_VERSION 0
|
jpayne@69
|
103
|
jpayne@69
|
104 /*
|
jpayne@69
|
105 * Flags for use in a ProcedureMethod.
|
jpayne@69
|
106 *
|
jpayne@69
|
107 * When the USE_DECLARER_NS flag is set, the method will use the namespace of
|
jpayne@69
|
108 * the object or class that declared it (or the clone of it, if it was from
|
jpayne@69
|
109 * such that the implementation of the method came to the particular use)
|
jpayne@69
|
110 * instead of the namespace of the object on which the method was invoked.
|
jpayne@69
|
111 * This flag must be distinct from all others that are associated with
|
jpayne@69
|
112 * methods.
|
jpayne@69
|
113 */
|
jpayne@69
|
114
|
jpayne@69
|
115 #define USE_DECLARER_NS 0x80
|
jpayne@69
|
116
|
jpayne@69
|
117 /*
|
jpayne@69
|
118 * Forwarded methods have the following extra information.
|
jpayne@69
|
119 */
|
jpayne@69
|
120
|
jpayne@69
|
121 typedef struct ForwardMethod {
|
jpayne@69
|
122 Tcl_Obj *prefixObj; /* The list of values to use to replace the
|
jpayne@69
|
123 * object and method name with. Will be a
|
jpayne@69
|
124 * non-empty list. */
|
jpayne@69
|
125 } ForwardMethod;
|
jpayne@69
|
126
|
jpayne@69
|
127 /*
|
jpayne@69
|
128 * Helper definitions that declare a "list" array. The two varieties are
|
jpayne@69
|
129 * either optimized for simplicity (in the case that the whole array is
|
jpayne@69
|
130 * typically assigned at once) or efficiency (in the case that the array is
|
jpayne@69
|
131 * expected to be expanded over time). These lists are designed to be iterated
|
jpayne@69
|
132 * over with the help of the FOREACH macro (see later in this file).
|
jpayne@69
|
133 *
|
jpayne@69
|
134 * The "num" field always counts the number of listType_t elements used in the
|
jpayne@69
|
135 * "list" field. When a "size" field exists, it describes how many elements
|
jpayne@69
|
136 * are present in the list; when absent, exactly "num" elements are present.
|
jpayne@69
|
137 */
|
jpayne@69
|
138
|
jpayne@69
|
139 #define LIST_STATIC(listType_t) \
|
jpayne@69
|
140 struct { int num; listType_t *list; }
|
jpayne@69
|
141 #define LIST_DYNAMIC(listType_t) \
|
jpayne@69
|
142 struct { int num, size; listType_t *list; }
|
jpayne@69
|
143
|
jpayne@69
|
144 /*
|
jpayne@69
|
145 * Now, the definition of what an object actually is.
|
jpayne@69
|
146 */
|
jpayne@69
|
147
|
jpayne@69
|
148 typedef struct Object {
|
jpayne@69
|
149 struct Foundation *fPtr; /* The basis for the object system. Putting
|
jpayne@69
|
150 * this here allows the avoidance of quite a
|
jpayne@69
|
151 * lot of hash lookups on the critical path
|
jpayne@69
|
152 * for object invocation and creation. */
|
jpayne@69
|
153 Tcl_Namespace *namespacePtr;/* This object's namespace. */
|
jpayne@69
|
154 Tcl_Command command; /* Reference to this object's public
|
jpayne@69
|
155 * command. */
|
jpayne@69
|
156 Tcl_Command myCommand; /* Reference to this object's internal
|
jpayne@69
|
157 * command. */
|
jpayne@69
|
158 struct Class *selfCls; /* This object's class. */
|
jpayne@69
|
159 Tcl_HashTable *methodsPtr; /* Object-local Tcl_Obj (method name) to
|
jpayne@69
|
160 * Method* mapping. */
|
jpayne@69
|
161 LIST_STATIC(struct Class *) mixins;
|
jpayne@69
|
162 /* Classes mixed into this object. */
|
jpayne@69
|
163 LIST_STATIC(Tcl_Obj *) filters;
|
jpayne@69
|
164 /* List of filter names. */
|
jpayne@69
|
165 struct Class *classPtr; /* This is non-NULL for all classes, and NULL
|
jpayne@69
|
166 * for everything else. It points to the class
|
jpayne@69
|
167 * structure. */
|
jpayne@69
|
168 int refCount; /* Number of strong references to this object.
|
jpayne@69
|
169 * Note that there may be many more weak
|
jpayne@69
|
170 * references; this mechanism exists to
|
jpayne@69
|
171 * avoid Tcl_Preserve. */
|
jpayne@69
|
172 int flags;
|
jpayne@69
|
173 int creationEpoch; /* Unique value to make comparisons of objects
|
jpayne@69
|
174 * easier. */
|
jpayne@69
|
175 int epoch; /* Per-object epoch, incremented when the way
|
jpayne@69
|
176 * an object should resolve call chains is
|
jpayne@69
|
177 * changed. */
|
jpayne@69
|
178 Tcl_HashTable *metadataPtr; /* Mapping from pointers to metadata type to
|
jpayne@69
|
179 * the ClientData values that are the values
|
jpayne@69
|
180 * of each piece of attached metadata. This
|
jpayne@69
|
181 * field starts out as NULL and is only
|
jpayne@69
|
182 * allocated if metadata is attached. */
|
jpayne@69
|
183 Tcl_Obj *cachedNameObj; /* Cache of the name of the object. */
|
jpayne@69
|
184 Tcl_HashTable *chainCache; /* Place to keep unused contexts. This table
|
jpayne@69
|
185 * is indexed by method name as Tcl_Obj. */
|
jpayne@69
|
186 Tcl_ObjectMapMethodNameProc *mapMethodNameProc;
|
jpayne@69
|
187 /* Function to allow remapping of method
|
jpayne@69
|
188 * names. For itcl-ng. */
|
jpayne@69
|
189 LIST_STATIC(Tcl_Obj *) variables;
|
jpayne@69
|
190 } Object;
|
jpayne@69
|
191
|
jpayne@69
|
192 #define OBJECT_DESTRUCTING 1 /* Indicates that an object is being or has
|
jpayne@69
|
193 * been destroyed */
|
jpayne@69
|
194 #define DESTRUCTOR_CALLED 2 /* Indicates that evaluation of destructor script for the
|
jpayne@69
|
195 object has began */
|
jpayne@69
|
196 #define OO_UNUSED_4 4 /* No longer used. */
|
jpayne@69
|
197 #define ROOT_OBJECT 0x1000 /* Flag to say that this object is the root of
|
jpayne@69
|
198 * the class hierarchy and should be treated
|
jpayne@69
|
199 * specially during teardown. */
|
jpayne@69
|
200 #define FILTER_HANDLING 0x2000 /* Flag set when the object is processing a
|
jpayne@69
|
201 * filter; when set, filters are *not*
|
jpayne@69
|
202 * processed on the object, preventing nasty
|
jpayne@69
|
203 * recursive filtering problems. */
|
jpayne@69
|
204 #define USE_CLASS_CACHE 0x4000 /* Flag set to say that the object is a pure
|
jpayne@69
|
205 * instance of the class, and has had nothing
|
jpayne@69
|
206 * added that changes the dispatch chain (i.e.
|
jpayne@69
|
207 * no methods, mixins, or filters. */
|
jpayne@69
|
208 #define ROOT_CLASS 0x8000 /* Flag to say that this object is the root
|
jpayne@69
|
209 * class of classes, and should be treated
|
jpayne@69
|
210 * specially during teardown (and in a few
|
jpayne@69
|
211 * other spots). */
|
jpayne@69
|
212 #define FORCE_UNKNOWN 0x10000 /* States that we are *really* looking up the
|
jpayne@69
|
213 * unknown method handler at that point. */
|
jpayne@69
|
214 #define DONT_DELETE 0x20000 /* Inhibit deletion of this object. */
|
jpayne@69
|
215
|
jpayne@69
|
216 /*
|
jpayne@69
|
217 * And the definition of a class. Note that every class also has an associated
|
jpayne@69
|
218 * object, through which it is manipulated.
|
jpayne@69
|
219 */
|
jpayne@69
|
220
|
jpayne@69
|
221 typedef struct Class {
|
jpayne@69
|
222 Object *thisPtr; /* Reference to the object associated with
|
jpayne@69
|
223 * this class. */
|
jpayne@69
|
224 int flags; /* Assorted flags. */
|
jpayne@69
|
225 LIST_STATIC(struct Class *) superclasses;
|
jpayne@69
|
226 /* List of superclasses, used for generation
|
jpayne@69
|
227 * of method call chains. */
|
jpayne@69
|
228 LIST_DYNAMIC(struct Class *) subclasses;
|
jpayne@69
|
229 /* List of subclasses, used to ensure deletion
|
jpayne@69
|
230 * of dependent entities happens properly when
|
jpayne@69
|
231 * the class itself is deleted. */
|
jpayne@69
|
232 LIST_DYNAMIC(Object *) instances;
|
jpayne@69
|
233 /* List of instances, used to ensure deletion
|
jpayne@69
|
234 * of dependent entities happens properly when
|
jpayne@69
|
235 * the class itself is deleted. */
|
jpayne@69
|
236 LIST_STATIC(Tcl_Obj *) filters;
|
jpayne@69
|
237 /* List of filter names, used for generation
|
jpayne@69
|
238 * of method call chains. */
|
jpayne@69
|
239 LIST_STATIC(struct Class *) mixins;
|
jpayne@69
|
240 /* List of mixin classes, used for generation
|
jpayne@69
|
241 * of method call chains. */
|
jpayne@69
|
242 LIST_DYNAMIC(struct Class *) mixinSubs;
|
jpayne@69
|
243 /* List of classes that this class is mixed
|
jpayne@69
|
244 * into, used to ensure deletion of dependent
|
jpayne@69
|
245 * entities happens properly when the class
|
jpayne@69
|
246 * itself is deleted. */
|
jpayne@69
|
247 Tcl_HashTable classMethods; /* Hash table of all methods. Hash maps from
|
jpayne@69
|
248 * the (Tcl_Obj*) method name to the (Method*)
|
jpayne@69
|
249 * method record. */
|
jpayne@69
|
250 Method *constructorPtr; /* Method record of the class constructor (if
|
jpayne@69
|
251 * any). */
|
jpayne@69
|
252 Method *destructorPtr; /* Method record of the class destructor (if
|
jpayne@69
|
253 * any). */
|
jpayne@69
|
254 Tcl_HashTable *metadataPtr; /* Mapping from pointers to metadata type to
|
jpayne@69
|
255 * the ClientData values that are the values
|
jpayne@69
|
256 * of each piece of attached metadata. This
|
jpayne@69
|
257 * field starts out as NULL and is only
|
jpayne@69
|
258 * allocated if metadata is attached. */
|
jpayne@69
|
259 struct CallChain *constructorChainPtr;
|
jpayne@69
|
260 struct CallChain *destructorChainPtr;
|
jpayne@69
|
261 Tcl_HashTable *classChainCache;
|
jpayne@69
|
262 /* Places where call chains are stored. For
|
jpayne@69
|
263 * constructors, the class chain is always
|
jpayne@69
|
264 * used. For destructors and ordinary methods,
|
jpayne@69
|
265 * the class chain is only used when the
|
jpayne@69
|
266 * object doesn't override with its own mixins
|
jpayne@69
|
267 * (and filters and method implementations for
|
jpayne@69
|
268 * when getting method chains). */
|
jpayne@69
|
269 LIST_STATIC(Tcl_Obj *) variables;
|
jpayne@69
|
270 } Class;
|
jpayne@69
|
271
|
jpayne@69
|
272 /*
|
jpayne@69
|
273 * The foundation of the object system within an interpreter contains
|
jpayne@69
|
274 * references to the key classes and namespaces, together with a few other
|
jpayne@69
|
275 * useful bits and pieces. Probably ought to eventually go in the Interp
|
jpayne@69
|
276 * structure itself.
|
jpayne@69
|
277 */
|
jpayne@69
|
278
|
jpayne@69
|
279 typedef struct ThreadLocalData {
|
jpayne@69
|
280 int nsCount; /* Epoch counter is used for keeping
|
jpayne@69
|
281 * the values used in Tcl_Obj internal
|
jpayne@69
|
282 * representations sane. Must be thread-local
|
jpayne@69
|
283 * because Tcl_Objs can cross interpreter
|
jpayne@69
|
284 * boundaries within a thread (objects don't
|
jpayne@69
|
285 * generally cross threads). */
|
jpayne@69
|
286 } ThreadLocalData;
|
jpayne@69
|
287
|
jpayne@69
|
288 typedef struct Foundation {
|
jpayne@69
|
289 Tcl_Interp *interp;
|
jpayne@69
|
290 Class *objectCls; /* The root of the object system. */
|
jpayne@69
|
291 Class *classCls; /* The class of all classes. */
|
jpayne@69
|
292 Tcl_Namespace *ooNs; /* ::oo namespace. */
|
jpayne@69
|
293 Tcl_Namespace *defineNs; /* Namespace containing special commands for
|
jpayne@69
|
294 * manipulating objects and classes. The
|
jpayne@69
|
295 * "oo::define" command acts as a special kind
|
jpayne@69
|
296 * of ensemble for this namespace. */
|
jpayne@69
|
297 Tcl_Namespace *objdefNs; /* Namespace containing special commands for
|
jpayne@69
|
298 * manipulating objects and classes. The
|
jpayne@69
|
299 * "oo::objdefine" command acts as a special
|
jpayne@69
|
300 * kind of ensemble for this namespace. */
|
jpayne@69
|
301 Tcl_Namespace *helpersNs; /* Namespace containing the commands that are
|
jpayne@69
|
302 * only valid when executing inside a
|
jpayne@69
|
303 * procedural method. */
|
jpayne@69
|
304 int epoch; /* Used to invalidate method chains when the
|
jpayne@69
|
305 * class structure changes. */
|
jpayne@69
|
306 ThreadLocalData *tsdPtr; /* Counter so we can allocate a unique
|
jpayne@69
|
307 * namespace to each object. */
|
jpayne@69
|
308 Tcl_Obj *unknownMethodNameObj;
|
jpayne@69
|
309 /* Shared object containing the name of the
|
jpayne@69
|
310 * unknown method handler method. */
|
jpayne@69
|
311 Tcl_Obj *constructorName; /* Shared object containing the "name" of a
|
jpayne@69
|
312 * constructor. */
|
jpayne@69
|
313 Tcl_Obj *destructorName; /* Shared object containing the "name" of a
|
jpayne@69
|
314 * destructor. */
|
jpayne@69
|
315 Tcl_Obj *clonedName; /* Shared object containing the name of a
|
jpayne@69
|
316 * "<cloned>" pseudo-constructor. */
|
jpayne@69
|
317 Tcl_Obj *defineName; /* Fully qualified name of oo::define. */
|
jpayne@69
|
318 } Foundation;
|
jpayne@69
|
319
|
jpayne@69
|
320 /*
|
jpayne@69
|
321 * A call context structure is built when a method is called. It contains the
|
jpayne@69
|
322 * chain of method implementations that are to be invoked by a particular
|
jpayne@69
|
323 * call, and the process of calling walks the chain, with the [next] command
|
jpayne@69
|
324 * proceeding to the next entry in the chain.
|
jpayne@69
|
325 */
|
jpayne@69
|
326
|
jpayne@69
|
327 #define CALL_CHAIN_STATIC_SIZE 4
|
jpayne@69
|
328
|
jpayne@69
|
329 struct MInvoke {
|
jpayne@69
|
330 Method *mPtr; /* Reference to the method implementation
|
jpayne@69
|
331 * record. */
|
jpayne@69
|
332 int isFilter; /* Whether this is a filter invocation. */
|
jpayne@69
|
333 Class *filterDeclarer; /* What class decided to add the filter; if
|
jpayne@69
|
334 * NULL, it was added by the object. */
|
jpayne@69
|
335 };
|
jpayne@69
|
336
|
jpayne@69
|
337 typedef struct CallChain {
|
jpayne@69
|
338 int objectCreationEpoch; /* The object's creation epoch. Note that the
|
jpayne@69
|
339 * object reference is not stored in the call
|
jpayne@69
|
340 * chain; it is in the call context. */
|
jpayne@69
|
341 int objectEpoch; /* Local (object structure) epoch counter
|
jpayne@69
|
342 * snapshot. */
|
jpayne@69
|
343 int epoch; /* Global (class structure) epoch counter
|
jpayne@69
|
344 * snapshot. */
|
jpayne@69
|
345 int flags; /* Assorted flags, see below. */
|
jpayne@69
|
346 int refCount; /* Reference count. */
|
jpayne@69
|
347 int numChain; /* Size of the call chain. */
|
jpayne@69
|
348 struct MInvoke *chain; /* Array of call chain entries. May point to
|
jpayne@69
|
349 * staticChain if the number of entries is
|
jpayne@69
|
350 * small. */
|
jpayne@69
|
351 struct MInvoke staticChain[CALL_CHAIN_STATIC_SIZE];
|
jpayne@69
|
352 } CallChain;
|
jpayne@69
|
353
|
jpayne@69
|
354 typedef struct CallContext {
|
jpayne@69
|
355 Object *oPtr; /* The object associated with this call. */
|
jpayne@69
|
356 int index; /* Index into the call chain of the currently
|
jpayne@69
|
357 * executing method implementation. */
|
jpayne@69
|
358 int skip; /* Current number of arguments to skip; can
|
jpayne@69
|
359 * vary depending on whether it is a direct
|
jpayne@69
|
360 * method call or a continuation via the
|
jpayne@69
|
361 * [next] command. */
|
jpayne@69
|
362 CallChain *callPtr; /* The actual call chain. */
|
jpayne@69
|
363 } CallContext;
|
jpayne@69
|
364
|
jpayne@69
|
365 /*
|
jpayne@69
|
366 * Bits for the 'flags' field of the call chain.
|
jpayne@69
|
367 */
|
jpayne@69
|
368
|
jpayne@69
|
369 #define PUBLIC_METHOD 0x01 /* This is a public (exported) method. */
|
jpayne@69
|
370 #define PRIVATE_METHOD 0x02 /* This is a private (class's direct instances
|
jpayne@69
|
371 * only) method. Supports itcl. */
|
jpayne@69
|
372 #define OO_UNKNOWN_METHOD 0x04 /* This is an unknown method. */
|
jpayne@69
|
373 #define CONSTRUCTOR 0x08 /* This is a constructor. */
|
jpayne@69
|
374 #define DESTRUCTOR 0x10 /* This is a destructor. */
|
jpayne@69
|
375
|
jpayne@69
|
376 /*
|
jpayne@69
|
377 * Structure containing definition information about basic class methods.
|
jpayne@69
|
378 */
|
jpayne@69
|
379
|
jpayne@69
|
380 typedef struct {
|
jpayne@69
|
381 const char *name; /* Name of the method in question. */
|
jpayne@69
|
382 int isPublic; /* Whether the method is public by default. */
|
jpayne@69
|
383 Tcl_MethodType definition; /* How to call the method. */
|
jpayne@69
|
384 } DeclaredClassMethod;
|
jpayne@69
|
385
|
jpayne@69
|
386 /*
|
jpayne@69
|
387 *----------------------------------------------------------------
|
jpayne@69
|
388 * Commands relating to OO support.
|
jpayne@69
|
389 *----------------------------------------------------------------
|
jpayne@69
|
390 */
|
jpayne@69
|
391
|
jpayne@69
|
392 MODULE_SCOPE int TclOOInit(Tcl_Interp *interp);
|
jpayne@69
|
393 MODULE_SCOPE int TclOODefineObjCmd(void *clientData,
|
jpayne@69
|
394 Tcl_Interp *interp, int objc,
|
jpayne@69
|
395 Tcl_Obj *const *objv);
|
jpayne@69
|
396 MODULE_SCOPE int TclOOObjDefObjCmd(void *clientData,
|
jpayne@69
|
397 Tcl_Interp *interp, int objc,
|
jpayne@69
|
398 Tcl_Obj *const *objv);
|
jpayne@69
|
399 MODULE_SCOPE int TclOODefineConstructorObjCmd(void *clientData,
|
jpayne@69
|
400 Tcl_Interp *interp, int objc,
|
jpayne@69
|
401 Tcl_Obj *const *objv);
|
jpayne@69
|
402 MODULE_SCOPE int TclOODefineDeleteMethodObjCmd(void *clientData,
|
jpayne@69
|
403 Tcl_Interp *interp, int objc,
|
jpayne@69
|
404 Tcl_Obj *const *objv);
|
jpayne@69
|
405 MODULE_SCOPE int TclOODefineDestructorObjCmd(void *clientData,
|
jpayne@69
|
406 Tcl_Interp *interp, int objc,
|
jpayne@69
|
407 Tcl_Obj *const *objv);
|
jpayne@69
|
408 MODULE_SCOPE int TclOODefineExportObjCmd(void *clientData,
|
jpayne@69
|
409 Tcl_Interp *interp, int objc,
|
jpayne@69
|
410 Tcl_Obj *const *objv);
|
jpayne@69
|
411 MODULE_SCOPE int TclOODefineForwardObjCmd(void *clientData,
|
jpayne@69
|
412 Tcl_Interp *interp, int objc,
|
jpayne@69
|
413 Tcl_Obj *const *objv);
|
jpayne@69
|
414 MODULE_SCOPE int TclOODefineMethodObjCmd(void *clientData,
|
jpayne@69
|
415 Tcl_Interp *interp, int objc,
|
jpayne@69
|
416 Tcl_Obj *const *objv);
|
jpayne@69
|
417 MODULE_SCOPE int TclOODefineRenameMethodObjCmd(void *clientData,
|
jpayne@69
|
418 Tcl_Interp *interp, int objc,
|
jpayne@69
|
419 Tcl_Obj *const *objv);
|
jpayne@69
|
420 MODULE_SCOPE int TclOODefineUnexportObjCmd(void *clientData,
|
jpayne@69
|
421 Tcl_Interp *interp, int objc,
|
jpayne@69
|
422 Tcl_Obj *const *objv);
|
jpayne@69
|
423 MODULE_SCOPE int TclOODefineClassObjCmd(void *clientData,
|
jpayne@69
|
424 Tcl_Interp *interp, int objc,
|
jpayne@69
|
425 Tcl_Obj *const *objv);
|
jpayne@69
|
426 MODULE_SCOPE int TclOODefineSelfObjCmd(void *clientData,
|
jpayne@69
|
427 Tcl_Interp *interp, int objc,
|
jpayne@69
|
428 Tcl_Obj *const *objv);
|
jpayne@69
|
429 MODULE_SCOPE int TclOOUnknownDefinition(void *clientData,
|
jpayne@69
|
430 Tcl_Interp *interp, int objc,
|
jpayne@69
|
431 Tcl_Obj *const *objv);
|
jpayne@69
|
432 MODULE_SCOPE int TclOOCopyObjectCmd(void *clientData,
|
jpayne@69
|
433 Tcl_Interp *interp, int objc,
|
jpayne@69
|
434 Tcl_Obj *const *objv);
|
jpayne@69
|
435 MODULE_SCOPE int TclOONextObjCmd(void *clientData,
|
jpayne@69
|
436 Tcl_Interp *interp, int objc,
|
jpayne@69
|
437 Tcl_Obj *const *objv);
|
jpayne@69
|
438 MODULE_SCOPE int TclOONextToObjCmd(void *clientData,
|
jpayne@69
|
439 Tcl_Interp *interp, int objc,
|
jpayne@69
|
440 Tcl_Obj *const *objv);
|
jpayne@69
|
441 MODULE_SCOPE int TclOOSelfObjCmd(void *clientData,
|
jpayne@69
|
442 Tcl_Interp *interp, int objc,
|
jpayne@69
|
443 Tcl_Obj *const *objv);
|
jpayne@69
|
444
|
jpayne@69
|
445 /*
|
jpayne@69
|
446 * Method implementations (in tclOOBasic.c).
|
jpayne@69
|
447 */
|
jpayne@69
|
448
|
jpayne@69
|
449 MODULE_SCOPE int TclOO_Class_Constructor(void *clientData,
|
jpayne@69
|
450 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
451 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
452 MODULE_SCOPE int TclOO_Class_Create(void *clientData,
|
jpayne@69
|
453 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
454 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
455 MODULE_SCOPE int TclOO_Class_CreateNs(void *clientData,
|
jpayne@69
|
456 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
457 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
458 MODULE_SCOPE int TclOO_Class_New(void *clientData,
|
jpayne@69
|
459 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
460 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
461 MODULE_SCOPE int TclOO_Object_Destroy(void *clientData,
|
jpayne@69
|
462 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
463 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
464 MODULE_SCOPE int TclOO_Object_Eval(void *clientData,
|
jpayne@69
|
465 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
466 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
467 MODULE_SCOPE int TclOO_Object_LinkVar(void *clientData,
|
jpayne@69
|
468 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
469 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
470 MODULE_SCOPE int TclOO_Object_Unknown(void *clientData,
|
jpayne@69
|
471 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
472 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
473 MODULE_SCOPE int TclOO_Object_VarName(void *clientData,
|
jpayne@69
|
474 Tcl_Interp *interp, Tcl_ObjectContext context,
|
jpayne@69
|
475 int objc, Tcl_Obj *const *objv);
|
jpayne@69
|
476
|
jpayne@69
|
477 /*
|
jpayne@69
|
478 * Private definitions, some of which perhaps ought to be exposed properly or
|
jpayne@69
|
479 * maybe just put in the internal stubs table.
|
jpayne@69
|
480 */
|
jpayne@69
|
481
|
jpayne@69
|
482 MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr);
|
jpayne@69
|
483 MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr);
|
jpayne@69
|
484 MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr);
|
jpayne@69
|
485 MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp,
|
jpayne@69
|
486 Object *useThisObj);
|
jpayne@69
|
487 MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp,
|
jpayne@69
|
488 Tcl_Class cls, const char *nameStr,
|
jpayne@69
|
489 const char *nsNameStr, int objc,
|
jpayne@69
|
490 Tcl_Obj *const *objv, int skip,
|
jpayne@69
|
491 Tcl_Object *objectPtr);
|
jpayne@69
|
492 MODULE_SCOPE Object * TclNewObjectInstanceCommon(Tcl_Interp *interp,
|
jpayne@69
|
493 Class *classPtr,
|
jpayne@69
|
494 const char *nameStr,
|
jpayne@69
|
495 const char *nsNameStr);
|
jpayne@69
|
496 MODULE_SCOPE int TclOODecrRefCount(Object *oPtr);
|
jpayne@69
|
497 MODULE_SCOPE int TclOOObjectDestroyed(Object *oPtr);
|
jpayne@69
|
498 MODULE_SCOPE int TclOODefineSlots(Foundation *fPtr);
|
jpayne@69
|
499 MODULE_SCOPE void TclOODeleteChain(CallChain *callPtr);
|
jpayne@69
|
500 MODULE_SCOPE void TclOODeleteChainCache(Tcl_HashTable *tablePtr);
|
jpayne@69
|
501 MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr);
|
jpayne@69
|
502 MODULE_SCOPE void TclOODeleteDescendants(Tcl_Interp *interp,
|
jpayne@69
|
503 Object *oPtr);
|
jpayne@69
|
504 MODULE_SCOPE void TclOODelMethodRef(Method *method);
|
jpayne@69
|
505 MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr,
|
jpayne@69
|
506 Tcl_Obj *methodNameObj, int flags,
|
jpayne@69
|
507 Tcl_Obj *cacheInThisObj);
|
jpayne@69
|
508 MODULE_SCOPE CallChain *TclOOGetStereotypeCallChain(Class *clsPtr,
|
jpayne@69
|
509 Tcl_Obj *methodNameObj, int flags);
|
jpayne@69
|
510 MODULE_SCOPE Foundation *TclOOGetFoundation(Tcl_Interp *interp);
|
jpayne@69
|
511 MODULE_SCOPE Tcl_Obj * TclOOGetFwdFromMethod(Method *mPtr);
|
jpayne@69
|
512 MODULE_SCOPE Proc * TclOOGetProcFromMethod(Method *mPtr);
|
jpayne@69
|
513 MODULE_SCOPE Tcl_Obj * TclOOGetMethodBody(Method *mPtr);
|
jpayne@69
|
514 MODULE_SCOPE int TclOOGetSortedClassMethodList(Class *clsPtr,
|
jpayne@69
|
515 int flags, const char ***stringsPtr);
|
jpayne@69
|
516 MODULE_SCOPE int TclOOGetSortedMethodList(Object *oPtr, int flags,
|
jpayne@69
|
517 const char ***stringsPtr);
|
jpayne@69
|
518 MODULE_SCOPE int TclOOInit(Tcl_Interp *interp);
|
jpayne@69
|
519 MODULE_SCOPE void TclOOInitInfo(Tcl_Interp *interp);
|
jpayne@69
|
520 MODULE_SCOPE int TclOOInvokeContext(void *clientData,
|
jpayne@69
|
521 Tcl_Interp *interp, int objc,
|
jpayne@69
|
522 Tcl_Obj *const objv[]);
|
jpayne@69
|
523 MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp,
|
jpayne@69
|
524 Tcl_ObjectContext context, int objc,
|
jpayne@69
|
525 Tcl_Obj *const *objv, int skip);
|
jpayne@69
|
526 MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr,
|
jpayne@69
|
527 const DeclaredClassMethod *dcm);
|
jpayne@69
|
528 MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr);
|
jpayne@69
|
529 MODULE_SCOPE void TclOOReleaseClassContents(Tcl_Interp *interp,
|
jpayne@69
|
530 Object *oPtr);
|
jpayne@69
|
531 MODULE_SCOPE int TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
|
jpayne@69
|
532 MODULE_SCOPE int TclOORemoveFromMixins(Class *mixinPtr, Object *oPtr);
|
jpayne@69
|
533 MODULE_SCOPE int TclOORemoveFromMixinSubs(Class *subPtr,
|
jpayne@69
|
534 Class *mixinPtr);
|
jpayne@69
|
535 MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr,
|
jpayne@69
|
536 Class *superPtr);
|
jpayne@69
|
537 MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp,
|
jpayne@69
|
538 CallChain *callPtr);
|
jpayne@69
|
539 MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr,
|
jpayne@69
|
540 CallContext *contextPtr);
|
jpayne@69
|
541 MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
|
jpayne@69
|
542
|
jpayne@69
|
543 /*
|
jpayne@69
|
544 * Include all the private API, generated from tclOO.decls.
|
jpayne@69
|
545 */
|
jpayne@69
|
546
|
jpayne@69
|
547 #include "tclOOIntDecls.h"
|
jpayne@69
|
548
|
jpayne@69
|
549 /*
|
jpayne@69
|
550 * Alternatives to Tcl_Preserve/Tcl_EventuallyFree/Tcl_Release.
|
jpayne@69
|
551 */
|
jpayne@69
|
552
|
jpayne@69
|
553 #define AddRef(ptr) ((ptr)->refCount++)
|
jpayne@69
|
554
|
jpayne@69
|
555 /*
|
jpayne@69
|
556 * A convenience macro for iterating through the lists used in the internal
|
jpayne@69
|
557 * memory management of objects.
|
jpayne@69
|
558 * REQUIRES DECLARATION: int i;
|
jpayne@69
|
559 */
|
jpayne@69
|
560
|
jpayne@69
|
561 #define FOREACH(var,ary) \
|
jpayne@69
|
562 for(i=0 ; i<(ary).num; i++) if ((ary).list[i] == NULL) { \
|
jpayne@69
|
563 continue; \
|
jpayne@69
|
564 } else if ((var) = (ary).list[i], 1)
|
jpayne@69
|
565
|
jpayne@69
|
566 /*
|
jpayne@69
|
567 * Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
|
jpayne@69
|
568 * sets up the declarations needed for the main macro, FOREACH_HASH, which
|
jpayne@69
|
569 * does the actual iteration. FOREACH_HASH_VALUE is a restricted version that
|
jpayne@69
|
570 * only iterates over values.
|
jpayne@69
|
571 */
|
jpayne@69
|
572
|
jpayne@69
|
573 #define FOREACH_HASH_DECLS \
|
jpayne@69
|
574 Tcl_HashEntry *hPtr;Tcl_HashSearch search
|
jpayne@69
|
575 #define FOREACH_HASH(key,val,tablePtr) \
|
jpayne@69
|
576 for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \
|
jpayne@69
|
577 ((key)=(void *)Tcl_GetHashKey((tablePtr),hPtr),\
|
jpayne@69
|
578 (val)=Tcl_GetHashValue(hPtr),1):0; hPtr=Tcl_NextHashEntry(&search))
|
jpayne@69
|
579 #define FOREACH_HASH_VALUE(val,tablePtr) \
|
jpayne@69
|
580 for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \
|
jpayne@69
|
581 ((val)=Tcl_GetHashValue(hPtr),1):0;hPtr=Tcl_NextHashEntry(&search))
|
jpayne@69
|
582
|
jpayne@69
|
583 /*
|
jpayne@69
|
584 * Convenience macro for duplicating a list. Needs no external declaration,
|
jpayne@69
|
585 * but all arguments are used multiple times and so must have no side effects.
|
jpayne@69
|
586 */
|
jpayne@69
|
587
|
jpayne@69
|
588 #undef DUPLICATE /* prevent possible conflict with definition in WINAPI nb30.h */
|
jpayne@69
|
589 #define DUPLICATE(target,source,type) \
|
jpayne@69
|
590 do { \
|
jpayne@69
|
591 size_t len = sizeof(type) * ((target).num=(source).num);\
|
jpayne@69
|
592 if (len != 0) { \
|
jpayne@69
|
593 memcpy(((target).list=(type*)ckalloc(len)), (source).list, len); \
|
jpayne@69
|
594 } else { \
|
jpayne@69
|
595 (target).list = NULL; \
|
jpayne@69
|
596 } \
|
jpayne@69
|
597 } while(0)
|
jpayne@69
|
598
|
jpayne@69
|
599 #endif /* TCL_OO_INTERNAL_H */
|
jpayne@69
|
600
|
jpayne@69
|
601 /*
|
jpayne@69
|
602 * Local Variables:
|
jpayne@69
|
603 * mode: c
|
jpayne@69
|
604 * c-basic-offset: 4
|
jpayne@69
|
605 * fill-column: 78
|
jpayne@69
|
606 * End:
|
jpayne@69
|
607 */
|