On Fri, 13 October 2000, Daniel Wickstrom wrote:

>     Jiang> TclObject (tcl.lang.TclObject, Java class) <contains>
>     Jiang>          CObject (tcl.lang.CObject, Java class) <contains> 
>     Jiang>                    a pointer to Tcl_Obj
> 
> In the case above what does the Tcl_Obj represent? Is it just a native
> tcl object such as a string, a list, or an array?

Yes.  Typically, Tcl_Obj is a native C version of the Tcl list, array, int, ...  But 
not always.  See the end of the email for an example.

>     Jiang> Tcl_Object <contains> 
>     Jiang>         Tcl_Obj <contains> 
>     Jiang>              Tcl_Object <contains>
>     Jiang>                  Tcl_Obj <contains> ...
> 
> Yeh this was confusing me, especially when I started thinking about
> the changes you made to the refcounting code.

It is best to think that this never happens when trying to understand the general 
structure of the code.  Otherwise, one can go quite insane :)

>     Jiang> TclBlend is smart enough to detect such attempt.  When it
>     Jiang> is detected, TclBlend removes the extra level containment
>     Jiang> so that most of the time you will have either:
> 
> Is that what's going on in the setInternalRep method of the TclObject
> class?  It checks for a CObject internal rep and creates a new
> reference to the current TclObject instance if the new rep is not of
> type CObject.  Where else is this detection done?

Yes.  It is guarding against recursion.  Also see javaObj.c where it guards against 
having a

Tcl_Obj <contains>
   TclObject <contains>
       Tcl_Obj <contains>
           ...

type of recursion.

> My initial impression is that this is the correct way to do it, though
> it can be tricky to get all of the reference counting right.

The rule of using reference counting properly is that if you want to keep the 
TclObject across calls to the Tcl interpreter, you must preserve it and release it 
later.

However, TclBlend didn't need this rule before because it implicitly preserved and 
released Tcl_Obj.  There are may be several places in the TclJava layer that contain 
reference counting bugs.  These bugs typically results in core dumps because they 
would cause reference to already free'ed Tcl_Obj to be used.

One example was in the ReflectObject, which allows you to create:

Tcl_Obj <contains> (1)
   TclObject <contains>
       ReflectObject <contains>
           TclObject <contains>
               Tcl_Obj (2)

Note that the above does have Tcl_Obj (1) containing another Tcl_Obj (2), which is a 
form of recursive containment.  This type of recursion is not detected by TclBlend 
because you put another level of indirection in the chain of containment.

The bug was that the ReflectObject did not increment the reference count of the 
TclObject even though the ReflectObject is going to keep the TclObject for the long 
term by putting it in a Hastable for use later.  The lowest level Tcl_Obj (2) can be 
free'ed by Tcl interpreter when its reference count decreases to zero.  Then later, 
the ReflectObject attempts to use the pointer to the free'ed Tcl_Obj (2), which can 
cause a segmentation fault.

There may be other places in TclJava, where the above type of thing happen.

-- Jiang Wu
   [EMAIL PROTECTED]


----------------------------------------------
[EMAIL PROTECTED] is brought to you by 
the Stanford Alumni Association and Critical Path.

----------------------------------------------------------------
The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:    send mail to [EMAIL PROTECTED]  
                 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
                 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com

Reply via email to