Skip to content

Commit

Permalink
support variable offset sizes for real
Browse files Browse the repository at this point in the history
  • Loading branch information
TYoungSL committed Aug 11, 2021
1 parent b561f67 commit 926e814
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 26 deletions.
61 changes: 54 additions & 7 deletions include/flatcc/flatcc_identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,41 @@ static inline void flatbuffers_identifier_from_type_hash(flatbuffers_thash_t typ
out_identifier[0] = (char)(type_hash & 0xff);
type_hash >>= 8;
out_identifier[1] = (char)(type_hash & 0xff);

#if FLATBUFFERS_THASH_WIDTH > 16
type_hash >>= 8;
out_identifier[2] = (char)(type_hash & 0xff);
type_hash >>= 8;
out_identifier[3] = (char)(type_hash & 0xff);
#endif

#if FLATBUFFERS_THASH_WIDTH > 32
type_hash >>= 8;
out_identifier[4] = (char)(type_hash & 0xff);
type_hash >>= 8;
out_identifier[5] = (char)(type_hash & 0xff);
type_hash >>= 8;
out_identifier[6] = (char)(type_hash & 0xff);
type_hash >>= 8;
out_identifier[7] = (char)(type_hash & 0xff);
#endif
}

/* Native integer encoding of file identifier. */
static inline flatbuffers_thash_t flatbuffers_type_hash_from_identifier(const flatbuffers_fid_t identifier)
{
uint8_t *p = (uint8_t *)identifier;

return identifier ?
(uint32_t)p[0] + (((uint32_t)p[1]) << 8) + (((uint32_t)p[2]) << 16) + (((uint32_t)p[3]) << 24) : 0;
return !identifier ? 0 :

#if FLATBUFFERS_THASH_WIDTH == 16
(uint16_t)p[0] + (((uint16_t)p[1]) << 8);
#elif FLATBUFFERS_THASH_WIDTH == 32
(uint32_t)p[0] + (((uint32_t)p[1]) << 8) + (((uint32_t)p[2]) << 16) + (((uint32_t)p[3]) << 24);
#elif FLATBUFFERS_THASH_WIDTH == 64
(uint64_t)p[0] + (((uint64_t)p[1]) << 8) + (((uint64_t)p[2]) << 16) + (((uint64_t)p[3]) << 24) +
(((uint64_t)p[4]) << 32) + (((uint64_t)p[5]) << 40) + (((uint64_t)p[6]) << 48) + (((uint64_t)p[7]) << 56);
#endif
}

/*
Expand All @@ -95,10 +117,25 @@ static inline flatbuffers_thash_t flatbuffers_type_hash_from_string(const char *
h += ((flatbuffers_thash_t)p[0]);
if (!p[1]) return h;
h += ((flatbuffers_thash_t)p[1]) << 8;

#if FLATBUFFERS_THASH_WIDTH > 16
if (!p[2]) return h;
h += ((flatbuffers_thash_t)p[2]) << 16;
/* No need to test for termination here. */
if (!p[3]) return h;
h += ((flatbuffers_thash_t)p[3]) << 24;
#endif

#if FLATBUFFERS_THASH_WIDTH > 32
if (!p[4]) return h;
h += ((flatbuffers_thash_t)p[4]) << 32;
if (!p[5]) return h;
h += ((flatbuffers_thash_t)p[5]) << 40;
if (!p[6]) return h;
h += ((flatbuffers_thash_t)p[6]) << 48;
if (!p[7]) return h;
h += ((flatbuffers_thash_t)p[7]) << 56;
#endif

return h;
}

