On 05/03/2016 05:53 AM, Markus Armbruster wrote:
> Okay, I'm confused.
>
> Consider BlockdevRef, defined as
>
> { 'alternate': 'BlockdevRef',
> 'data': { 'definition': 'BlockdevOptions',
> 'reference': 'str' } }
>
> where BlockdevOptions is a (flat) union. Let's clone a BlockdevRef
> holding a str. Sequence of calls:
>
> qapi_BlockdevRef_clone(src)
> qapi_clone_visitor_new(src)
> // qcv->depth is now 0
> visit_type_BlockdevRef(v, NULL, &dst, &error_abort)
> visit_start_alternate(v, NULL, &dst,
> sizeof(BlockdevRef), true, &error_abort)
> qapi_clone_start_alternate(v, NULL, &dst,
> sizeof(BlockdevRef), true, &error_abort)so far, so good, > qapi_clone_start_struct(v, NULL, &dst, > sizeof(BlockdevRef), &error_abort) Not reached if it holds a string. qapi_clone_start_alternate() sets dst->type to QTYPE_QSTRING, but qapi_clone_start_struct() is only used for QTYPE_QDICT. > // does not increment qcv->depth > visit_type_str(v, NULL, &dst->u.references, &error_abort) > qapi_clone_type_str(v, NULL, &dst->u.references, &error_abort) > assert(qcv->depth) // why does this hold? Either we call: visit_start_alternate() visit_start_struct(NULL) visit_end_struct() visit_end_alternate() or we elide the inner struct visit because the alternate's branch is scalar. Either way, we only need +1 to the depth over the entire alternate, because we only need 1 level of g_memdup() at the time we first enter the alternate. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
