The beginnings of freezing and thawing are going in, which is good -- this
should get us to PMC constants in the bytecode files, and proper
over-the-wire freeze/thaw stuff. We're a bit raw at the moment, which is
fine, so I wanted to give a heads up as to where things are moving, what
needs doing, and things to keep in mind as you write PMC classes.
Numbered, mainly for easy referral later:

1) When freezing a PMC, the result should *always* be a PMC. Even if you
know your class only holds a lower level X, for whatever value X might be,
it still needs to be a full PMC in the data stream.

2) A PMC, when frozen, must maintain its internal PMC structure in the
data stream. That means if you have a hash of PMCs, you have to store each
PMC (via the freeze API) in the data stream. It's possible that they may
be shared with other PMCs (whether your PMC class knows it or not) in the
data stream and must be thawed in a way that maintains that sharing.

3) So long as the constraints of #1 and #2 are met, PMCs can freeze their
internal data any way they want. If pushing out the integer 3 in the
stream is enough to encode "It was a dark and stormy night" well, good for
you.

4) Don't count on the order PMCs are frozen, nor on the order that they
are reconstituted.

5) The vtable API for freeze/thaw is as follows:

freeze(thingie *freezecontext) - called when a PMC should freeze itself
thaw(thingie *thawcontext) - called when an empty PMC should reconstitute
                             itself
thawfinish() - Called on each PMC after the full stream of PMCs has been
               thawed

We don't, I realized, need mark as a vtable method for freezing or
thawing.

6) The freeze/thaw library needs to consist of the following calls (some
of which we already have)

freezepmc(pmc *, name)
freezestring(string *, name)
freezeint(int, name)
freezefloat(float, name)
startlist(name)
endlist(name)
startpairs(name)
endpairs(name)
addpmctolist(pmc *)

name is a string pointer or null if there is no name. (There should be a
context pointer there too, but this is pine and editing's a pain) These
are all the functions that the PMC freeze routine calls to save off parts
of themselves, *not* anything that opcodes call.

The freezepmc routine here, it should be noted, acts as a mark routine of
sorts, which is why we don't need one on the PMC itself for this.
addpmctolist() just throws a PMC on the list of PMCs to be frozen to this
stream without actually freezing it at the current spot in the stream. (It
could, for example, be used to put the package stash on the list without
actually hanging it off the PMC making the add call)

Leo's idea of passing in a struct as part of the freeze is a good one, as
one of the things hanging off it can be a vtable with all these calls in
it, so we can have multiple freeze methods active at once. (Arguments as
to why that's a good thing are separate and I don't want to go there :)


This clear enough? We're most of the way there, we just need to make a few
alterations in the vtable names and functions, and some rejigging of the
draft freeze/thaw stuff that's in now.

                                        Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                      teddy bears get drunk

Reply via email to