All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.