mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2026-04-26 04:43:22 +00:00
There's no reason to do two malloc's for an alternate type visiting
a QAPI struct; let's just inline the struct directly as the C union
branch of the struct.
Surprisingly, no clients were actually using the struct member prior
to this patch outside of the testsuite; an earlier patch in the series
added some testsuite coverage to make the effect of this patch more
obvious.
In qapi.py, c_type() gains a new is_unboxed flag to control when we
are emitting a C struct unboxed within the context of an outer
struct (different from our other two modes of usage with no flags
for normal local variable declarations, and with is_param for adding
'const' in a parameter list). I don't know if there is any more
pythonic way of collapsing the two flags into a single parameter,
as we never have a caller setting both flags at once.
Ultimately, we want to also unbox branches for QAPI unions, but as
that touches a lot more client code, it is better as separate
patches. But since unions and alternates share gen_variants(), I
had to hack in a way to test if we are visiting an alternate type
for setting the is_unboxed flag: look for a non-object branch.
This works because alternates have at least two branches, with at
most one object branch, while unions have only object branches.
The hack will go away in a later patch.
The generated code difference to qapi-types.h is relatively small:
| struct BlockdevRef {
| QType type;
| union { /* union tag is @type */
| void *data;
|- BlockdevOptions *definition;
|+ BlockdevOptions definition;
| char *reference;
| } u;
| };
The corresponding spot in qapi-visit.c calls visit_type_FOO(), which
first calls visit_start_struct() to allocate or deallocate the member
and handle a layer of {} from the JSON stream, then visits the
members. To peel off the indirection and the memory management that
comes with it, we inline this call, then suppress allocation /
deallocation by passing NULL to visit_start_struct(), and adjust the
member visit:
| switch ((*obj)->type) {
| case QTYPE_QDICT:
|- visit_type_BlockdevOptions(v, name, &(*obj)->u.definition, &err);
|+ visit_start_struct(v, name, NULL, 0, &err);
|+ if (err) {
|+ break;
|+ }
|+ visit_type_BlockdevOptions_fields(v, &(*obj)->u.definition, &err);
|+ error_propagate(errp, err);
|+ err = NULL;
|+ visit_end_struct(v, &err);
| break;
| case QTYPE_QSTRING:
| visit_type_str(v, name, &(*obj)->u.reference, &err);
The visit of non-object fields is unchanged.
Backports commit becceedc4d9bc1435099c90a0514945a89844d3a from qemu
|
||
|---|---|---|
| .. | ||
| crypto | ||
| default-configs | ||
| docs | ||
| fpu | ||
| hw | ||
| include | ||
| qapi | ||
| qobject | ||
| qom | ||
| scripts | ||
| target-arm | ||
| target-i386 | ||
| target-m68k | ||
| target-mips | ||
| target-sparc | ||
| tcg | ||
| util | ||
| aarch64.h | ||
| aarch64eb.h | ||
| accel.c | ||
| arm.h | ||
| armeb.h | ||
| CODING_STYLE | ||
| configure | ||
| COPYING | ||
| COPYING.LIB | ||
| cpu-exec-common.c | ||
| cpu-exec.c | ||
| cpus.c | ||
| cputlb.c | ||
| exec.c | ||
| gen_all_header.sh | ||
| glib_compat.c | ||
| HACKING | ||
| header_gen.py | ||
| ioport.c | ||
| LICENSE | ||
| m68k.h | ||
| Makefile | ||
| Makefile.objs | ||
| Makefile.target | ||
| memory.c | ||
| memory_mapping.c | ||
| mips.h | ||
| mips64.h | ||
| mips64el.h | ||
| mipsel.h | ||
| powerpc.h | ||
| qapi-schema.json | ||
| qemu-log.c | ||
| qemu-timer.c | ||
| rules.mak | ||
| softmmu_template.h | ||
| sparc.h | ||
| sparc64.h | ||
| tcg-runtime.c | ||
| translate-all.c | ||
| translate-all.h | ||
| translate-common.c | ||
| unicorn_common.h | ||
| VERSION | ||
| vl.c | ||
| vl.h | ||
| x86_64.h | ||