There seems to be a problem with how TclObject and Tcl_Obj are related.
Regardless of what we do to fix the GC problem, using queue or using
reference counting, this problem can lead to very undesirable behavior.  See
the stack overflow problem posted before.

Tcl_Obj and TclObject should really be peers to each other.  Logically, they
should be on equal footing.  Tcl_Obj is used in C functions to access the
real data (the internal representation), while TclObject is used in Java to
access the real data (the internal representation).  The internal
representation may be in C or Java.

The whole thing should look like this:

  Tcl_Obj   <-- equivalent to --> TclObject
     |                               |
      \--------> internal rep <-----/
                    |
                    V
           Java Object <or> C Object

The current implementation makes TclObject dual purpose.  Sometimes, a
TclObject is just a Java version of Tcl_Obj.  Other times, a TclObject is
the internal rep of a Tcl_Obj.  This dual role causes some confusion.  Same
thing is true for Tcl_Obj.  Sometimes, Tcl_Obj is a C reference to
TclObject.  Other times, it is an internal rep of a TclObject.

Take a look at TclObject.setInternalRep() on how TclBlend tries to toggle
the role played by a Tcl_Obj from being an internal rep into a C reference
to TclObject.  But, where is the similar code for toggling the roles played
by a TclObject?

We really care about this issue because the C Tcl interpreter makes the
basic assumption that a Tcl_Obj can change its internal rep into different
forms.  Suppose the interpreter gives us a Tcl_Obj, we are free to convert
its internal rep into different forms, integer, string, or list.  The
interpreter should still have the same access to the data regardless of its
internal form.  This doesn't happen in TclBlend.  Take this example:

        TclObject (A) <contains --> Tcl_Obj (B) 
                                   <contains>
                                      |
                                      V
                             C string internal rep (C)

TclBlend returns (A) into the Java code to represent (B).  The interpreter
understands (B).  Assuming the original internal rep (C) is a simple C
string containing an integer.  TclBlend is free to alter the internal rep
into a TclInteger.  We now have:

       TclObject (A) <-- is contained by> Tcl_Obj (B)
       <contains>
          |
          V
    TclInteger (D)

The new internal rep is a Java object, TclInteger (D).  So far so good.
Let's do the internal rep conversion one more time.  This time, let's make
the internal rep into a list using TclList.setListFromAny.  We end up with:

       TclObject (A) <-- is contained by> Tcl_Obj (B)
           |
           V
       <contains --> Tcl_Obj (E)
                     <contains>
                         |
                         V
                    C Tcl_List internal rep (F)

This is wrong.  We did not arrive back at where we started.  The Tcl
interpreter and the Java program are looking at different objects now.  I
was testing out this behavior and found the stack overflow bug.  In
addition, the memory loss reported by Dan is also related to this problem.
Object (E) is wrongly introduced.  The interpreter does not know about (E).
The interpreter is expecting object (B) to change form instead.  Therefore,
the interpreter would clean up (B) and leave (E) to dangle.

The correct answer to the above conversion should be:

        TclObject (A) <contains --> Tcl_Obj (B) 
                                   <contains>
                                      |
                                      V
                                  C Tcl_List internal rep (F)

If this were the case, then there would be no memory loss.

-- Jiang Wu
   [EMAIL PROTECTED]



----------------------------------------------------------------
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