generator: Add support for structure of non-object values
This commit is contained in:
parent
2ee315ca64
commit
a6416543a4
|
@ -93,6 +93,19 @@ class ObjectType(Type):
|
|||
self.native_methods = []
|
||||
self.built_type = None
|
||||
|
||||
class StructureMember:
|
||||
def __init__(self, name, typ, annotation):
|
||||
self.name = name
|
||||
self.type = typ
|
||||
self.annotation = annotation
|
||||
self.length = None
|
||||
|
||||
class StructureType(Type):
|
||||
def __init__(self, name, record):
|
||||
Type.__init__(self, name, record)
|
||||
self.extensible = record.get("extensible", False)
|
||||
self.members = []
|
||||
|
||||
############################################################
|
||||
# PARSE
|
||||
############################################################
|
||||
|
@ -112,9 +125,13 @@ def link_object(obj, types):
|
|||
arguments_by_name[arg.name.canonical_case()] = arg
|
||||
|
||||
for (arg, a) in zip(arguments, record.get('args', [])):
|
||||
assert(arg.annotation == 'value' or 'length' in a)
|
||||
if arg.annotation != 'value':
|
||||
if a['length'] == 'strlen':
|
||||
if not 'length' in a:
|
||||
if arg.type.category == 'structure':
|
||||
arg.length = "constant_one"
|
||||
else:
|
||||
assert(false)
|
||||
elif a['length'] == 'strlen':
|
||||
arg.length = 'strlen'
|
||||
else:
|
||||
arg.length = arguments_by_name[a['length']]
|
||||
|
@ -133,6 +150,13 @@ def link_object(obj, types):
|
|||
break
|
||||
assert(obj.built_type != None)
|
||||
|
||||
def link_structure(struct, types):
|
||||
def make_member(m):
|
||||
return StructureMember(Name(m['name']), types[m['type']], m.get('annotation', 'value'))
|
||||
|
||||
# TODO(cwallez@chromium.org): Handle pointer members and their length
|
||||
struct.members = [make_member(m) for m in struct.record['members']]
|
||||
|
||||
def parse_json(json):
|
||||
category_to_parser = {
|
||||
'bitmask': BitmaskType,
|
||||
|
@ -140,6 +164,7 @@ def parse_json(json):
|
|||
'native': NativeType,
|
||||
'natively defined': NativelyDefined,
|
||||
'object': ObjectType,
|
||||
'structure': StructureType,
|
||||
}
|
||||
|
||||
types = {}
|
||||
|
@ -159,6 +184,9 @@ def parse_json(json):
|
|||
for obj in by_category['object']:
|
||||
link_object(obj, types)
|
||||
|
||||
for struct in by_category['structure']:
|
||||
link_structure(struct, types)
|
||||
|
||||
for category in by_category.keys():
|
||||
by_category[category] = sorted(by_category[category], key=lambda typ: typ.name.canonical_case())
|
||||
|
||||
|
|
|
@ -33,6 +33,17 @@
|
|||
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["structure"] %}
|
||||
typedef struct {
|
||||
{% if type.extensible %}
|
||||
const void* nextInChain;
|
||||
{% endif %}
|
||||
{% for member in type.members %}
|
||||
{{as_annotated_cType(member)}};
|
||||
{% endfor %}
|
||||
} {{as_cType(type.name)}};
|
||||
{% endfor %}
|
||||
|
||||
// Custom types depending on the target language
|
||||
typedef uint64_t nxtCallbackUserdata;
|
||||
typedef void (*nxtDeviceErrorCallback)(const char* message, nxtCallbackUserdata userdata);
|
||||
|
|
|
@ -30,6 +30,25 @@ namespace nxt {
|
|||
{% endfor %}
|
||||
|
||||
|
||||
{% for type in by_category["structure"] %}
|
||||
{% set CppType = as_cppType(type.name) %}
|
||||
{% set CType = as_cType(type.name) %}
|
||||
|
||||
static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
|
||||
static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
|
||||
|
||||
{% if type.extensible %}
|
||||
static_assert(offsetof({{CppType}}, nextInChain) == offsetof({{CType}}, nextInChain),
|
||||
"offsetof mismatch for {{CppType}}::nextInChain");
|
||||
{% endif %}
|
||||
{% for member in type.members %}
|
||||
{% set memberName = member.name.camelCase() %}
|
||||
static_assert(offsetof({{CppType}}, {{memberName}}) == offsetof({{CType}}, {{memberName}}),
|
||||
"offsetof mismatch for {{CppType}}::{{memberName}}");
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["object"] %}
|
||||
{% set CppType = as_cppType(type.name) %}
|
||||
{% set CType = as_cType(type.name) %}
|
||||
|
|
|
@ -55,6 +55,18 @@ namespace nxt {
|
|||
class {{as_cppType(type.name)}};
|
||||
{% endfor %}
|
||||
|
||||
{% for type in by_category["structure"] %}
|
||||
struct {{as_cppType(type.name)}} {
|
||||
{% if type.extensible %}
|
||||
const void* nextInChain = nullptr;
|
||||
{% endif %}
|
||||
{% for member in type.members %}
|
||||
{{as_annotated_cppType(member)}};
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
{% endfor %}
|
||||
|
||||
template<typename Derived, typename CType>
|
||||
class ObjectBase {
|
||||
public:
|
||||
|
|
|
@ -49,6 +49,8 @@ namespace {{namespace}} {
|
|||
{%- if not loop.first %}, {% endif -%}
|
||||
{%- if arg.type.category in ["enum", "bitmask"] -%}
|
||||
static_cast<nxt::{{as_cppType(arg.type.name)}}>({{as_varName(arg.name)}})
|
||||
{%- elif arg.type.category == "structure" and arg.annotation != "value" -%}
|
||||
reinterpret_cast<const nxt::{{as_cppType(arg.type.name)}}*>({{as_varName(arg.name)}})
|
||||
{%- else -%}
|
||||
{{as_varName(arg.name)}}
|
||||
{%- endif -%}
|
||||
|
@ -147,6 +149,8 @@ namespace {{namespace}} {
|
|||
{%- if not loop.first %}, {% endif -%}
|
||||
{%- if arg.type.category in ["enum", "bitmask"] -%}
|
||||
static_cast<nxt::{{as_cppType(arg.type.name)}}>({{as_varName(arg.name)}})
|
||||
{%- elif arg.type.category == "structure" and arg.annotation != "value" -%}
|
||||
reinterpret_cast<const nxt::{{as_cppType(arg.type.name)}}*>({{as_varName(arg.name)}})
|
||||
{%- else -%}
|
||||
{{as_varName(arg.name)}}
|
||||
{%- endif -%}
|
||||
|
|
|
@ -264,6 +264,8 @@ namespace wire {
|
|||
{% set argName = as_varName(arg.name) %}
|
||||
{% if arg.length == "strlen" %}
|
||||
memcpy(allocCmd->GetPtr_{{argName}}(), {{argName}}, allocCmd->{{argName}}Strlen + 1);
|
||||
{% elif arg.length == "constant_one" %}
|
||||
memcpy(allocCmd->GetPtr_{{argName}}(), {{argName}}, sizeof(*{{argName}}));
|
||||
{% elif arg.type.category == "object" %}
|
||||
auto {{argName}}Storage = reinterpret_cast<uint32_t*>(allocCmd->GetPtr_{{argName}}());
|
||||
for (size_t i = 0; i < {{as_varName(arg.length.name)}}; i++) {
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace wire {
|
|||
{% for arg in method.arguments if arg.annotation != "value" %}
|
||||
{% if arg.length == "strlen" %}
|
||||
result += {{as_varName(arg.name)}}Strlen + 1;
|
||||
{% elif arg.length == "constant_one" %}
|
||||
result += sizeof({{as_cType(arg.type.name)}});
|
||||
{% elif arg.type.category == "object" %}
|
||||
result += {{as_varName(arg.length.name)}} * sizeof(uint32_t);
|
||||
{% else %}
|
||||
|
@ -53,6 +55,8 @@ namespace wire {
|
|||
{% endif %}
|
||||
{% if arg.length == "strlen" %}
|
||||
ptr += {{as_varName(arg.name)}}Strlen + 1;
|
||||
{% elif arg.length == "constant_one" %}
|
||||
ptr += sizeof({{as_cType(arg.type.name)}});
|
||||
{% elif arg.type.category == "object" %}
|
||||
ptr += {{as_varName(arg.length.name)}} * sizeof(uint32_t);
|
||||
{% else %}
|
||||
|
|
Loading…
Reference in New Issue