Skip to content

Commit 4323d38

Browse files
Nicolas Pitrenashif
Nicolas Pitre
authored andcommitted
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 <[email protected]>
1 parent def743e commit 4323d38

File tree

2 files changed

+23
-21
lines changed

2 files changed

+23
-21
lines changed

include/json.h

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,12 @@ enum json_tokens {
5151
struct json_obj_descr {
5252
const char *field_name;
5353

54-
/* Alignment can never be 0 or more than 4. The macros to create a
55-
* struct json_obj_descr will subtract 1 from the result of
56-
* __alignof__() calls in order to keep this value in the 0-3 range
57-
* and thus use only 2 bits. 1 is added back when rounding it up to
58-
* calculate the struct size while parsing an array or object.
54+
/* Alignment can be 1, 2, 4, or 8. The macros to create
55+
* a struct json_obj_descr will store the alignment's
56+
* power of 2 in order to keep this value in the 0-3 range
57+
* and thus use only 2 bits.
5958
*/
60-
u32_t alignment : 2;
59+
u32_t align_shift : 2;
6160

6261
/* 127 characters is more than enough for a field name. */
6362
u32_t field_name_len : 7;
@@ -100,6 +99,9 @@ struct json_obj_descr {
10099
typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
101100
void *data);
102101

102+
#define Z_ALIGN_SHIFT(type) (__alignof__(type) == 1 ? 0 : \
103+
__alignof__(type) == 2 ? 1 : \
104+
__alignof__(type) == 4 ? 2 : 3)
103105

104106
/**
105107
* @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,
128130
.field_name = (#field_name_), \
129131
.field_name_len = sizeof(#field_name_) - 1, \
130132
.offset = offsetof(struct_, field_name_), \
131-
.alignment = __alignof__(struct_) - 1, \
133+
.align_shift = Z_ALIGN_SHIFT(struct_), \
132134
.type = type_, \
133135
}
134136

@@ -162,7 +164,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
162164
.field_name = (#field_name_), \
163165
.field_name_len = (sizeof(#field_name_) - 1), \
164166
.offset = offsetof(struct_, field_name_), \
165-
.alignment = __alignof__(struct_) - 1, \
167+
.align_shift = Z_ALIGN_SHIFT(struct_), \
166168
.type = JSON_TOK_OBJECT_START, \
167169
.object = { \
168170
.sub_descr = sub_descr_, \
@@ -201,13 +203,13 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
201203
.field_name = (#field_name_), \
202204
.field_name_len = sizeof(#field_name_) - 1, \
203205
.offset = offsetof(struct_, field_name_), \
204-
.alignment = __alignof__(struct_) - 1, \
206+
.align_shift = Z_ALIGN_SHIFT(struct_), \
205207
.type = JSON_TOK_LIST_START, \
206208
.array = { \
207209
.element_descr = &(struct json_obj_descr) { \
208210
.type = elem_type_, \
209211
.offset = offsetof(struct_, len_field_), \
210-
.alignment = __alignof__(struct_) - 1, \
212+
.align_shift = Z_ALIGN_SHIFT(struct_), \
211213
}, \
212214
.n_elements = (max_len_), \
213215
}, \
@@ -258,7 +260,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
258260
.field_name = (#field_name_), \
259261
.field_name_len = sizeof(#field_name_) - 1, \
260262
.offset = offsetof(struct_, field_name_), \
261-
.alignment = __alignof__(struct_) - 1, \
263+
.align_shift = Z_ALIGN_SHIFT(struct_), \
262264
.type = JSON_TOK_LIST_START, \
263265
.array = { \
264266
.element_descr = &(struct json_obj_descr) { \
@@ -268,7 +270,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
268270
.sub_descr_len = elem_descr_len_, \
269271
}, \
270272
.offset = offsetof(struct_, len_field_), \
271-
.alignment = __alignof__(struct_) - 1, \
273+
.align_shift = Z_ALIGN_SHIFT(struct_), \
272274
}, \
273275
.n_elements = (max_len_), \
274276
}, \
@@ -328,7 +330,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
328330
.field_name = (#field_name_), \
329331
.field_name_len = sizeof(#field_name_) - 1, \
330332
.offset = offsetof(struct_, field_name_), \
331-
.alignment = __alignof__(struct_) - 1, \
333+
.align_shift = Z_ALIGN_SHIFT(struct_), \
332334
.type = JSON_TOK_LIST_START, \
333335
.array = { \
334336
.element_descr = &(struct json_obj_descr) { \
@@ -338,7 +340,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
338340
.sub_descr_len = elem_descr_len_, \
339341
}, \
340342
.offset = offsetof(struct_, len_field_), \
341-
.alignment = __alignof__(struct_) - 1, \
343+
.align_shift = Z_ALIGN_SHIFT(struct_), \
342344
}, \
343345
.n_elements = (max_len_), \
344346
}, \
@@ -367,7 +369,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
367369
.field_name = (json_field_name_), \
368370
.field_name_len = sizeof(json_field_name_) - 1, \
369371
.offset = offsetof(struct_, struct_field_name_), \
370-
.alignment = __alignof__(struct_) - 1, \
372+
.align_shift = Z_ALIGN_SHIFT(struct_), \
371373
.type = type_, \
372374
}
373375

@@ -393,7 +395,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
393395
.field_name = (json_field_name_), \
394396
.field_name_len = (sizeof(json_field_name_) - 1), \
395397
.offset = offsetof(struct_, struct_field_name_), \
396-
.alignment = __alignof__(struct_) - 1, \
398+
.align_shift = Z_ALIGN_SHIFT(struct_), \
397399
.type = JSON_TOK_OBJECT_START, \
398400
.object = { \
399401
.sub_descr = sub_descr_, \
@@ -429,13 +431,13 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
429431
.field_name = (json_field_name_), \
430432
.field_name_len = sizeof(json_field_name_) - 1, \
431433
.offset = offsetof(struct_, struct_field_name_), \
432-
.alignment = __alignof__(struct_) - 1, \
434+
.align_shift = Z_ALIGN_SHIFT(struct_), \
433435
.type = JSON_TOK_LIST_START, \
434436
.array = { \
435437
.element_descr = &(struct json_obj_descr) { \
436438
.type = elem_type_, \
437439
.offset = offsetof(struct_, len_field_), \
438-
.alignment = __alignof__(struct_) - 1, \
440+
.align_shift = Z_ALIGN_SHIFT(struct_), \
439441
}, \
440442
.n_elements = (max_len_), \
441443
}, \
@@ -495,7 +497,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
495497
.field_name = json_field_name_, \
496498
.field_name_len = sizeof(json_field_name_) - 1, \
497499
.offset = offsetof(struct_, struct_field_name_), \
498-
.alignment = __alignof__(struct_) - 1, \
500+
.align_shift = Z_ALIGN_SHIFT(struct_), \
499501
.type = JSON_TOK_LIST_START, \
500502
.element_descr = &(struct json_obj_descr) { \
501503
.type = JSON_TOK_OBJECT_START, \
@@ -504,7 +506,7 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
504506
.sub_descr_len = elem_descr_len_, \
505507
}, \
506508
.offset = offsetof(struct_, len_field_), \
507-
.alignment = __alignof__(struct_) - 1, \
509+
.align_shift = Z_ALIGN_SHIFT(struct_), \
508510
}, \
509511
.n_elements = (max_len_), \
510512
}

lib/os/json.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ static ptrdiff_t get_elem_size(const struct json_obj_descr *descr)
493493
for (i = 0; i < descr->object.sub_descr_len; i++) {
494494
ptrdiff_t s = get_elem_size(&descr->object.sub_descr[i]);
495495

496-
total += ROUND_UP(s, descr->alignment + 1);
496+
total += ROUND_UP(s, 1 << descr->align_shift);
497497
}
498498

499499
return total;

0 commit comments

Comments
 (0)