qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>, Fam Zheng <famz@redhat.com>,
	Eduardo Habkost <ehabkost@redhat.com>,
	"open list:Block layer core" <qemu-block@nongnu.org>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Michael Roth <mdroth@linux.vnet.ibm.com>,
	Jan Kiszka <jan.kiszka@siemens.com>,
	Jason Wang <jasowang@redhat.com>,
	qemu-devel@nongnu.org, Vincenzo Maffione <v.maffione@gmail.com>,
	Luiz Capitulino <lcapitulino@redhat.com>,
	Gerd Hoffmann <kraxel@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Igor Mammedov <imammedo@redhat.com>,
	Giuseppe Lettieri <g.lettieri@iet.unipi.it>,
	Luigi Rizzo <rizzo@iet.unipi.it>,
	Samuel Thibault <samuel.thibault@ens-lyon.org>
Subject: Re: [Qemu-devel] [PATCH v2 14/19] qapi: Don't special-case simple union wrappers
Date: Thu, 3 Mar 2016 09:12:27 -0700	[thread overview]
Message-ID: <56D8626B.3060509@redhat.com> (raw)
In-Reply-To: <877fhj6d3t.fsf@blackfin.pond.sub.org>

[-- Attachment #1: Type: text/plain, Size: 7024 bytes --]

On 03/03/2016 03:59 AM, Markus Armbruster wrote:
> Eric Blake <eblake@redhat.com> writes:
> 
>> Simple unions were carrying a special case that hid their 'data'
>> QMP member from the resulting C struct, via the hack method
>> QAPISchemaObjectTypeVariant.simple_union_type().  But using the
>> work we started by unboxing flat union and alternate branches, we
>> expose the simple union's implicit type in qapi-types.h as an
>> anonymous type, and drop our last use of the hack.
>>

>> All clients of simple unions have to adjust from using su->u.member
>> to now using su->u.member.data;
> 
> By now, a reader not familiar with the code may wonder why this is an
> improvement.  It is, because
> 
> * it removes an asymmetry between QAPI's QMP side and QAPI's C side
>   (both now have 'data'), and
> 
> * it hopefully turns simple unions into sugar for flat unions as
>   described in qapi-code-gen.txt, where before their equivalence only
>   applied to the QMP side, not to the C side.
> 
> And that's well worth having to type .data in a few places.
> 
> Can we work that into the commit message?

Yes, definitely.


>> +++ b/scripts/qapi-types.py
>> @@ -122,14 +122,24 @@ def gen_variants(variants):
>>                  c_name=c_name(variants.tag_member.name))
>>
>>      for var in variants.variants:
>> -        # Ugly special case for simple union TODO get rid of it
>> -        simple_union_type = var.simple_union_type()
>> -        typ = simple_union_type or var.type
>> -        ret += mcgen('''
>> +        if (isinstance(var.type, QAPISchemaObjectType) and
>> +                var.type.is_implicit()):
> 
> Uh, this condition is exactly var.type.simple_union_type() != None.  I'm
> afraid we still have a special case.

The isinstance() is necessary because of alternates - a builtin type
branch to an alternate is implicit, but must be emitted directly, only
object types can be unboxed.  And, down the road, if we DO add anonymous
branches to a flat union, then this condition will also work for that
anonymous branch (in fact, I have it in my local tree, just not part of
this series).  Yes, that's the part of the commit message you said I
could drop, but I'll have to come up with some way to highlight that
potential in the commit message.

> 
> Special treatment for simple unions: instead of a member
> 

Rather, special treatment for an implicit object branch (right now, only
simple unions have implicit object branches, but an anonymous branch to
a flat union would also qualify for this treatment):

>     TypeOfBranch name_of_branch;
> 
> we generate one
> 
>     struct {
>         TypeOfBranch data;
>     } name_of_branch;
> 

> Without the special case, we'd get
> 
>     typedef struct :obj-intList-wrapper :obj-intList-wrapper;
> 
>     struct :obj-intList-wrapper {
>         intList *data;
>     } :obj-intList-wrapper;
> 
>     struct UserDefNativeListUnion {
>         UserDefNativeListUnionKind type;
>         union { /* union tag is @type */
>             :obj-intList-wrapper integer;
>             [more of the same...]
>         } u;
>     }
> 
> except QAPISchemaObjectType.c_name() would refuse to cooperate in
> creating this nonsense.
> 
> Conclusion: you replace one special case by another one.  The
> improvement is in that the new special case is less special.  Instead of
> "if simple union variant, do something else", we now have
> 
>     Use the C type corresponding to the type, except when it's an
>     implicit object type, use an anonymous struct type, because we don't
>     have a C type then.

Yes, exactly.  Words I should use in my commit message :)

> 
> Should we have a C type even then?  We'd need to give it a reserved
> name.

I found it easier to inline an anonymous struct than to think about how
to create a reserved name.  Maybe that decision of mine can be revisited.

> 
> On first glance, the new special case is just as special at the old one:
> it applies to simple unions.  But that's not necessarily so.  We could
> make use of it elsewhere if we wanted.  We'd have to factor the code out
> of the "for variants" loop, of course.  In other words, it's still
> special, but its specialness is less arbitrary.  That's why it's an
> improvement.
> 
> Next is the visit update for this change of the type layout.
> 
> Note that direct_name is only used when !typ.is_implicit(), and
> implicit_name is only used when typ.is_implicit().
> 
> Further note that despite its name, gen_visit_members_call() doesn't
> generate a call when typ.is_implicit().
> 
> Separate function for implicit type?

By the end of the series, we have two callers of the helper; if we split
to two helpers, then both callers have to test for .is_implicit() (and
it gets worse if I find a third place to use this helper in a later
patch).  My goal was to make the helper do as much as possible to
simplify the callers, but I got stuck at how to pass the difference
between a direct-use prefix vs. an implicit-use prefix.

Again, maybe the idea of creating a named C type for implicit types
would make this simpler.

> After:
> 
>        if typ.is_empty():
>            pass
>        elif typ.is_implicit():
>            assert implicit_name
>            assert not typ.variants
>            ret += gen_visit_members(typ.members, prefix=implicit_name)
>        else:
>            ret += mcgen('''
>        visit_type_%(c_type)s_members(v, %(c_name)s, &err);
>    ''',
>                         c_type=typ.c_name(), c_name=direct_name)
> 
> Special treatment for member of implicit type: generate inline code to
> visit its members, because visit_type_T_members() doesn't exist then.
> 
> Should it exist?

Only if we create a named C type for uses of implicit types.

>> +++ b/backends/baum.c
>> @@ -567,7 +567,7 @@ static CharDriverState *chr_baum_init(const char *id,
>>                                        ChardevReturn *ret,
>>                                        Error **errp)
>>  {
>> -    ChardevCommon *common = backend->u.braille;
>> +    ChardevCommon *common = backend->u.braille.data;
>>      BaumDriverState *baum;
>>      CharDriverState *chr;
>>      brlapi_handle_t *handle;
> 
> Many trivial updates like this one.  The only interesting question is
> whether you got them all.  What did you do to find them?

The compiler caught most of them.  For a few others, particularly under
net/, it was search and replace (basically, the compiler warned me about
some uses of NetClientOptions now being different, so I then grepped for
ALL uses of NetClientOptions to pick up the ones that I'm not set up to
compile).

I may have missed something, but it is a compiler error, so someone
would flag it pretty quickly if they are set up to compile code that I
am not.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

  reply	other threads:[~2016-03-03 16:12 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-25 23:38 [Qemu-devel] [PATCH v2 00/19] easier unboxed visits/qapi implicit types Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 01/19] qapi: Rename 'fields' to 'members' in internal interface Eric Blake
2016-03-02 17:15   ` Markus Armbruster
2016-03-02 20:05     ` Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 02/19] qapi-visit: Expose visit_type_FOO_members() Eric Blake
2016-03-02 17:24   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 03/19] qapi: Update docs to match recent generator changes Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 04/19] chardev: Shorten references into ChardevBackend Eric Blake
2016-03-02 17:55   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 05/19] util: Shorten references into SocketAddress Eric Blake
2016-03-02 18:03   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 06/19] ui: Shorten references into InputEvent Eric Blake
2016-03-01 15:32   ` [Qemu-devel] [PATCH v2.5 " Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 07/19] qapi: Avoid use of 'data' member of qapi unions Eric Blake
2016-03-02 18:18   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 08/19] chardev: Drop useless ChardevDummy type Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 09/19] qapi: Drop useless 'data' member of unions Eric Blake
2016-03-02 18:30   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 10/19] qapi-visit: Factor out gen_visit_members_call() Eric Blake
2016-03-02 18:53   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 11/19] qapi: Add type.is_empty() helper Eric Blake
2016-03-02 19:04   ` Markus Armbruster
2016-03-02 20:16     ` Eric Blake
2016-03-03  7:08       ` Markus Armbruster
2016-03-02 23:04     ` Eric Blake
2016-03-03  7:18       ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 12/19] qapi: Fix command with named empty argument type Eric Blake
2016-03-03  8:54   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 13/19] qapi-visit: Simplify visit of empty branch in union Eric Blake
2016-03-03  9:14   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 14/19] qapi: Don't special-case simple union wrappers Eric Blake
2016-03-03 10:59   ` Markus Armbruster
2016-03-03 16:12     ` Eric Blake [this message]
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 15/19] qapi-visit: Move error check into gen_visit_members_call() Eric Blake
2016-03-03 11:56   ` Markus Armbruster
2016-03-04 14:27     ` Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 16/19] qapi: Allow anonymous base for flat union Eric Blake
2016-03-03 13:04   ` Markus Armbruster
2016-03-04 14:32     ` Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 17/19] qapi: Use anonymous base in SchemaInfo Eric Blake
2016-03-03 13:06   ` Markus Armbruster
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 18/19] qapi: Use anonymous base in CpuInfo Eric Blake
2016-03-03 13:08   ` Markus Armbruster
2016-03-04 14:35     ` Eric Blake
2016-02-25 23:38 ` [Qemu-devel] [PATCH v2 19/19] qapi: Make c_type() more OO-like Eric Blake
2016-03-03 13:29   ` Markus Armbruster
2016-03-04 14:37     ` Eric Blake
2016-03-01 15:02 ` [Qemu-devel] [PATCH v2 00/19] easier unboxed visits/qapi implicit types Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56D8626B.3060509@redhat.com \
    --to=eblake@redhat.com \
    --cc=armbru@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=famz@redhat.com \
    --cc=g.lettieri@iet.unipi.it \
    --cc=imammedo@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=jasowang@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rizzo@iet.unipi.it \
    --cc=samuel.thibault@ens-lyon.org \
    --cc=v.maffione@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).