upb: implement immutability
PiperOrigin-RevId: 601848001
diff --git a/upb/message/internal/array.h b/upb/message/internal/array.h
index dc3eea9..21a8256 100644
--- a/upb/message/internal/array.h
+++ b/upb/message/internal/array.h
@@ -33,13 +33,21 @@
// 2 maps to elem size 8
// 3 maps to elem size 16
//
- // Bit #2 contains the frozen/immutable flag (currently unimplemented).
+ // Bit #2 contains the frozen/immutable flag.
uintptr_t UPB_ONLYBITS(data);
size_t UPB_ONLYBITS(size); // The number of elements in the array.
size_t UPB_PRIVATE(capacity); // Allocated storage. Measured in elements.
};
+UPB_INLINE void UPB_PRIVATE(_upb_Array_ShallowFreeze)(struct upb_Array* arr) {
+ arr->UPB_ONLYBITS(data) |= _UPB_ARRAY_MASK_IMM;
+}
+
+UPB_INLINE bool UPB_PRIVATE(_upb_Array_IsFrozen)(const struct upb_Array* arr) {
+ return (arr->UPB_ONLYBITS(data) & _UPB_ARRAY_MASK_IMM) != 0;
+}
+
UPB_INLINE void UPB_PRIVATE(_upb_Array_SetTaggedPtr)(struct upb_Array* array,
void* data, size_t lg2) {
UPB_ASSERT(lg2 != 1);
@@ -89,6 +97,7 @@
UPB_INLINE bool UPB_PRIVATE(_upb_Array_Reserve)(struct upb_Array* array,
size_t size, upb_Arena* arena) {
+ UPB_ASSERT(!UPB_PRIVATE(_upb_Array_IsFrozen)(array));
if (array->UPB_PRIVATE(capacity) < size)
return UPB_PRIVATE(_upb_Array_Realloc)(array, size, arena);
return true;
@@ -97,6 +106,7 @@
// Resize without initializing new elements.
UPB_INLINE bool UPB_PRIVATE(_upb_Array_ResizeUninitialized)(
struct upb_Array* array, size_t size, upb_Arena* arena) {
+ UPB_ASSERT(!UPB_PRIVATE(_upb_Array_IsFrozen)(array));
UPB_ASSERT(size <= array->UPB_ONLYBITS(size) ||
arena); // Allow NULL arena when shrinking.
if (!UPB_PRIVATE(_upb_Array_Reserve)(array, size, arena)) return false;
@@ -110,6 +120,7 @@
UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(struct upb_Array* array, size_t i,
const void* data,
size_t elem_size) {
+ UPB_ASSERT(!UPB_PRIVATE(_upb_Array_IsFrozen)(array));
UPB_ASSERT(i < array->UPB_ONLYBITS(size));
UPB_ASSERT(elem_size == 1U << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array));
char* arr_data = (char*)UPB_PRIVATE(_upb_Array_MutableDataPtr)(array);