Expand All @@ -125,21 +162,31 @@ static inline void flatbuffers_identifier_from_name(const char *name, flatbuffer
* additional information and just complicates matters. Furthermore, the
* unmodified type hash has the benefit that it can seed a child namespace.
*/
static inline uint32_t flatbuffers_disperse_type_hash(flatbuffers_thash_t type_hash)
static inline flatbuffers_thash_t flatbuffers_disperse_type_hash(flatbuffers_thash_t type_hash)
{
flatbuffers_thash_t x = type_hash;

#if FLATBUFFERS_THASH_WIDTH == 32
/* http://stackoverflow.com/a/12996028 */
uint32_t x = type_hash;

x = ((x >> 16) ^ x) * UINT32_C(0x45d9f3b);
x = ((x >> 16) ^ x) * UINT32_C(0x45d9f3b);
x = ((x >> 16) ^ x);
#elif FLATBUFFERS_THASH_WIDTH == 64
/* http://stackoverflow.com/a/12996028 */

x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
x = x ^ (x >> 31);
#endif

return x;
}


/* We have hardcoded assumptions about identifier size. */
static_assert(sizeof(flatbuffers_fid_t) == 4, "unexpected file identifier size");
static_assert(sizeof(flatbuffers_thash_t) == 4, "unexpected type hash size");
//static_assert(sizeof(flatbuffers_fid_t) == 4, "unexpected file identifier size");
//static_assert(sizeof(flatbuffers_thash_t) == 4, "unexpected type hash size");

#ifdef __cplusplus
}
Expand Down
78 changes: 60 additions & 18 deletions include/flatcc/flatcc_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ extern "C" {
#include <stdint.h>
#endif

#include "../../config/config.h"

/*
* This should match generated type declaratios in
* `flatbuffers_common_reader.h` (might have different name prefix).
Expand Down Expand Up @@ -44,40 +46,80 @@ extern "C" {
#define flatbuffers_thash_t_defined
#define flatbuffers_fid_t_defined

/* uoffset_t is also used for vector and string headers. */
#define FLATBUFFERS_UOFFSET_MAX UINT32_MAX
#define FLATBUFFERS_SOFFSET_MAX INT32_MAX
#define FLATBUFFERS_SOFFSET_MIN INT32_MIN
#define FLATBUFFERS_VOFFSET_MAX UINT16_MAX
#define FLATBUFFERS_UTYPE_MAX UINT8_MAX
/* Well - the max of the underlying type. */
#define FLATBUFFERS_BOOL_MAX UINT8_MAX
#define FLATBUFFERS_THASH_MAX UINT32_MAX

#define FLATBUFFERS_ID_MAX (FLATBUFFERS_VOFFSET_MAX / sizeof(flatbuffers_voffset_t) - 3)
/* Vectors of empty structs can yield div by zero, so we must guard against this. */
#define FLATBUFFERS_COUNT_MAX(elem_size) (FLATBUFFERS_UOFFSET_MAX/((elem_size) == 0 ? 1 : (elem_size)))

#define FLATBUFFERS_UOFFSET_WIDTH 32
#define FLATBUFFERS_COUNT_WIDTH 32
#define FLATBUFFERS_SOFFSET_WIDTH 32
#define FLATBUFFERS_VOFFSET_WIDTH 16
#define FLATBUFFERS_UTYPE_WIDTH 8
#define FLATBUFFERS_BOOL_WIDTH 8
#define FLATBUFFERS_THASH_WIDTH 32

#define FLATBUFFERS_TRUE 1
#define FLATBUFFERS_FALSE 0

#define FLATBUFFERS_PROTOCOL_IS_LE 1
#define FLATBUFFERS_PROTOCOL_IS_BE 0

/* uoffset_t is also used for vector and string headers. */
#if FLATCC_OFFSET_SIZE == 4
typedef uint32_t flatbuffers_uoffset_t;
typedef int32_t flatbuffers_soffset_t;
typedef uint32_t flatbuffers_thash_t;
#define FLATBUFFERS_UOFFSET_MAX UINT32_MAX
#define FLATBUFFERS_SOFFSET_MAX INT32_MAX
#define FLATBUFFERS_SOFFSET_MIN INT32_MIN
#define FLATBUFFERS_THASH_MAX UINT32_MAX
#define FLATBUFFERS_UOFFSET_WIDTH 32
#define FLATBUFFERS_SOFFSET_WIDTH 32
#define FLATBUFFERS_THASH_WIDTH 32
#elif FLATCC_OFFSET_SIZE == 8
typedef uint64_t flatbuffers_uoffset_t;
typedef int64_t flatbuffers_soffset_t;
typedef uint64_t flatbuffers_thash_t;
#define FLATBUFFERS_UOFFSET_MAX UINT64_MAX
#define FLATBUFFERS_SOFFSET_MAX INT64_MAX
#define FLATBUFFERS_SOFFSET_MIN INT64_MIN
#define FLATBUFFERS_THASH_MAX UINT64_MAX
#define FLATBUFFERS_UOFFSET_WIDTH 64
#define FLATBUFFERS_SOFFSET_WIDTH 64
#define FLATBUFFERS_THASH_WIDTH 64
#elif FLATCC_OFFSET_SIZE == 2
typedef uint16_t flatbuffers_uoffset_t;
typedef int16_t flatbuffers_soffset_t;
typedef uint16_t flatbuffers_thash_t;
#define FLATBUFFERS_UOFFSET_MAX UINT16_MAX
#define FLATBUFFERS_SOFFSET_MAX INT16_MAX
#define FLATBUFFERS_SOFFSET_MIN INT16_MIN
#define FLATBUFFERS_THASH_MAX UINT16_MAX
#define FLATBUFFERS_UOFFSET_WIDTH 16
#define FLATBUFFERS_SOFFSET_WIDTH 16
#define FLATBUFFERS_THASH_WIDTH 16
#else
#error FLATCC_OFFSET_SIZE must be defined.
#endif

#if FLATCC_VOFFSET_SIZE == 2
typedef uint16_t flatbuffers_voffset_t;
#define FLATBUFFERS_VOFFSET_MAX UINT16_MAX
#define FLATBUFFERS_VOFFSET_WIDTH 16
#elif FLATCC_VOFFSET_SIZE == 8
typedef uint64_t flatbuffers_voffset_t;
#define FLATBUFFERS_VOFFSET_MAX UINT64_MAX
#define FLATBUFFERS_VOFFSET_WIDTH 64
#elif FLATCC_VOFFSET_SIZE == 4
typedef uint32_t flatbuffers_voffset_t;
#define FLATBUFFERS_VOFFSET_MAX UINT32_MAX
#define FLATBUFFERS_VOFFSET_WIDTH 32
#else
#error FLATCC_VOFFSET_SIZE must be defined.
#endif

#define FLATBUFFERS_UTYPE_MAX UINT8_MAX
#define FLATBUFFERS_UTYPE_WIDTH 8
typedef uint8_t flatbuffers_utype_t;

/* Well - the max of the underlying type. */
#define FLATBUFFERS_BOOL_MAX UINT8_MAX
#define FLATBUFFERS_BOOL_WIDTH 8
typedef uint8_t flatbuffers_bool_t;
typedef uint32_t flatbuffers_thash_t;

/* Public facing type operations. */
typedef flatbuffers_utype_t flatbuffers_union_type_t;

Expand Down
17 changes: 17 additions & 0 deletions src/compiler/codegen_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#define gen_panic(context, msg) fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg), assert(0), exit(-1)
#endif

#ifndef STRINGIZE
#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)
#endif

static inline void token_name(fb_token_t *t, int *n, const char **s) {
*n = (int)t->len;
Expand Down Expand Up @@ -339,6 +343,19 @@ static inline int gen_prologue(fb_output_t *out)
if (out->opts->cgen_pragmas) {
fprintf(out->fp, "#include \"flatcc/flatcc_prologue.h\"\n");
}

fputs(
"#ifndef FLATCC_OFFSET_SIZE \n"
"#define FLATCC_OFFSET_SIZE " STRINGIZE(FLATCC_OFFSET_SIZE) "\n"
"#endif\n",
out->fp);

fputs(
"#ifndef FLATCC_VOFFSET_SIZE \n"
"#define FLATCC_VOFFSET_SIZE " STRINGIZE(FLATCC_VOFFSET_SIZE) "\n"
"#endif\n",
out->fp);

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ int flatcc_builder_default_alloc(void *alloc_context, iovec_t *b, size_t request
#define table_limit (FLATBUFFERS_VOFFSET_MAX - field_size + 1)
#define data_limit (FLATBUFFERS_UOFFSET_MAX - field_size + 1)

#define set_identifier(id) memcpy(&B->identifier, (id) ? (void *)(id) : (void *)_pad, identifier_size)
#define set_identifier(id) strncpy((char * restrict)&B->identifier, (id) ? (void *)(id) : (void *)_pad, identifier_size)

/* Must also return true when no buffer has been started. */
#define is_top_buffer(B) (B->nest_id == 0)
Expand Down

0 comments on commit 926e814

Please sign in to comment.