diff options
Diffstat (limited to 'generic/tclOOInt.h')
-rw-r--r-- | generic/tclOOInt.h | 290 |
1 files changed, 161 insertions, 129 deletions
diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index b5d1296..3ef395c 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -30,35 +30,45 @@ * Forward declarations. */ -struct CallChain; -struct Class; -struct Foundation; -struct Object; +typedef struct CallChain CallChain; +typedef struct CallContext CallContext; +typedef struct Class Class; +typedef struct DeclaredClassMethod DeclaredClassMethod; +typedef struct ForwardMethod ForwardMethod; +typedef struct Foundation Foundation; +typedef struct Method Method; +typedef struct MInvoke MInvoke; +typedef struct Object Object; +typedef struct PrivateVariableMapping PrivateVariableMapping; +typedef struct ProcedureMethod ProcedureMethod; +typedef struct PropertyStorage PropertyStorage; /* * The data that needs to be stored per method. This record is used to collect * information about all sorts of methods, including forwards, constructors * and destructors. */ - -typedef struct Method { - const Tcl_MethodType *typePtr; - /* The type of method. If NULL, this is a +struct Method { + union { + const Tcl_MethodType *typePtr; + const Tcl_MethodType2 *type2Ptr; + }; /* The type of method. If NULL, this is a * special flag record which is just used for - * the setting of the flags field. */ + * the setting of the flags field. Note that + * this is a union of two pointer types that + * have the same layout at least as far as the + * internal version field. */ Tcl_Size refCount; - void *clientData; /* Type-specific data. */ + void *clientData; /* Type-specific data. */ Tcl_Obj *namePtr; /* Name of the method. */ - struct Object *declaringObjectPtr; - /* The object that declares this method, or + Object *declaringObjectPtr; /* The object that declares this method, or * NULL if it was declared by a class. */ - struct Class *declaringClassPtr; - /* The class that declares this method, or + Class *declaringClassPtr; /* The class that declares this method, or * NULL if it was declared directly on an * object. */ int flags; /* Assorted flags. Includes whether this * method is public/exported or not. */ -} Method; +}; /* * Pre- and post-call callbacks, to allow procedure-like methods to be fine @@ -75,10 +85,9 @@ typedef void *(TclOO_PmCDCloneProc)(void *clientData); /* * Procedure-like methods have the following extra information. */ - -typedef struct ProcedureMethod { +struct ProcedureMethod { int version; /* Version of this structure. Currently must - * be 0. */ + * be TCLOO_PROCEDURE_METHOD_VERSION_1. */ Proc *procPtr; /* Core of the implementation of the method; * includes the argument definition and the * body bytecodes. */ @@ -107,44 +116,47 @@ typedef struct ProcedureMethod { * destructor, which we can't know until then * for messy reasons. Other flags are variable * but not used. */ -} ProcedureMethod; +}; -#define TCLOO_PROCEDURE_METHOD_VERSION 0 +enum ProcedureMethodVersion { + TCLOO_PROCEDURE_METHOD_VERSION_1 = 0 +}; +#define TCLOO_PROCEDURE_METHOD_VERSION TCLOO_PROCEDURE_METHOD_VERSION_1 /* * Flags for use in a ProcedureMethod. * - * When the USE_DECLARER_NS flag is set, the method will use the namespace of - * the object or class that declared it (or the clone of it, if it was from - * such that the implementation of the method came to the particular use) - * instead of the namespace of the object on which the method was invoked. - * This flag must be distinct from all others that are associated with - * methods. */ - -#define USE_DECLARER_NS 0x80 +enum ProceudreMethodFlags { + USE_DECLARER_NS = 0x80 /* When set, the method will use the namespace + * of the object or class that declared it (or + * the clone of it, if it was from such that + * the implementation of the method came to the + * particular use) instead of the namespace of + * the object on which the method was invoked. + * This flag must be distinct from all others + * that are associated with methods. */ +}; /* * Forwarded methods have the following extra information. */ - -typedef struct ForwardMethod { +struct ForwardMethod { Tcl_Obj *prefixObj; /* The list of values to use to replace the * object and method name with. Will be a * non-empty list. */ -} ForwardMethod; +}; /* * Structure used in private variable mappings. Describes the mapping of a * single variable from the user's local name to the system's storage name. * [TIP #500] */ - -typedef struct { +struct PrivateVariableMapping { Tcl_Obj *variableObj; /* Name used within methods. This is the part * that is properly under user control. */ Tcl_Obj *fullNameObj; /* Name used at the instance namespace level. */ -} PrivateVariableMapping; +}; /* * Helper definitions that declare a "list" array. The two varieties are @@ -167,18 +179,21 @@ typedef struct { * These types are needed in function arguments. */ +typedef LIST_STATIC(Class *) ClassList; +typedef LIST_DYNAMIC(Class *) VarClassList; +typedef LIST_STATIC(Tcl_Obj *) FilterList; +typedef LIST_DYNAMIC(Object *) ObjectList; typedef LIST_STATIC(Tcl_Obj *) VariableNameList; typedef LIST_STATIC(PrivateVariableMapping) PrivateVariableList; +typedef LIST_STATIC(Tcl_Obj *) PropertyList; /* - * This type is used in various places. + * This type is used in various places. It holds the parts of an object or + * class relating to property information. */ - -typedef struct { - LIST_STATIC(Tcl_Obj *) readable; - /* The readable properties slot. */ - LIST_STATIC(Tcl_Obj *) writable; - /* The writable properties slot. */ +struct PropertyStorage { + PropertyList readable; /* The readable properties slot. */ + PropertyList writable; /* The writable properties slot. */ Tcl_Obj *allReadableCache; /* The cache of all readable properties * exposed by this object or class (in its * stereotypical instancs). Contains a sorted @@ -188,40 +203,36 @@ typedef struct { * stereotypical instances). Contains a sorted * unique list if not NULL. */ int epoch; /* The epoch that the caches are valid for. */ -} PropertyStorage; +}; /* * Now, the definition of what an object actually is. */ -typedef struct Object { - struct Foundation *fPtr; /* The basis for the object system. Putting - * this here allows the avoidance of quite a - * lot of hash lookups on the critical path - * for object invocation and creation. */ +struct Object { + Foundation *fPtr; /* The basis for the object system, which is + * conceptually part of the interpreter. */ Tcl_Namespace *namespacePtr;/* This object's namespace. */ Tcl_Command command; /* Reference to this object's public * command. */ Tcl_Command myCommand; /* Reference to this object's internal * command. */ - struct Class *selfCls; /* This object's class. */ + Class *selfCls; /* This object's class. */ Tcl_HashTable *methodsPtr; /* Object-local Tcl_Obj (method name) to * Method* mapping. */ - LIST_STATIC(struct Class *) mixins; - /* Classes mixed into this object. */ - LIST_STATIC(Tcl_Obj *) filters; - /* List of filter names. */ - struct Class *classPtr; /* This is non-NULL for all classes, and NULL + ClassList mixins; /* Classes mixed into this object. */ + FilterList filters; /* List of filter names. */ + Class *classPtr; /* This is non-NULL for all classes, and NULL * for everything else. It points to the class * structure. */ Tcl_Size refCount; /* Number of strong references to this object. * Note that there may be many more weak * references; this mechanism exists to * avoid Tcl_Preserve. */ - int flags; - Tcl_Size creationEpoch; /* Unique value to make comparisons of objects + int flags; /* See ObjectFlags. */ + Tcl_Size creationEpoch; /* Unique value to make comparisons of objects * easier. */ - Tcl_Size epoch; /* Per-object epoch, incremented when the way + Tcl_Size epoch; /* Per-object epoch, incremented when the way * an object should resolve call chains is * changed. */ Tcl_HashTable *metadataPtr; /* Mapping from pointers to metadata type to @@ -244,67 +255,62 @@ typedef struct Object { PropertyStorage properties; /* Information relating to the lists of * properties that this object *claims* to * support. */ -} Object; +}; -#define OBJECT_DESTRUCTING 1 /* Indicates that an object is being or has +enum ObjectFlags { + OBJECT_DESTRUCTING = 1, /* Indicates that an object is being or has * been destroyed */ -#define DESTRUCTOR_CALLED 2 /* Indicates that evaluation of destructor + DESTRUCTOR_CALLED = 2, /* Indicates that evaluation of destructor * script for the object has began */ -#define OO_UNUSED_4 4 /* No longer used. */ -#define ROOT_OBJECT 0x1000 /* Flag to say that this object is the root of + ROOT_OBJECT = 0x1000, /* Flag to say that this object is the root of * the class hierarchy and should be treated * specially during teardown. */ -#define FILTER_HANDLING 0x2000 /* Flag set when the object is processing a + FILTER_HANDLING = 0x2000, /* Flag set when the object is processing a * filter; when set, filters are *not* * processed on the object, preventing nasty * recursive filtering problems. */ -#define USE_CLASS_CACHE 0x4000 /* Flag set to say that the object is a pure + USE_CLASS_CACHE = 0x4000, /* Flag set to say that the object is a pure * instance of the class, and has had nothing * added that changes the dispatch chain (i.e. * no methods, mixins, or filters. */ -#define ROOT_CLASS 0x8000 /* Flag to say that this object is the root + ROOT_CLASS = 0x8000, /* Flag to say that this object is the root * class of classes, and should be treated * specially during teardown (and in a few * other spots). */ -#define FORCE_UNKNOWN 0x10000 /* States that we are *really* looking up the + FORCE_UNKNOWN = 0x10000, /* States that we are *really* looking up the * unknown method handler at that point. */ -#define DONT_DELETE 0x20000 /* Inhibit deletion of this object. Used + DONT_DELETE = 0x20000, /* Inhibit deletion of this object. Used * during fundamental object type mutation to * make sure that the object actually survives * to the end of the operation. */ -#define HAS_PRIVATE_METHODS 0x40000 + HAS_PRIVATE_METHODS = 0x40000 /* Object/class has (or had) private methods, * and so shouldn't be cached so * aggressively. */ +}; /* * And the definition of a class. Note that every class also has an associated * object, through which it is manipulated. */ -typedef struct Class { +struct Class { Object *thisPtr; /* Reference to the object associated with * this class. */ int flags; /* Assorted flags. */ - LIST_STATIC(struct Class *) superclasses; - /* List of superclasses, used for generation + ClassList superclasses; /* List of superclasses, used for generation * of method call chains. */ - LIST_DYNAMIC(struct Class *) subclasses; - /* List of subclasses, used to ensure deletion + VarClassList subclasses; /* List of subclasses, used to ensure deletion * of dependent entities happens properly when * the class itself is deleted. */ - LIST_DYNAMIC(Object *) instances; - /* List of instances, used to ensure deletion + ObjectList instances; /* List of instances, used to ensure deletion * of dependent entities happens properly when * the class itself is deleted. */ - LIST_STATIC(Tcl_Obj *) filters; - /* List of filter names, used for generation + FilterList filters; /* List of filter names, used for generation * of method call chains. */ - LIST_STATIC(struct Class *) mixins; - /* List of mixin classes, used for generation + ClassList mixins; /* List of mixin classes, used for generation * of method call chains. */ - LIST_DYNAMIC(struct Class *) mixinSubs; - /* List of classes that this class is mixed + VarClassList mixinSubs; /* List of classes that this class is mixed * into, used to ensure deletion of dependent * entities happens properly when the class * itself is deleted. */ @@ -320,8 +326,8 @@ typedef struct Class { * of each piece of attached metadata. This * field starts out as NULL and is only * allocated if metadata is attached. */ - struct CallChain *constructorChainPtr; - struct CallChain *destructorChainPtr; + CallChain *constructorChainPtr; + CallChain *destructorChainPtr; Tcl_HashTable *classChainCache; /* Places where call chains are stored. For * constructors, the class chain is always @@ -355,15 +361,12 @@ typedef struct Class { PropertyStorage properties; /* Information relating to the lists of * properties that this class *claims* to * support. */ -} Class; +}; /* - * The foundation of the object system within an interpreter contains - * references to the key classes and namespaces, together with a few other - * useful bits and pieces. Probably ought to eventually go in the Interp - * structure itself. + * Master epoch counter for making unique IDs for objects that can be compared + * cheaply. */ - typedef struct ThreadLocalData { Tcl_Size nsCount; /* Epoch counter is used for keeping * the values used in Tcl_Obj internal @@ -373,19 +376,17 @@ typedef struct ThreadLocalData { * generally cross threads). */ } ThreadLocalData; -typedef struct Foundation { - Tcl_Interp *interp; +/* + * The foundation of the object system within an interpreter contains + * references to the key classes and namespaces, together with a few other + * useful bits and pieces. Probably ought to eventually go in the Interp + * structure itself. + */ +struct Foundation { + Tcl_Interp *interp; /* The interpreter this is attached to. */ Class *objectCls; /* The root of the object system. */ Class *classCls; /* The class of all classes. */ Tcl_Namespace *ooNs; /* ::oo namespace. */ - Tcl_Namespace *defineNs; /* Namespace containing special commands for - * manipulating objects and classes. The - * "oo::define" command acts as a special kind - * of ensemble for this namespace. */ - Tcl_Namespace *objdefNs; /* Namespace containing special commands for - * manipulating objects and classes. The - * "oo::objdefine" command acts as a special - * kind of ensemble for this namespace. */ Tcl_Namespace *helpersNs; /* Namespace containing the commands that are * only valid when executing inside a * procedural method. */ @@ -403,17 +404,19 @@ typedef struct Foundation { Tcl_Obj *clonedName; /* Shared object containing the name of a * "<cloned>" pseudo-constructor. */ Tcl_Obj *defineName; /* Fully qualified name of oo::define. */ -} Foundation; + Tcl_Obj *myName; /* The "my" shared object. */ +}; /* - * A call context structure is built when a method is called. It contains the - * chain of method implementations that are to be invoked by a particular - * call, and the process of calling walks the chain, with the [next] command - * proceeding to the next entry in the chain. + * The number of MInvoke records in the CallChain before we allocate + * separately. */ - #define CALL_CHAIN_STATIC_SIZE 4 +/* + * Information relating to the invocation of a particular method implementation + * in a call chain. + */ struct MInvoke { Method *mPtr; /* Reference to the method implementation * record. */ @@ -422,7 +425,10 @@ struct MInvoke { * NULL, it was added by the object. */ }; -typedef struct CallChain { +/* + * The cacheable part of a call context. + */ +struct CallChain { Tcl_Size objectCreationEpoch;/* The object's creation epoch. Note that the * object reference is not stored in the call * chain; it is in the call context. */ @@ -433,13 +439,19 @@ typedef struct CallChain { int flags; /* Assorted flags, see below. */ Tcl_Size refCount; /* Reference count. */ Tcl_Size numChain; /* Size of the call chain. */ - struct MInvoke *chain; /* Array of call chain entries. May point to + MInvoke *chain; /* Array of call chain entries. May point to * staticChain if the number of entries is * small. */ - struct MInvoke staticChain[CALL_CHAIN_STATIC_SIZE]; -} CallChain; + MInvoke staticChain[CALL_CHAIN_STATIC_SIZE]; +}; -typedef struct CallContext { +/* + * A call context structure is built when a method is called. It contains the + * chain of method implementations that are to be invoked by a particular + * call, and the process of calling walks the chain, with the [next] command + * proceeding to the next entry in the chain. + */ +struct CallContext { Object *oPtr; /* The object associated with this call. */ Tcl_Size index; /* Index into the call chain of the currently * executing method implementation. */ @@ -448,33 +460,32 @@ typedef struct CallContext { * method call or a continuation via the * [next] command. */ CallChain *callPtr; /* The actual call chain. */ -} CallContext; +}; /* * Bits for the 'flags' field of the call chain. */ - -#define PUBLIC_METHOD 0x01 /* This is a public (exported) method. */ -#define PRIVATE_METHOD 0x02 /* This is a private (class's direct instances +enum TclOOCallChainFlags { + PUBLIC_METHOD = 0x01, /* This is a public (exported) method. */ + PRIVATE_METHOD = 0x02, /* This is a private (class's direct instances * only) method. Supports itcl. */ -#define OO_UNKNOWN_METHOD 0x04 /* This is an unknown method. */ -#define CONSTRUCTOR 0x08 /* This is a constructor. */ -#define DESTRUCTOR 0x10 /* This is a destructor. */ -#define TRUE_PRIVATE_METHOD 0x20 - /* This is a private method only accessible + OO_UNKNOWN_METHOD = 0x04, /* This is an unknown method. */ + CONSTRUCTOR = 0x08, /* This is a constructor. */ + DESTRUCTOR = 0x10, /* This is a destructor. */ + TRUE_PRIVATE_METHOD = 0x20 /* This is a private method only accessible * from other methods defined on this class * or instance. [TIP #500] */ +}; #define SCOPE_FLAGS (PUBLIC_METHOD | PRIVATE_METHOD | TRUE_PRIVATE_METHOD) /* * Structure containing definition information about basic class methods. */ - -typedef struct { +struct DeclaredClassMethod { const char *name; /* Name of the method in question. */ int isPublic; /* Whether the method is public by default. */ Tcl_MethodType definition; /* How to call the method. */ -} DeclaredClassMethod; +}; /* *---------------------------------------------------------------- @@ -482,7 +493,7 @@ typedef struct { *---------------------------------------------------------------- */ -MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); +MODULE_SCOPE int TclOOInit(Tcl_Interp *interp); MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOObjDefObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineConstructorObjCmd; @@ -498,11 +509,14 @@ MODULE_SCOPE Tcl_ObjCmdProc TclOODefineClassObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefineObjSelfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOODefinePrivateObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOODefinePropertyCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOUnknownDefinition; MODULE_SCOPE Tcl_ObjCmdProc TclOOCopyObjectCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOONextToObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOSelfObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOInfoObjectPropCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOInfoClassPropCmd; /* * Method implementations (in tclOOBasic.c). @@ -517,6 +531,7 @@ MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_Eval; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_LinkVar; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_Unknown; MODULE_SCOPE Tcl_MethodCallProc TclOO_Object_VarName; +MODULE_SCOPE Tcl_MethodCallProc TclOO_Configurable_Configure; /* * Private definitions, some of which perhaps ought to be exposed properly or @@ -528,14 +543,14 @@ MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr); MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr); MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp, Object *useThisObj); -MODULE_SCOPE int TclMethodIsType(Tcl_Method method, +MODULE_SCOPE int TclMethodIsType(Tcl_Method method, const Tcl_MethodType *typePtr, void **clientDataPtr); MODULE_SCOPE Tcl_Method TclNewInstanceMethod(Tcl_Interp *interp, Tcl_Object object, Tcl_Obj *nameObj, int flags, const Tcl_MethodType *typePtr, void *clientData); -MODULE_SCOPE Tcl_Method TclNewMethod(Tcl_Interp *interp, Tcl_Class cls, +MODULE_SCOPE Tcl_Method TclNewMethod(Tcl_Class cls, Tcl_Obj *nameObj, int flags, const Tcl_MethodType *typePtr, void *clientData); @@ -557,14 +572,13 @@ MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr); MODULE_SCOPE void TclOODeleteDescendants(Tcl_Interp *interp, Object *oPtr); MODULE_SCOPE void TclOODelMethodRef(Method *method); -MODULE_SCOPE Tcl_Obj * TclOOGetAllClassProperties(Class *clsPtr, - int writable, int *allocated); -MODULE_SCOPE Tcl_Obj * TclOOGetAllObjectProperties(Object *oPtr, - int writable, int *allocated); MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr, Tcl_Obj *methodNameObj, int flags, Object *contextObjPtr, Class *contextClsPtr, Tcl_Obj *cacheInThisObj); +MODULE_SCOPE Class * TclOOGetClassDefineCmdContext(Tcl_Interp *interp); +MODULE_SCOPE Class * TclOOGetClassFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr); MODULE_SCOPE Tcl_Namespace *TclOOGetDefineContextNamespace( Tcl_Interp *interp, Object *oPtr, int forClass); MODULE_SCOPE CallChain *TclOOGetStereotypeCallChain(Class *clsPtr, @@ -583,10 +597,13 @@ MODULE_SCOPE void TclOOInitInfo(Tcl_Interp *interp); MODULE_SCOPE int TclOOInvokeContext(void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE Tcl_Var TclOOLookupObjectVar(Tcl_Interp *interp, + Tcl_Object object, Tcl_Obj *varName, + Tcl_Var *aryPtr); MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp, Tcl_ObjectContext context, Tcl_Size objc, Tcl_Obj *const *objv, Tcl_Size skip); -MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr, +MODULE_SCOPE void TclOONewBasicMethod(Class *clsPtr, const DeclaredClassMethod *dcm); MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr); MODULE_SCOPE void TclOOReleaseClassContents(Tcl_Interp *interp, @@ -601,7 +618,22 @@ MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp, CallChain *callPtr); MODULE_SCOPE void TclOOStashContext(Tcl_Obj *objPtr, CallContext *contextPtr); +MODULE_SCOPE Tcl_Obj * TclOOGetAllObjectProperties(Object *oPtr, + int writable); MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); +MODULE_SCOPE Tcl_Obj * TclOOGetPropertyList(PropertyList *propList); +MODULE_SCOPE void TclOOReleasePropertyStorage(PropertyStorage *propsPtr); +MODULE_SCOPE void TclOOInstallReadableProperties(PropertyStorage *props, + Tcl_Size objc, Tcl_Obj *const objv[]); +MODULE_SCOPE void TclOOInstallWritableProperties(PropertyStorage *props, + Tcl_Size objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int TclOOInstallStdPropertyImpls(void *useInstance, + Tcl_Interp *interp, Tcl_Obj *propName, + int readable, int writable); +MODULE_SCOPE void TclOORegisterProperty(Class *clsPtr, + Tcl_Obj *propName, int mayRead, int mayWrite); +MODULE_SCOPE void TclOORegisterInstanceProperty(Object *oPtr, + Tcl_Obj *propName, int mayRead, int mayWrite); /* * Include all the private API, generated from tclOO.decls. |