diff --git a/upb/decode.c b/upb/decode.c index 3aabe0e1dc..abbbe80e6a 100644 --- a/upb/decode.c +++ b/upb/decode.c @@ -461,7 +461,9 @@ static const char *decode_fixed_packed(upb_decstate *d, const char *ptr, decode_reserve(d, arr, count); void *mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); arr->len += count; - memcpy(mem, ptr, val->size); /* XXX: ptr boundary. */ + // Note: if/when the decoder supports multi-buffer input, we will need to + // handle buffer seams here. + memcpy(mem, ptr, val->size); return ptr + val->size; } diff --git a/upb/def.c b/upb/def.c index 97db5e86aa..47be1caf07 100644 --- a/upb/def.c +++ b/upb/def.c @@ -2363,7 +2363,7 @@ static void create_service( } } -static int popcount(uint64_t x) { +static int count_bits_debug(uint64_t x) { // For assertions only, speed does not matter. int n = 0; while (x) { @@ -2387,17 +2387,20 @@ upb_enumlayout *create_enumlayout(symtab_addctx *ctx, const upb_enumdef *e) { } int32_t *values = symtab_alloc(ctx, sizeof(*values) * n); - int32_t *p = values; - for (int i = 0; i < e->value_count; i++) { - int32_t val = e->values[i].number; - if ((uint32_t)val >= 64) { - *p++ = val; + if (n) { + int32_t *p = values; + + for (int i = 0; i < e->value_count; i++) { + int32_t val = e->values[i].number; + if ((uint32_t)val >= 64) { + *p++ = val; + } } + UPB_ASSERT(p == values + n); } - UPB_ASSERT(p == values + n); - UPB_ASSERT(upb_inttable_count(&e->iton) == n + popcount(mask)); + UPB_ASSERT(upb_inttable_count(&e->iton) == n + count_bits_debug(mask)); upb_enumlayout *layout = symtab_alloc(ctx, sizeof(*layout)); layout->value_count = n; @@ -2407,6 +2410,34 @@ upb_enumlayout *create_enumlayout(symtab_addctx *ctx, const upb_enumdef *e) { return layout; } +static void create_enumvaldef( + symtab_addctx *ctx, const char *prefix, + const google_protobuf_EnumValueDescriptorProto *val_proto, upb_enumdef *e, + int i) { + upb_enumvaldef *val = (upb_enumvaldef *)&e->values[i]; + upb_strview name = google_protobuf_EnumValueDescriptorProto_name(val_proto); + upb_value v = upb_value_constptr(val); + + val->enum_ = e; /* Must happen prior to symtab_add(). */ + val->full_name = makefullname(ctx, prefix, name); + val->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); + symtab_add(ctx, val->full_name, pack_def(val, UPB_DEFTYPE_ENUMVAL)); + + SET_OPTIONS(val->opts, EnumValueDescriptorProto, EnumValueOptions, val_proto); + + if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && val->number != 0) { + symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)", + e->full_name); + } + + CHK_OOM(upb_strtable_insert(&e->ntoi, name.data, name.size, v, ctx->arena)); + + // Multiple enumerators can have the same number, first one wins. + if (!upb_inttable_lookup(&e->iton, val->number, NULL)) { + CHK_OOM(upb_inttable_insert(&e->iton, val->number, v, ctx->arena)); + } +} + static void create_enumdef( symtab_addctx *ctx, const char *prefix, const google_protobuf_EnumDescriptorProto *enum_proto, @@ -2442,29 +2473,7 @@ static void create_enumdef( SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); for (i = 0; i < n; i++) { - const google_protobuf_EnumValueDescriptorProto *val_proto = values[i]; - upb_enumvaldef *val = (upb_enumvaldef*)&e->values[i]; - upb_strview name = google_protobuf_EnumValueDescriptorProto_name(val_proto); - upb_value v = upb_value_constptr(val); - - val->enum_ = e; /* Must happen prior to symtab_add(). */ - val->full_name = makefullname(ctx, prefix, name); - val->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); - symtab_add(ctx, val->full_name, pack_def(val, UPB_DEFTYPE_ENUMVAL)); - - SET_OPTIONS(val->opts, EnumValueDescriptorProto, EnumValueOptions, val_proto); - - if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && val->number != 0) { - symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)", - e->full_name); - } - - CHK_OOM(upb_strtable_insert(&e->ntoi, name.data, name.size, v, ctx->arena)); - - // Multiple enumerators can have the same number, first one wins. - if (!upb_inttable_lookup(&e->iton, val->number, NULL)) { - CHK_OOM(upb_inttable_insert(&e->iton, val->number, v, ctx->arena)); - } + create_enumvaldef(ctx, prefix, values[i], e, i); } upb_inttable_compact(&e->iton, ctx->arena); @@ -2473,7 +2482,7 @@ static void create_enumdef( if (ctx->layout) { UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count); e->layout = ctx->layout->enums[ctx->enum_count++]; - UPB_ASSERT(n == e->layout->value_count + popcount(e->layout->mask)); + UPB_ASSERT(n == e->layout->value_count + count_bits_debug(e->layout->mask)); } else { e->layout = create_enumlayout(ctx, e); } diff --git a/upbc/protoc-gen-upb.cc b/upbc/protoc-gen-upb.cc index 52758ff0f8..f157335d1d 100644 --- a/upbc/protoc-gen-upb.cc +++ b/upbc/protoc-gen-upb.cc @@ -745,7 +745,7 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) { output("\n"); if (file->syntax() == protobuf::FileDescriptor::SYNTAX_PROTO2) { - for (auto enumdesc : this_file_enums) { + for (const auto* enumdesc : this_file_enums) { output("extern const upb_enumlayout $0;\n", EnumInit(enumdesc)); } }