From 4323d381e794b834b412839ada9019f999711a4e Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 17 May 2019 17:17:33 -0400 Subject: [PATCH] json: make it 64-bit compatible The struct json_obj_descr definition allocates only 2 bits for type alignment. Instead of using them literally minus 1 to encode 1, 2, or 4, let's store the alignment's shift value instead so that 1, 2, 4 or 8 can be encoded with the same 2 bits to accommodate 64-bit builds. Signed-off-by: Nicolas Pitre --- include/json.h | 42 ++++++++++++++++++++++-------------------- lib/os/json.c | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/include/json.h b/include/json.h index 263c63ef476..c5a37115c23 100644 --- a/include/json.h +++ b/include/json.h @@ -51,13 +51,12 @@ enum json_tokens { struct json_obj_descr { const char *field_name; - /* Alignment can never be 0 or more than 4. The macros to create a - * struct json_obj_descr will subtract 1 from the result of - * __alignof__() calls in order to keep this value in the 0-3 range - * and thus use only 2 bits. 1 is added back when rounding it up to - * calculate the struct size while parsing an array or object. + /* Alignment can be 1, 2, 4, or 8. The macros to create + * a struct json_obj_descr will store the alignment's + * power of 2 in order to keep this value in the 0-3 range + * and thus use only 2 bits. */ - u32_t alignment : 2; + u32_t align_shift : 2; /* 127 characters is more than enough for a field name. */ u32_t field_name_len : 7; @@ -100,6 +99,9 @@ struct json_obj_descr { typedef int (*json_append_bytes_t)(const char *bytes, size_t len, void *data); +#define Z_ALIGN_SHIFT(type) (__alignof__(type) == 1 ? 0 : \ + __alignof__(type) == 2 ? 1 : \ + __alignof__(type) == 4 ? 2 : 3) /** * @brief Helper macro to declare a descriptor for supported primitive @@ -128,7 +130,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (#field_name_), \ .field_name_len = sizeof(#field_name_) - 1, \ .offset = offsetof(struct_, field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = type_, \ } @@ -162,7 +164,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (#field_name_), \ .field_name_len = (sizeof(#field_name_) - 1), \ .offset = offsetof(struct_, field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = JSON_TOK_OBJECT_START, \ .object = { \ .sub_descr = sub_descr_, \ @@ -201,13 +203,13 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (#field_name_), \ .field_name_len = sizeof(#field_name_) - 1, \ .offset = offsetof(struct_, field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = JSON_TOK_LIST_START, \ .array = { \ .element_descr = &(struct json_obj_descr) { \ .type = elem_type_, \ .offset = offsetof(struct_, len_field_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ }, \ .n_elements = (max_len_), \ }, \ @@ -258,7 +260,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (#field_name_), \ .field_name_len = sizeof(#field_name_) - 1, \ .offset = offsetof(struct_, field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = JSON_TOK_LIST_START, \ .array = { \ .element_descr = &(struct json_obj_descr) { \ @@ -268,7 +270,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .sub_descr_len = elem_descr_len_, \ }, \ .offset = offsetof(struct_, len_field_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ }, \ .n_elements = (max_len_), \ }, \ @@ -328,7 +330,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (#field_name_), \ .field_name_len = sizeof(#field_name_) - 1, \ .offset = offsetof(struct_, field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = JSON_TOK_LIST_START, \ .array = { \ .element_descr = &(struct json_obj_descr) { \ @@ -338,7 +340,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .sub_descr_len = elem_descr_len_, \ }, \ .offset = offsetof(struct_, len_field_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ }, \ .n_elements = (max_len_), \ }, \ @@ -367,7 +369,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (json_field_name_), \ .field_name_len = sizeof(json_field_name_) - 1, \ .offset = offsetof(struct_, struct_field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = type_, \ } @@ -393,7 +395,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (json_field_name_), \ .field_name_len = (sizeof(json_field_name_) - 1), \ .offset = offsetof(struct_, struct_field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = JSON_TOK_OBJECT_START, \ .object = { \ .sub_descr = sub_descr_, \ @@ -429,13 +431,13 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = (json_field_name_), \ .field_name_len = sizeof(json_field_name_) - 1, \ .offset = offsetof(struct_, struct_field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = JSON_TOK_LIST_START, \ .array = { \ .element_descr = &(struct json_obj_descr) { \ .type = elem_type_, \ .offset = offsetof(struct_, len_field_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ }, \ .n_elements = (max_len_), \ }, \ @@ -495,7 +497,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .field_name = json_field_name_, \ .field_name_len = sizeof(json_field_name_) - 1, \ .offset = offsetof(struct_, struct_field_name_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ .type = JSON_TOK_LIST_START, \ .element_descr = &(struct json_obj_descr) { \ .type = JSON_TOK_OBJECT_START, \ @@ -504,7 +506,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, .sub_descr_len = elem_descr_len_, \ }, \ .offset = offsetof(struct_, len_field_), \ - .alignment = __alignof__(struct_) - 1, \ + .align_shift = Z_ALIGN_SHIFT(struct_), \ }, \ .n_elements = (max_len_), \ } diff --git a/lib/os/json.c b/lib/os/json.c index 830fa9dcd1f..d5df75f86ef 100644 --- a/lib/os/json.c +++ b/lib/os/json.c @@ -493,7 +493,7 @@ static ptrdiff_t get_elem_size(const struct json_obj_descr *descr) for (i = 0; i < descr->object.sub_descr_len; i++) { ptrdiff_t s = get_elem_size(&descr->object.sub_descr[i]); - total += ROUND_UP(s, descr->alignment + 1); + total += ROUND_UP(s, 1 << descr->align_shift); } return total;