create and lock down upb/internal/array.h

Internal array functions are now implemented in upb/internal/array.c and declared in
upb/internal/array.h, which only has local visibility.

PiperOrigin-RevId: 458260144
pull/13171/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 46e306bead
commit 8c44f04697
  1. 35
      BUILD
  2. 3
      upb/arena.c
  3. 5
      upb/array.c
  4. 1
      upb/array.h
  5. 1
      upb/decode.c
  6. 3
      upb/decode_fast.c
  7. 4
      upb/encode.c
  8. 89
      upb/internal/array.c
  9. 204
      upb/internal/array.h
  10. 1
      upb/map.h
  11. 2
      upb/mini_table_accessors.c
  12. 61
      upb/msg.c
  13. 156
      upb/msg_internal.h
  14. 6
      upbc/protoc-gen-upb.cc

35
BUILD

@ -104,6 +104,7 @@ cc_library(
srcs = [ srcs = [
"upb/alloc.c", "upb/alloc.c",
"upb/arena.c", "upb/arena.c",
"upb/array.c",
"upb/decode.c", "upb/decode.c",
"upb/encode.c", "upb/encode.c",
"upb/internal/table.h", "upb/internal/table.h",
@ -115,9 +116,11 @@ cc_library(
hdrs = [ hdrs = [
"upb/alloc.h", "upb/alloc.h",
"upb/arena.h", "upb/arena.h",
"upb/array.h",
"upb/decode.h", "upb/decode.h",
"upb/encode.h", "upb/encode.h",
"upb/extension_registry.h", "upb/extension_registry.h",
"upb/message_value.h",
"upb/msg.h", "upb/msg.h",
"upb/status.h", "upb/status.h",
"upb/string_view.h", "upb/string_view.h",
@ -128,6 +131,7 @@ cc_library(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
":arena_internal", ":arena_internal",
":array_internal",
":decode_internal", ":decode_internal",
":encode_internal", ":encode_internal",
":extension_registry", ":extension_registry",
@ -220,6 +224,7 @@ cc_library(
copts = UPB_DEFAULT_COPTS, copts = UPB_DEFAULT_COPTS,
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
":array_internal",
":collections", ":collections",
":mini_table", ":mini_table",
":mini_table_internal", ":mini_table_internal",
@ -276,6 +281,7 @@ cc_library(
copts = UPB_DEFAULT_COPTS, copts = UPB_DEFAULT_COPTS,
deps = [ deps = [
":arena_internal", ":arena_internal",
":array_internal",
":decode_internal", ":decode_internal",
":extension_registry", ":extension_registry",
":port", ":port",
@ -292,10 +298,13 @@ cc_library(
cc_library( cc_library(
name = "generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", name = "generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
hdrs = [ hdrs = [
"upb/array.h",
"upb/decode.h", "upb/decode.h",
"upb/decode_fast.h", "upb/decode_fast.h",
"upb/encode.h", "upb/encode.h",
"upb/extension_registry.h", "upb/extension_registry.h",
"upb/internal/array.h",
"upb/message_value.h",
"upb/msg.h", "upb/msg.h",
"upb/msg_internal.h", "upb/msg_internal.h",
"upb/port_def.inc", "upb/port_def.inc",
@ -340,12 +349,10 @@ upb_proto_reflection_library(
cc_library( cc_library(
name = "collections", name = "collections",
srcs = [ srcs = [
"upb/array.c",
"upb/map.c", "upb/map.c",
"upb/msg_internal.h", "upb/msg_internal.h",
], ],
hdrs = [ hdrs = [
"upb/array.h",
"upb/collections.h", "upb/collections.h",
"upb/map.h", "upb/map.h",
"upb/message_value.h", "upb/message_value.h",
@ -718,6 +725,27 @@ cc_library(
# Internal C/C++ libraries ##################################################### # Internal C/C++ libraries #####################################################
cc_library(
name = "array_internal",
srcs = [
"upb/alloc.h",
"upb/arena.h",
"upb/array.h",
"upb/internal/array.c",
"upb/message_value.h",
"upb/msg.h",
"upb/status.h",
"upb/string_view.h",
"upb/upb.h",
],
hdrs = ["upb/internal/array.h"],
copts = UPB_DEFAULT_COPTS,
visibility = ["//:__subpackages__"],
deps = [
":port",
],
)
cc_library( cc_library(
name = "arena_internal", name = "arena_internal",
srcs = [ srcs = [
@ -787,6 +815,7 @@ upb_amalgamation(
], ],
libs = [ libs = [
":arena_internal", ":arena_internal",
":array_internal",
":collections", ":collections",
":decode_internal", ":decode_internal",
":descriptor_upb_proto", ":descriptor_upb_proto",
@ -816,6 +845,7 @@ upb_amalgamation(
], ],
libs = [ libs = [
":arena_internal", ":arena_internal",
":array_internal",
":collections", ":collections",
":decode_internal", ":decode_internal",
":descriptor_upb_proto", ":descriptor_upb_proto",
@ -848,6 +878,7 @@ upb_amalgamation(
], ],
libs = [ libs = [
":arena_internal", ":arena_internal",
":array_internal",
":collections", ":collections",
":decode_internal", ":decode_internal",
":descriptor_upb_proto", ":descriptor_upb_proto",

@ -25,9 +25,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "upb/arena.h"
#include "upb/alloc.h"
#include "upb/internal/arena.h" #include "upb/internal/arena.h"
// Must be last. // Must be last.

@ -25,13 +25,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "upb/array.h" #include "upb/internal/array.h"
#include <string.h> #include <string.h>
#include "upb/msg.h"
#include "upb/msg_internal.h"
// Must be last. // Must be last.
#include "upb/port_def.inc" #include "upb/port_def.inc"

@ -29,7 +29,6 @@
#define UPB_ARRAY_H_ #define UPB_ARRAY_H_
#include "upb/message_value.h" #include "upb/message_value.h"
#include "upb/upb.h"
// Must be last. // Must be last.
#include "upb/port_def.inc" #include "upb/port_def.inc"

@ -29,6 +29,7 @@
#include <string.h> #include <string.h>
#include "upb/internal/array.h"
#include "upb/internal/decode.h" #include "upb/internal/decode.h"
#include "upb/upb.h" #include "upb/upb.h"

@ -37,9 +37,10 @@
#include "upb/decode_fast.h" #include "upb/decode_fast.h"
#include "upb/internal/array.h"
#include "upb/internal/decode.h" #include "upb/internal/decode.h"
/* Must be last. */ // Must be last.
#include "upb/port_def.inc" #include "upb/port_def.inc"
#if UPB_FASTTABLE #if UPB_FASTTABLE

@ -29,14 +29,14 @@
#include "upb/encode.h" #include "upb/encode.h"
#include <setjmp.h>
#include <string.h> #include <string.h>
#include "upb/extension_registry.h" #include "upb/extension_registry.h"
#include "upb/internal/array.h"
#include "upb/msg_internal.h" #include "upb/msg_internal.h"
#include "upb/upb.h" #include "upb/upb.h"
/* Must be last. */ // Must be last.
#include "upb/port_def.inc" #include "upb/port_def.inc"
#define UPB_PB_VARINT_MAX_LEN 10 #define UPB_PB_VARINT_MAX_LEN 10

@ -0,0 +1,89 @@
/*
* Copyright (c) 2009-2021, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "upb/internal/array.h"
#include <string.h>
// Must be last.
#include "upb/port_def.inc"
bool _upb_array_realloc(upb_Array* arr, size_t min_capacity, upb_Arena* arena) {
size_t new_capacity = UPB_MAX(arr->capacity, 4);
int elem_size_lg2 = arr->data & 7;
size_t old_bytes = arr->capacity << elem_size_lg2;
size_t new_bytes;
void* ptr = _upb_array_ptr(arr);
/* Log2 ceiling of size. */
while (new_capacity < min_capacity) new_capacity *= 2;
new_bytes = new_capacity << elem_size_lg2;
ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes);
if (!ptr) {
return false;
}
arr->data = _upb_tag_arrptr(ptr, elem_size_lg2);
arr->capacity = new_capacity;
return true;
}
static upb_Array* getorcreate_array(upb_Array** arr_ptr, int elem_size_lg2,
upb_Arena* arena) {
upb_Array* arr = *arr_ptr;
if (!arr) {
arr = _upb_Array_New(arena, 4, elem_size_lg2);
if (!arr) return NULL;
*arr_ptr = arr;
}
return arr;
}
void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size,
int elem_size_lg2, upb_Arena* arena) {
upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
return arr && _upb_Array_Resize(arr, size, arena) ? _upb_array_ptr(arr)
: NULL;
}
bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
int elem_size_lg2, upb_Arena* arena) {
upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
if (!arr) return false;
size_t elems = arr->size;
if (!_upb_Array_Resize(arr, elems + 1, arena)) {
return false;
}
char* data = _upb_array_ptr(arr);
memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);
return true;
}

@ -0,0 +1,204 @@
/*
* Copyright (c) 2009-2021, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UPB_INTERNAL_ARRAY_H_
#define UPB_INTERNAL_ARRAY_H_
#include <string.h>
#include "upb/array.h"
// Must be last.
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
/* Our internal representation for repeated fields. */
struct upb_Array {
uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */
size_t size; /* The number of elements in the array. */
size_t capacity; /* Allocated storage. Measured in elements. */
uint64_t junk;
};
UPB_INLINE const void* _upb_array_constptr(const upb_Array* arr) {
UPB_ASSERT((arr->data & 7) <= 4);
return (void*)(arr->data & ~(uintptr_t)7);
}
UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) {
UPB_ASSERT(elem_size_lg2 <= 4);
return (uintptr_t)ptr | elem_size_lg2;
}
UPB_INLINE void* _upb_array_ptr(upb_Array* arr) {
return (void*)_upb_array_constptr(arr);
}
UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) {
UPB_ASSERT(elem_size_lg2 <= 4);
UPB_ASSERT(((uintptr_t)ptr & 7) == 0);
return (uintptr_t)ptr | (unsigned)elem_size_lg2;
}
UPB_INLINE upb_Array* _upb_Array_New(upb_Arena* a, size_t init_capacity,
int elem_size_lg2) {
const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_Array), 8);
const size_t bytes = sizeof(upb_Array) + (init_capacity << elem_size_lg2);
upb_Array* arr = (upb_Array*)upb_Arena_Malloc(a, bytes);
if (!arr) return NULL;
arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2);
arr->size = 0;
arr->capacity = init_capacity;
return arr;
}
/* Resizes the capacity of the array to be at least min_size. */
bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena);
/* Fallback functions for when the accessors require a resize. */
void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size,
int elem_size_lg2, upb_Arena* arena);
bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
int elem_size_lg2, upb_Arena* arena);
UPB_INLINE bool _upb_array_reserve(upb_Array* arr, size_t size,
upb_Arena* arena) {
if (arr->capacity < size) return _upb_array_realloc(arr, size, arena);
return true;
}
UPB_INLINE bool _upb_Array_Resize(upb_Array* arr, size_t size,
upb_Arena* arena) {
if (!_upb_array_reserve(arr, size, arena)) return false;
arr->size = size;
return true;
}
UPB_INLINE void _upb_array_detach(const void* msg, size_t ofs) {
*UPB_PTR_AT(msg, ofs, upb_Array*) = NULL;
}
UPB_INLINE const void* _upb_array_accessor(const void* msg, size_t ofs,
size_t* size) {
const upb_Array* arr = *UPB_PTR_AT(msg, ofs, const upb_Array*);
if (arr) {
if (size) *size = arr->size;
return _upb_array_constptr(arr);
} else {
if (size) *size = 0;
return NULL;
}
}
UPB_INLINE void* _upb_array_mutable_accessor(void* msg, size_t ofs,
size_t* size) {
upb_Array* arr = *UPB_PTR_AT(msg, ofs, upb_Array*);
if (arr) {
if (size) *size = arr->size;
return _upb_array_ptr(arr);
} else {
if (size) *size = 0;
return NULL;
}
}
UPB_INLINE void* _upb_Array_Resize_accessor2(void* msg, size_t ofs, size_t size,
int elem_size_lg2,
upb_Arena* arena) {
upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*);
upb_Array* arr = *arr_ptr;
if (!arr || arr->capacity < size) {
return _upb_Array_Resize_fallback(arr_ptr, size, elem_size_lg2, arena);
}
arr->size = size;
return _upb_array_ptr(arr);
}
UPB_INLINE bool _upb_Array_Append_accessor2(void* msg, size_t ofs,
int elem_size_lg2,
const void* value,
upb_Arena* arena) {
upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*);
size_t elem_size = 1 << elem_size_lg2;
upb_Array* arr = *arr_ptr;
void* ptr;
if (!arr || arr->size == arr->capacity) {
return _upb_Array_Append_fallback(arr_ptr, value, elem_size_lg2, arena);
}
ptr = _upb_array_ptr(arr);
memcpy(UPB_PTR_AT(ptr, arr->size * elem_size, char), value, elem_size);
arr->size++;
return true;
}
/* Used by old generated code, remove once all code has been regenerated. */
UPB_INLINE int _upb_sizelg2(upb_CType type) {
switch (type) {
case kUpb_CType_Bool:
return 0;
case kUpb_CType_Float:
case kUpb_CType_Int32:
case kUpb_CType_UInt32:
case kUpb_CType_Enum:
return 2;
case kUpb_CType_Message:
return UPB_SIZE(2, 3);
case kUpb_CType_Double:
case kUpb_CType_Int64:
case kUpb_CType_UInt64:
return 3;
case kUpb_CType_String:
case kUpb_CType_Bytes:
return UPB_SIZE(3, 4);
}
UPB_UNREACHABLE();
}
UPB_INLINE void* _upb_Array_Resize_accessor(void* msg, size_t ofs, size_t size,
upb_CType type, upb_Arena* arena) {
return _upb_Array_Resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena);
}
UPB_INLINE bool _upb_Array_Append_accessor(void* msg, size_t ofs,
size_t elem_size, upb_CType type,
const void* value,
upb_Arena* arena) {
(void)elem_size;
return _upb_Array_Append_accessor2(msg, ofs, _upb_sizelg2(type), value,
arena);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* UPB_INTERNAL_ARRAY_H_ */

@ -29,7 +29,6 @@
#define UPB_MAP_H_ #define UPB_MAP_H_
#include "upb/message_value.h" #include "upb/message_value.h"
#include "upb/upb.h"
// Must be last. // Must be last.
#include "upb/port_def.inc" #include "upb/port_def.inc"

@ -29,8 +29,8 @@
#include "upb/decode.h" #include "upb/decode.h"
#include "upb/encode.h" #include "upb/encode.h"
#include "upb/internal/array.h"
#include "upb/mini_table.h" #include "upb/mini_table.h"
#include "upb/msg_internal.h"
// Must be last. // Must be last.
#include "upb/port_def.inc" #include "upb/port_def.inc"

@ -27,8 +27,9 @@
#include "upb/msg.h" #include "upb/msg.h"
#include "upb/internal/table.h"
#include "upb/msg_internal.h" #include "upb/msg_internal.h"
// Must be last.
#include "upb/port_def.inc" #include "upb/port_def.inc"
/** upb_Message ***************************************************************/ /** upb_Message ***************************************************************/
@ -173,64 +174,6 @@ size_t upb_Message_ExtensionCount(const upb_Message* msg) {
return count; return count;
} }
/** upb_Array *****************************************************************/
bool _upb_array_realloc(upb_Array* arr, size_t min_capacity, upb_Arena* arena) {
size_t new_capacity = UPB_MAX(arr->capacity, 4);
int elem_size_lg2 = arr->data & 7;
size_t old_bytes = arr->capacity << elem_size_lg2;
size_t new_bytes;
void* ptr = _upb_array_ptr(arr);
/* Log2 ceiling of size. */
while (new_capacity < min_capacity) new_capacity *= 2;
new_bytes = new_capacity << elem_size_lg2;
ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes);
if (!ptr) {
return false;
}
arr->data = _upb_tag_arrptr(ptr, elem_size_lg2);
arr->capacity = new_capacity;
return true;
}
static upb_Array* getorcreate_array(upb_Array** arr_ptr, int elem_size_lg2,
upb_Arena* arena) {
upb_Array* arr = *arr_ptr;
if (!arr) {
arr = _upb_Array_New(arena, 4, elem_size_lg2);
if (!arr) return NULL;
*arr_ptr = arr;
}
return arr;
}
void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size,
int elem_size_lg2, upb_Arena* arena) {
upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
return arr && _upb_Array_Resize(arr, size, arena) ? _upb_array_ptr(arr)
: NULL;
}
bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
int elem_size_lg2, upb_Arena* arena) {
upb_Array* arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
if (!arr) return false;
size_t elems = arr->size;
if (!_upb_Array_Resize(arr, elems + 1, arena)) {
return false;
}
char* data = _upb_array_ptr(arr);
memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);
return true;
}
/** upb_Map *******************************************************************/ /** upb_Map *******************************************************************/
upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) {

@ -406,162 +406,6 @@ UPB_INLINE bool _upb_has_submsg_nohasbit(const upb_Message* msg, size_t ofs) {
return *UPB_PTR_AT(msg, ofs, const upb_Message*) != NULL; return *UPB_PTR_AT(msg, ofs, const upb_Message*) != NULL;
} }
/** upb_Array *****************************************************************/
/* Our internal representation for repeated fields. */
struct upb_Array {
uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */
size_t size; /* The number of elements in the array. */
size_t capacity; /* Allocated storage. Measured in elements. */
uint64_t junk;
};
UPB_INLINE const void* _upb_array_constptr(const upb_Array* arr) {
UPB_ASSERT((arr->data & 7) <= 4);
return (void*)(arr->data & ~(uintptr_t)7);
}
UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) {
UPB_ASSERT(elem_size_lg2 <= 4);
return (uintptr_t)ptr | elem_size_lg2;
}
UPB_INLINE void* _upb_array_ptr(upb_Array* arr) {
return (void*)_upb_array_constptr(arr);
}
UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) {
UPB_ASSERT(elem_size_lg2 <= 4);
UPB_ASSERT(((uintptr_t)ptr & 7) == 0);
return (uintptr_t)ptr | (unsigned)elem_size_lg2;
}
UPB_INLINE upb_Array* _upb_Array_New(upb_Arena* a, size_t init_capacity,
int elem_size_lg2) {
const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_Array), 8);
const size_t bytes = sizeof(upb_Array) + (init_capacity << elem_size_lg2);
upb_Array* arr = (upb_Array*)upb_Arena_Malloc(a, bytes);
if (!arr) return NULL;
arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2);
arr->size = 0;
arr->capacity = init_capacity;
return arr;
}
/* Resizes the capacity of the array to be at least min_size. */
bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena);
/* Fallback functions for when the accessors require a resize. */
void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size,
int elem_size_lg2, upb_Arena* arena);
bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
int elem_size_lg2, upb_Arena* arena);
UPB_INLINE bool _upb_array_reserve(upb_Array* arr, size_t size,
upb_Arena* arena) {
if (arr->capacity < size) return _upb_array_realloc(arr, size, arena);
return true;
}
UPB_INLINE bool _upb_Array_Resize(upb_Array* arr, size_t size,
upb_Arena* arena) {
if (!_upb_array_reserve(arr, size, arena)) return false;
arr->size = size;
return true;
}
UPB_INLINE void _upb_array_detach(const void* msg, size_t ofs) {
*UPB_PTR_AT(msg, ofs, upb_Array*) = NULL;
}
UPB_INLINE const void* _upb_array_accessor(const void* msg, size_t ofs,
size_t* size) {
const upb_Array* arr = *UPB_PTR_AT(msg, ofs, const upb_Array*);
if (arr) {
if (size) *size = arr->size;
return _upb_array_constptr(arr);
} else {
if (size) *size = 0;
return NULL;
}
}
UPB_INLINE void* _upb_array_mutable_accessor(void* msg, size_t ofs,
size_t* size) {
upb_Array* arr = *UPB_PTR_AT(msg, ofs, upb_Array*);
if (arr) {
if (size) *size = arr->size;
return _upb_array_ptr(arr);
} else {
if (size) *size = 0;
return NULL;
}
}
UPB_INLINE void* _upb_Array_Resize_accessor2(void* msg, size_t ofs, size_t size,
int elem_size_lg2,
upb_Arena* arena) {
upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*);
upb_Array* arr = *arr_ptr;
if (!arr || arr->capacity < size) {
return _upb_Array_Resize_fallback(arr_ptr, size, elem_size_lg2, arena);
}
arr->size = size;
return _upb_array_ptr(arr);
}
UPB_INLINE bool _upb_Array_Append_accessor2(void* msg, size_t ofs,
int elem_size_lg2,
const void* value,
upb_Arena* arena) {
upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*);
size_t elem_size = 1 << elem_size_lg2;
upb_Array* arr = *arr_ptr;
void* ptr;
if (!arr || arr->size == arr->capacity) {
return _upb_Array_Append_fallback(arr_ptr, value, elem_size_lg2, arena);
}
ptr = _upb_array_ptr(arr);
memcpy(UPB_PTR_AT(ptr, arr->size * elem_size, char), value, elem_size);
arr->size++;
return true;
}
/* Used by old generated code, remove once all code has been regenerated. */
UPB_INLINE int _upb_sizelg2(upb_CType type) {
switch (type) {
case kUpb_CType_Bool:
return 0;
case kUpb_CType_Float:
case kUpb_CType_Int32:
case kUpb_CType_UInt32:
case kUpb_CType_Enum:
return 2;
case kUpb_CType_Message:
return UPB_SIZE(2, 3);
case kUpb_CType_Double:
case kUpb_CType_Int64:
case kUpb_CType_UInt64:
return 3;
case kUpb_CType_String:
case kUpb_CType_Bytes:
return UPB_SIZE(3, 4);
}
UPB_UNREACHABLE();
}
UPB_INLINE void* _upb_Array_Resize_accessor(void* msg, size_t ofs, size_t size,
upb_CType type, upb_Arena* arena) {
return _upb_Array_Resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena);
}
UPB_INLINE bool _upb_Array_Append_accessor(void* msg, size_t ofs,
size_t elem_size, upb_CType type,
const void* value,
upb_Arena* arena) {
(void)elem_size;
return _upb_Array_Append_accessor2(msg, ofs, _upb_sizelg2(type), value,
arena);
}
/** upb_Map *******************************************************************/ /** upb_Map *******************************************************************/
/* Right now we use strmaps for everything. We'll likely want to use /* Right now we use strmaps for everything. We'll likely want to use

@ -863,10 +863,11 @@ void WriteHeader(const FileLayout& layout, Output& output) {
output( output(
"#ifndef $0_UPB_H_\n" "#ifndef $0_UPB_H_\n"
"#define $0_UPB_H_\n\n" "#define $0_UPB_H_\n\n"
"#include \"upb/msg_internal.h\"\n"
"#include \"upb/decode.h\"\n" "#include \"upb/decode.h\"\n"
"#include \"upb/decode_fast.h\"\n" "#include \"upb/decode_fast.h\"\n"
"#include \"upb/encode.h\"\n\n", "#include \"upb/encode.h\"\n\n"
"#include \"upb/internal/array.h\"\n"
"#include \"upb/msg_internal.h\"\n",
ToPreproc(file->name())); ToPreproc(file->name()));
for (int i = 0; i < file->public_dependency_count(); i++) { for (int i = 0; i < file->public_dependency_count(); i++) {
@ -1480,6 +1481,7 @@ void WriteSource(const FileLayout& layout, Output& output,
output( output(
"#include <stddef.h>\n" "#include <stddef.h>\n"
"#include \"upb/internal/array.h\"\n"
"#include \"upb/msg_internal.h\"\n" "#include \"upb/msg_internal.h\"\n"
"#include \"$0\"\n", "#include \"$0\"\n",
HeaderFilename(file)); HeaderFilename(file));

Loading…
Cancel
Save