Skip to content
Prev 59927 / 63424 Next

Clearing attributes returns ALTREP, serialize still saves them

Ok, a bit more:

The relevant bit in serialize.c that I can see is:


if (ALTREP(s) && stream->version >= 3) {

SEXP info = ALTREP_SERIALIZED_CLASS(s);

SEXP state = ALTREP_SERIALIZED_STATE(s);

if (info != NULL && state != NULL) {

   int flags = PackFlags(ALTREP_SXP, LEVELS(s), OBJECT(s), 0, 0);

   PROTECT(state);

   PROTECT(info);

   OutInteger(stream, flags);

   WriteItem(info, ref_table, stream);

  * WriteItem(state, ref_table, stream);*

   WriteItem(ATTRIB(s), ref_table, stream);

   UNPROTECT(2); /* state, info */

   return;

}
/* else fall through to standard processing */
    }

And in the wrapper altclass, we have:

*static SEXP wrapper_Serialized_state(SEXP x)*
{
    return CONS(*WRAPPER_WRAPPED(x)*, WRAPPER_METADATA(x));
}

So whats happening, is that the data isn't being written out during the
WriteItem(ATTRIB(s)), that actually has the correct attribute value. Its
being written out in the bolden line above that, the state, which has the
wrapped SEXP, which ITSELF has the attributes on it, but is not an ALTREP,
so that goes through standard processing, which writes out the attributes
as normal.

So that, I believe, is what needs to change. One possibility is that
wrapper_Serialized_state can be made smarter so that the inner attributes
are duplicated and then wiped clean for any that are overridden by the
attributes on the wrapper.  Another option is that the ALTREP WriteItem
section could be made smarter, but that seems less robust.

Finally, the wrapper might be able to be modified in such a way that
setting the attribute on the wrapper clears taht attribute on the wrapped
value, if present. .

I think making wrapper_Serialized_state smarter is the right way to attack
this, and thats the first thing I'll try when I get to it, but if someone
tackles it before me hopefully this digging helped some.

Best,
~G

On Fri, Jul 2, 2021 at 10:18 PM Gabriel Becker <gabembecker at gmail.com>
wrote: