generator: Add support for structure of non-object values

This commit is contained in:
Corentin Wallez 2018-05-17 16:55:53 -04:00 committed by Corentin Wallez
parent 2ee315ca64
commit a6416543a4
7 changed files with 82 additions and 2 deletions

View File

@ -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())

View File

@ -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);

View File

@ -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) %}

View File

@ -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:

View File

@ -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 -%}

View File

@ -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++) {

View File

@ -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 %}