[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
introspect.py output representation (was: [PATCH v2 00/11] qapi: static
From: |
Markus Armbruster |
Subject: |
introspect.py output representation (was: [PATCH v2 00/11] qapi: static typing conversion, pt2) |
Date: |
Mon, 16 Nov 2020 14:17:32 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) |
Warning: losely related brain dump ahead.
introspect.py's purpose is providing query-qmp-schema with the data it
needs to built its response, which is a JSON object conforming to
['SchemaInfo'].
Stupidest solution that could possibly work: have this module generate a
C string holding the (JSON text) response.
Since a QMP command handler returns a QAPI object, not the response
string, this becomes:
schema
|
| qapi-gen.py
v
C string --------------------------------------------------
|
| qobject_from_json()
v
QObject qmp_query_qmp_schema()
|
| QObject input visitor
v
SchemaInfoList --------------------------------------------------
|
| QObject output visitor generated wrapper
v
QObject --------------------------------------------------
|
| qobject_to_json() QMP core
v
C string
Meh. So many pointless conversions.
Shortcut: 'gen' false lets us cut out two:
schema
|
| qapi-gen.py
v
C string --------------------------------------------------
|
| qobject_from_json() qmp_query_qmp_schema()
v
QObject --------------------------------------------------
|
| qobject_to_json() QMP core
v
C string
Less work for handwritten qmp_query_qmp_schema(); it's now a one-liner.
This is the initial version (commit 39a1815816).
Commit 7d0f982bfb replaced the generated C string by a QLitObject:
schema
|
| qapi-gen.py
v
QLitObj --------------------------------------------------
|
| qobject_from_qlit() qmp_query_qmp_schema()
v
QObject --------------------------------------------------
|
| qobject_to_json() QMP core
v
C string
The commit message claims the QLitObj is "easier to deal with". I doubt
it. The conversion to QObject is a one-liner before and after. Neither
form is hard to generate (example appended).
QLitObj takes more memory: ~360KiB, mostly .data (unnecessarily?),
wheras the C string is ~150KiB .text. Of course, both are dwarved many
times over by QObject: 12.4MiB. Gross.
However, to actually work with the introspection data in C, we'd want it
as SchemaInfoList. I have a few uses for introspection data in mind,
and I definitely won't code them taking QObject input.
SchemaInfoList is one visitor away from QObject, so no big deal.
But what if we generated SchemaInfoList directly? We'd have:
schema
|
| qapi-gen.py
v
SchemaInfoList --------------------------------------------------
|
| QObject output visitor generated wrapper
v
QObject --------------------------------------------------
|
| qobject_to_json() QMP core
v
C string
At ~480KiB, SchemaInfoList is less compact than QLitObj (let alone the C
string). It should go entirely into .text, though.
I don't think generating SchemaInfoList would be particularly hard.
Just work. Bigger fish to fry, I guess. But getting the idea out can't
hurt.
Example: BlockdevOptionsFile
{ 'struct': 'BlockdevOptionsFile',
'data': { 'filename': 'str',
'*pr-manager': 'str',
'*locking': 'OnOffAuto',
'*aio': 'BlockdevAioOptions',
'*drop-cache': {'type': 'bool',
'if': 'defined(CONFIG_LINUX)'},
'*x-check-cache-dropped': 'bool' },
'features': [ { 'name': 'dynamic-auto-read-only',
'if': 'defined(CONFIG_POSIX)' } ] }
Generated QLitObj:
/* "267" = BlockdevOptionsFile */
QLIT_QDICT(((QLitDictEntry[]) {
{ "features", QLIT_QLIST(((QLitObject[]) {
#if defined(CONFIG_POSIX)
QLIT_QSTR("dynamic-auto-read-only"),
#endif /* defined(CONFIG_POSIX) */
{}
})), },
{ "members", QLIT_QLIST(((QLitObject[]) {
QLIT_QDICT(((QLitDictEntry[]) {
{ "name", QLIT_QSTR("filename"), },
{ "type", QLIT_QSTR("str"), },
{}
})),
QLIT_QDICT(((QLitDictEntry[]) {
{ "default", QLIT_QNULL, },
{ "name", QLIT_QSTR("pr-manager"), },
{ "type", QLIT_QSTR("str"), },
{}
})),
QLIT_QDICT(((QLitDictEntry[]) {
{ "default", QLIT_QNULL, },
{ "name", QLIT_QSTR("locking"), },
{ "type", QLIT_QSTR("412"), },
{}
})),
QLIT_QDICT(((QLitDictEntry[]) {
{ "default", QLIT_QNULL, },
{ "name", QLIT_QSTR("aio"), },
{ "type", QLIT_QSTR("413"), },
{}
})),
#if defined(CONFIG_LINUX)
QLIT_QDICT(((QLitDictEntry[]) {
{ "default", QLIT_QNULL, },
{ "name", QLIT_QSTR("drop-cache"), },
{ "type", QLIT_QSTR("bool"), },
{}
})),
#endif /* defined(CONFIG_LINUX) */
QLIT_QDICT(((QLitDictEntry[]) {
{ "default", QLIT_QNULL, },
{ "name", QLIT_QSTR("x-check-cache-dropped"), },
{ "type", QLIT_QSTR("bool"), },
{}
})),
{}
})), },
{ "meta-type", QLIT_QSTR("object"), },
{ "name", QLIT_QSTR("267"), },
{}
})),
Generated C string would look like this:
"{\"features\": ["
#if defined(CONFIG_POSIX)
"\"dynamic-auto-read-only\""
#endif /* defined(CONFIG_POSIX) */
"], "
"\"members\": ["
"{\"name\": \"filename\", \"type\": \"str\"}, "
"{\"name\": \"pr-manager\", \"default\": null, \"type\": \"str\"}, "
"{\"name\": \"locking\", \"default\": null, \"type\": \"412\"}, "
"{\"name\": \"aio\", \"default\": null, \"type\": \"413\"}, "
#if defined(CONFIG_LINUX)
"{\"name\": \"drop-cache\", \"default\": null, \"type\": \"bool\"}, "
#endif /* defined(CONFIG_LINUX) */
"{\"name\": \"x-check-cache-dropped\", \"default\": null, \"type\":
\"bool\"}"
"], "
"\"meta-type\": \"object\", "
"\"name\": \"267\""
"}"
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- introspect.py output representation (was: [PATCH v2 00/11] qapi: static typing conversion, pt2),
Markus Armbruster <=