From 2453c29945269ab4734362d7613c187d3e6e8fbb Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 25 Apr 2021 10:56:32 +0000 Subject: Documenting our reference count management --- doc/Method.3 | 26 +++++++++++++++++++++++++- doc/NRE.3 | 19 +++++++++++++++++++ doc/Namespace.3 | 16 ++++++++++++++-- doc/Object.3 | 7 ++++++- doc/ObjectType.3 | 22 ++++++++++++++++++++++ 5 files changed, 86 insertions(+), 4 deletions(-) diff --git a/doc/Method.3 b/doc/Method.3 index 9e636a1..577cd54 100644 --- a/doc/Method.3 +++ b/doc/Method.3 @@ -258,8 +258,32 @@ also return TCL_ERROR; it should return TCL_OK otherwise. The \fIoldClientData\fR field to a Tcl_CloneProc gives the value from the method being copied from, and the \fInewClientDataPtr\fR field will point to a variable in which to write the value for the method being copied to. +.SH "REFERENCE COUNT MANAGEMENT" +.PP +The \fInameObj\fR argument to \fBTcl_NewMethod\fR and +\fBTcl_NewInstanceMethod\fR (when non-NULL) will have its reference count +incremented if there is no existing method with that name in that +class/object. +.PP +The result of \fBTcl_MethodName\fR is a value with a reference count of at +least one. It should not be modified without first duplicating it (with +\fBTcl_DuplicateObj\fR). +.PP +The values in the first \fIobjc\fR values of the \fIobjv\fR argument to +\fBTcl_ObjectContextInvokeNext\fR are assumed to have a reference count of at +least 1; the containing array is assumed to endure until the next method +implementation (see \fBnext\fR) returns. Be aware that methods may +\fByield\fR; if any post-call actions are desired (e.g., decrementing the +reference count of values passed in here), they must be scheduled with +\fBTcl_NRAddCallback\fR. +.PP +The \fIcallProc\fR of the \fBTcl_MethodType\fR structure takes values of at +least reference count 1 in its \fIobjv\fR argument. It may add its own +references, but must not decrement the reference count below that level; the +caller of the method will decrement the reference count once the method +returns properly (and the reference will be held if the method \fByield\fRs). .SH "SEE ALSO" -Class(3), oo::class(n), oo::define(n), oo::object(n) +Class(3), NRE(3), oo::class(n), oo::define(n), oo::object(n) .SH KEYWORDS constructor, method, object diff --git a/doc/NRE.3 b/doc/NRE.3 index 20efe2f..011e100 100644 --- a/doc/NRE.3 +++ b/doc/NRE.3 @@ -227,6 +227,25 @@ int Any function comprising a routine can push other functions, making it possible implement looping and sequencing constructs using the function stack. .PP +.SH "REFERENCE COUNT MANAGEMENT" +.PP +The first \fIobjc\fR values in the \fIobjv\fR array passed to the functions +\fBTcl_NRCallObjProc\fR, \fBTcl_NREvalObjv\fR, and \fBTcl_NRCmdSwap\fR should +have a reference count of at least 1; they may have additional references +taken during the execution. +.PP +The \fIobjPtr\fR argument to \fBTcl_NREvalObj\fR and \fBTcl_NRExprObj\fR +should have a reference count of at least 1, and may have additional +references taken to it during execution. +.PP +The \fIresultObj\fR argument to \fBTcl_NRExprObj\fR should be an unshared +object. +.PP +Use \fBTcl_NRAddCallback\fR to schedule any required final decrementing of the +reference counts of arguments to any of the other functions on this page, as +with any other post-processing step in the non-recursive execution engine. +.PP +The .SH "SEE ALSO" Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3) .SH KEYWORDS diff --git a/doc/Namespace.3 b/doc/Namespace.3 index a037442..49b772c 100644 --- a/doc/Namespace.3 +++ b/doc/Namespace.3 @@ -46,10 +46,10 @@ Tcl_Command \fBTcl_FindCommand\fR(\fIinterp, name, contextNsPtr, flags\fR) .sp Tcl_Obj * -\fBTcl_GetNamespaceUnknownHandler(\fIinterp, nsPtr\fR) +\fBTcl_GetNamespaceUnknownHandler\fR(\fIinterp, nsPtr\fR) .sp int -\fBTcl_SetNamespaceUnknownHandler(\fIinterp, nsPtr, handlerPtr\fR) +\fBTcl_SetNamespaceUnknownHandler\fR(\fIinterp, nsPtr, handlerPtr\fR) .SH ARGUMENTS .AS Tcl_NamespaceDeleteProc allowOverwrite in/out .AP Tcl_Interp *interp in/out @@ -159,6 +159,18 @@ for the namespace, or NULL if none is set. \fBTcl_SetNamespaceUnknownHandler\fR sets the unknown command handler for the namespace. If \fIhandlerPtr\fR is NULL, then the handler is reset to its default. +.SH "REFERENCE COUNT MANAGEMENT" +.PP +The \fIobjPtr\fR argument to \fBTcl_AppendExportList\fR should be an +unshared object, as it will be modified by this function. The +reference count of \fIobjPtr\fR will not be altered. +.PP +\fBTcl_GetNamespaceUnknownHandler\fR returns a possibly shared value. +Its reference count should be incremented if the value is to be +retained. +.PP +The \fIhandlerPtr\fR argument to \fBTcl_SetNamespaceUnknownHandler\fR +will have its reference count incremented if it is a non-empty list. .SH "SEE ALSO" Tcl_CreateCommand(3), Tcl_ListObjAppendList(3), Tcl_SetVar(3) .SH KEYWORDS diff --git a/doc/Object.3 b/doc/Object.3 index eadd041..2099552 100644 --- a/doc/Object.3 +++ b/doc/Object.3 @@ -283,7 +283,12 @@ to reduce storage requirements. Reference counting is used to determine when a value is no longer needed and can safely be freed. A value just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR -has \fIrefCount\fR 0. +has \fIrefCount\fR 0, meaning that the object can often be given to a function +like \fBTcl_SetObjResult\fR, \fBTcl_ListObjAppendElement\fR, or +\fBTcl_DictObjPut\fR (as a value) without explicit reference management, all +of which are common use cases. (The latter two require that the the target +list or dictionary be well-formed, but that is often easy to arrange when the +value is being initially constructed.) The macro \fBTcl_IncrRefCount\fR increments the reference count when a new reference to the value is created. The macro \fBTcl_DecrRefCount\fR decrements the count diff --git a/doc/ObjectType.3 b/doc/ObjectType.3 index 67f5174..7e3cc12 100644 --- a/doc/ObjectType.3 +++ b/doc/ObjectType.3 @@ -248,6 +248,28 @@ The \fIfreeIntRepProc\fR implementation must not access the uses of that field during value deletion. The defined tasks for the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR member. +.PP +Note that if a subsidiary value has its reference count reduced to zero +during the running of a \fIfreeIntRepProc\fR, that value may be not freed +immediately, in order to limit stack usage. However, the value will be freed +before the outermost current \fBTcl_DecrRefCount\fR returns. +.SH "REFERENCE COUNT MANAGEMENT" +.PP +The \fIobjPtr\fR argument to \fBTcl_AppendAllObjTypes\fR should be an unshared +value; this function will not modify the reference count of that value, but +will modify its contents. If \fIobjPtr\fR is not (interpretable as) a list, +this function will set the interpreter result and produce an error; using an +unshared empty value is strongly recommended. +.PP +The \fIobjPtr\fR argument to \fBTcl_ConvertToType\fR can have any non-zero +reference count; this function will not modify the reference count, but may +write to the interpreter result on error so values that originate from there +should have an additional reference made before calling this. +.PP +None of the callback functions in the \fBTcl_ObjType\fR structure should +modify the reference count of their arguments, but if the values contain +subsidiary values (e.g., the elements of a list or the keys of a dictionary) +then those subsidiary values may have their reference counts modified. .SH "SEE ALSO" Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3) .SH KEYWORDS -- cgit v0.12