Minireflect fixed array (#6129)

* CMakeLists: also really generate optional_scalars as needed by test elsewhere

* [C++] Handle fixed-length array in minireflection

Fixes #6128
This commit is contained in:
Mark Nauwelaerts
2020-09-23 02:57:01 +02:00
committed by GitHub
parent 96d5e35977
commit 34d67b425e
16 changed files with 127 additions and 73 deletions

View File

@@ -2747,7 +2747,7 @@ inline const char * const *ElementaryTypeNames() {
// Basic type info cost just 16bits per field!
struct TypeCode {
uint16_t base_type : 4; // ElementaryType
uint16_t is_vector : 1;
uint16_t is_repeating : 1; // Either vector (in table) or array (in struct)
int16_t sequence_ref : 11; // Index into type_refs below, or -1 for none.
};
@@ -2763,6 +2763,7 @@ struct TypeTable {
size_t num_elems; // of type_codes, values, names (but not type_refs).
const TypeCode *type_codes; // num_elems count
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
const int16_t *array_sizes; // less than num_elems entries (see TypeCode).
const int64_t *values; // Only set for non-consecutive enum/union or structs.
const char *const *names; // Only set if compiled with --reflect-names.
};

View File

@@ -234,10 +234,11 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
visitor->StartSequence();
const uint8_t *prev_val = nullptr;
size_t set_idx = 0;
size_t array_idx = 0;
for (size_t i = 0; i < type_table->num_elems; i++) {
auto type_code = type_table->type_codes[i];
auto type = static_cast<ElementaryType>(type_code.base_type);
auto is_vector = type_code.is_vector != 0;
auto is_repeating = type_code.is_repeating != 0;
auto ref_idx = type_code.sequence_ref;
const TypeTable *ref = nullptr;
if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); }
@@ -249,15 +250,25 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
} else {
val = obj + type_table->values[i];
}
visitor->Field(i, set_idx, type, is_vector, ref, name, val);
visitor->Field(i, set_idx, type, is_repeating, ref, name, val);
if (val) {
set_idx++;
if (is_vector) {
val += ReadScalar<uoffset_t>(val);
auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
if (is_repeating) {
auto elem_ptr = val;
size_t size = 0;
if (type_table->st == ST_TABLE) {
// variable length vector
val += ReadScalar<uoffset_t>(val);
auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
elem_ptr = vec->Data();
size = vec->size();
} else {
// otherwise fixed size array
size = type_table->array_sizes[array_idx];
++array_idx;
}
visitor->StartVector();
auto elem_ptr = vec->Data();
for (size_t j = 0; j < vec->size(); j++) {
for (size_t j = 0; j < size; j++) {
visitor->Element(j, type, ref, elem_ptr);
IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j),
visitor);