From 9cb10577fcefa3ed004e0bbdc61e6238e8137e3c Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 4 Jul 2017 17:02:48 -0700 Subject: First version of a real C codegen for upb. Also includes an implementation of the conformance tests to display what the API usage will be like. There is still a lot to do, and things that are broken (oneofs, repeated fields, etc), but it's a good start. --- upb/msg.h | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'upb/msg.h') diff --git a/upb/msg.h b/upb/msg.h index 1d888b8..ee1e2fb 100644 --- a/upb/msg.h +++ b/upb/msg.h @@ -110,6 +110,22 @@ const upb_visitorplan *upb_msgfactory_getvisitorplan(upb_msgfactory *f, const upb_handlers *h); +/** upb_stringview ************************************************************/ + +typedef struct { + const char *data; + size_t size; +} upb_stringview; + +UPB_INLINE upb_stringview upb_stringview_make(const char *data, size_t size) { + upb_stringview ret; + ret.data = data; + ret.size = size; + return ret; +} + +#define UPB_STRINGVIEW_INIT(ptr, len) {ptr, len} + /** upb_msgval ****************************************************************/ /* A union representing all possible protobuf values. Used for generic get/set @@ -127,10 +143,7 @@ typedef union { const upb_msg* msg; const upb_array* arr; const void* ptr; - struct { - const char *ptr; - size_t len; - } str; + upb_stringview str; } upb_msgval; #define ACCESSORS(name, membername, ctype) \ @@ -157,22 +170,12 @@ ACCESSORS(map, map, const upb_map*) ACCESSORS(msg, msg, const upb_msg*) ACCESSORS(ptr, ptr, const void*) ACCESSORS(arr, arr, const upb_array*) +ACCESSORS(str, str, upb_stringview) #undef ACCESSORS -UPB_INLINE upb_msgval upb_msgval_str(const char *ptr, size_t len) { - upb_msgval ret; - ret.str.ptr = ptr; - ret.str.len = len; - return ret; -} - -UPB_INLINE const char* upb_msgval_getstr(upb_msgval val) { - return val.str.ptr; -} - -UPB_INLINE size_t upb_msgval_getstrlen(upb_msgval val) { - return val.str.len; +UPB_INLINE upb_msgval upb_msgval_makestr(const char *data, size_t size) { + return upb_msgval_str(upb_stringview_make(data, size)); } @@ -384,11 +387,6 @@ bool upb_msg_getscalarhandlerdata(const upb_handlers *h, #define UPB_NOT_IN_ONEOF UINT16_MAX -typedef struct { - const char *ptr; - uint32_t length; -} upb_msglayout_strinit_v1; - typedef struct { uint32_t number; uint32_t offset; /* If in a oneof, offset of default in default_msg below. */ @@ -405,21 +403,22 @@ typedef struct { } upb_msglayout_oneofinit_v1; typedef struct upb_msglayout_msginit_v1 { - const struct upb_msglayout_msginit_v1 **submsgs; + const struct upb_msglayout_msginit_v1 *const* submsgs; const upb_msglayout_fieldinit_v1 *fields; const upb_msglayout_oneofinit_v1 *oneofs; - uint32_t *case_offsets; void *default_msg; - /* Must be aligned to 8. Doesn't include internal members like unknown - * fields, extension dict, pointer to msglayout, etc. */ + /* Must be aligned to sizeof(void*). Doesn't include internal members like + * unknown * fields, extension dict, pointer to msglayout, etc. */ uint32_t size; uint16_t field_count; uint16_t oneof_count; bool extendable; bool is_proto2; - char align; } upb_msglayout_msginit_v1; +#define UPB_ALIGN_UP_TO(val, align) ((val + (align - 1)) & -align) +#define UPB_ALIGNED_SIZEOF(type) UPB_ALIGN_UP_TO(sizeof(type), sizeof(void*)) + /* Initialize/uninitialize a msglayout from a msginit. If upb uses v1 * internally, this will not allocate any memory. Should only be used by * generated code. */ -- cgit v1.2.3 From 1278ff899409025692d6915421f1af1c99dc837e Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 11 Jul 2017 14:11:54 -0500 Subject: Responded to PR comments. --- tests/conformance_upb.c | 2 +- tools/make_c_api.lua | 11 ++++++----- tools/upbc.lua | 4 ++++ upb/msg.c | 4 ++-- upb/msg.h | 2 +- 5 files changed, 14 insertions(+), 9 deletions(-) (limited to 'upb/msg.h') diff --git a/tests/conformance_upb.c b/tests/conformance_upb.c index 9f83e80..1671409 100644 --- a/tests/conformance_upb.c +++ b/tests/conformance_upb.c @@ -81,7 +81,7 @@ void DoTest( char *serialized = protobuf_test_messages_proto3_TestAllTypes_serialize( test_message, env, &serialized_len); if (!serialized) { - fprintf(stderr, "conformance_upb: Error serialiing."); + fprintf(stderr, "conformance_upb: Error serializing."); exit(1); } conformance_ConformanceResponse_set_protobuf_payload( diff --git a/tools/make_c_api.lua b/tools/make_c_api.lua index aaf5d1e..c13f37c 100644 --- a/tools/make_c_api.lua +++ b/tools/make_c_api.lua @@ -30,11 +30,6 @@ function strip_proto(filename) return string.gsub(filename, '%.proto$','') end ---[[ - [upb.TYPE_ENUM] = 5, - [upb.TYPE_MESSAGE] = 8, ---]] - local function join(...) return table.concat({...}, ".") end @@ -138,6 +133,12 @@ local function field_layout_rank(field) -- 5. string fields -- 6. submessage fields -- 7. repeated fields + -- + -- This has the following nice properties: + -- + -- 1. padding alignment is (nearly) minimized. + -- 2. fields that might have defaults (1-5) are segregated + -- from fields that are always zero-initialized (6-7). local rank if field:containing_oneof() then rank = 4 diff --git a/tools/upbc.lua b/tools/upbc.lua index bf9a68d..bfd93f8 100644 --- a/tools/upbc.lua +++ b/tools/upbc.lua @@ -18,6 +18,10 @@ for _, argument in ipairs(arg) do if argument == "--generate-upbdefs" then generate_upbdefs = true else + if src then + print("upbc can only handle one input file at a time.") + return 1 + end src = argument end end diff --git a/upb/msg.c b/upb/msg.c index 34525b7..f1070d7 100644 --- a/upb/msg.c +++ b/upb/msg.c @@ -340,8 +340,8 @@ static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) { } /* Size of the entire structure should be a multiple of its greatest - * alignment. */ - l->data.size = align_up(l->data.size, 8 /* TODO: track for real? */); + * alignment. TODO: track overall alignment for real? */ + l->data.size = align_up(l->data.size, 8); if (upb_msglayout_initdefault(l, m)) { return l; diff --git a/upb/msg.h b/upb/msg.h index ee1e2fb..7026a50 100644 --- a/upb/msg.h +++ b/upb/msg.h @@ -408,7 +408,7 @@ typedef struct upb_msglayout_msginit_v1 { const upb_msglayout_oneofinit_v1 *oneofs; void *default_msg; /* Must be aligned to sizeof(void*). Doesn't include internal members like - * unknown * fields, extension dict, pointer to msglayout, etc. */ + * unknown fields, extension dict, pointer to msglayout, etc. */ uint32_t size; uint16_t field_count; uint16_t oneof_count; -- cgit v1.2.3