diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 4fdaf1683f..db5b30d1ee 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -7098,7 +7098,7 @@ static void upb_Decoder_AddKnownMessageSetItem( } upb_Message* submsg = _upb_Decoder_NewSubMessage2( d, ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg), - &ext->ext->UPB_PRIVATE(field), (upb_TaggedMessagePtr*)&ext->data); + &ext->ext->UPB_PRIVATE(field), &ext->data.tagged_msg_val); upb_DecodeStatus status = upb_Decode( data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt), d->extreg, d->options, &d->arena); @@ -7452,7 +7452,7 @@ const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr, _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } d->original_msg = msg; - msg = (upb_Message*)&ext->data; + msg = &ext->data.UPB_PRIVATE(ext_msg_val); if (upb_MiniTableField_IsSubMessage(&ext->ext->UPB_PRIVATE(field))) { ext_sub.UPB_PRIVATE(submsg) = &ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg); @@ -8260,7 +8260,7 @@ static void encode_ext(upb_encstate* e, const upb_Extension* ext, sub.UPB_PRIVATE(subenum) = ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(subenum); } - encode_field(e, (upb_Message*)&ext->data, &sub, + encode_field(e, &ext->data.UPB_PRIVATE(ext_msg_val), &sub, &ext->ext->UPB_PRIVATE(field)); } } diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index 3d7ed26f42..ab63bb5674 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -1244,6 +1244,56 @@ UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { #include +#ifndef UPB_MESSAGE_INTERNAL_TYPES_H_ +#define UPB_MESSAGE_INTERNAL_TYPES_H_ + +#include + +// Must be last. + +#define UPB_OPAQUE(x) x##_opaque + +struct upb_Message { + union { + uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen + double d; // Forces same size for 32-bit/64-bit builds + }; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(_upb_Message_ShallowFreeze)( + struct upb_Message* msg) { + msg->UPB_OPAQUE(internal) |= 1ULL; +} + +UPB_API_INLINE bool upb_Message_IsFrozen(const struct upb_Message* msg) { + return (msg->UPB_OPAQUE(internal) & 1ULL) != 0; +} + +UPB_INLINE struct upb_Message_Internal* UPB_PRIVATE(_upb_Message_GetInternal)( + const struct upb_Message* msg) { + const uintptr_t tmp = msg->UPB_OPAQUE(internal) & ~1ULL; + return (struct upb_Message_Internal*)tmp; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetInternal)( + struct upb_Message* msg, struct upb_Message_Internal* internal) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + msg->UPB_OPAQUE(internal) = (uintptr_t)internal; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#undef UPB_OPAQUE + + +#endif /* UPB_MESSAGE_INTERNAL_TYPES_H_ */ + // Must be last. #ifdef __cplusplus @@ -1268,6 +1318,14 @@ typedef union { // documentation in kUpb_DecodeOption_ExperimentalAllowUnlinked for more // information. uintptr_t tagged_msg_val; // upb_TaggedMessagePtr + + // For an extension field, we are essentially treating ext->data (a + // upb_MessageValue) as if it were a message with one field that lives at + // offset 0. This works because upb_MessageValue is precisely one value that + // can hold any type of data. Recall that an extension can be of any type + // (scalar, repeated, or message). For a message extension, that will be a + // single upb_Message* at offset 0 of the upb_MessageValue. + struct upb_Message UPB_PRIVATE(ext_msg_val); } upb_MessageValue; UPB_API_INLINE upb_MessageValue upb_MessageValue_Zero(void) { @@ -2343,56 +2401,6 @@ bool UPB_PRIVATE(_upb_Message_Realloc)(struct upb_Message* msg, size_t need, #endif /* UPB_MESSAGE_INTERNAL_MESSAGE_H_ */ -#ifndef UPB_MESSAGE_INTERNAL_TYPES_H_ -#define UPB_MESSAGE_INTERNAL_TYPES_H_ - -#include - -// Must be last. - -#define UPB_OPAQUE(x) x##_opaque - -struct upb_Message { - union { - uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen - double d; // Forces same size for 32-bit/64-bit builds - }; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_INLINE void UPB_PRIVATE(_upb_Message_ShallowFreeze)( - struct upb_Message* msg) { - msg->UPB_OPAQUE(internal) |= 1ULL; -} - -UPB_API_INLINE bool upb_Message_IsFrozen(const struct upb_Message* msg) { - return (msg->UPB_OPAQUE(internal) & 1ULL) != 0; -} - -UPB_INLINE struct upb_Message_Internal* UPB_PRIVATE(_upb_Message_GetInternal)( - const struct upb_Message* msg) { - const uintptr_t tmp = msg->UPB_OPAQUE(internal) & ~1ULL; - return (struct upb_Message_Internal*)tmp; -} - -UPB_INLINE void UPB_PRIVATE(_upb_Message_SetInternal)( - struct upb_Message* msg, struct upb_Message_Internal* internal) { - UPB_ASSERT(!upb_Message_IsFrozen(msg)); - msg->UPB_OPAQUE(internal) = (uintptr_t)internal; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#undef UPB_OPAQUE - - -#endif /* UPB_MESSAGE_INTERNAL_TYPES_H_ */ - // Must be last. typedef struct upb_Message upb_Message; diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index 07c682741b..4acea479f1 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -7098,7 +7098,7 @@ static void upb_Decoder_AddKnownMessageSetItem( } upb_Message* submsg = _upb_Decoder_NewSubMessage2( d, ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg), - &ext->ext->UPB_PRIVATE(field), (upb_TaggedMessagePtr*)&ext->data); + &ext->ext->UPB_PRIVATE(field), &ext->data.tagged_msg_val); upb_DecodeStatus status = upb_Decode( data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt), d->extreg, d->options, &d->arena); @@ -7452,7 +7452,7 @@ const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr, _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } d->original_msg = msg; - msg = (upb_Message*)&ext->data; + msg = &ext->data.UPB_PRIVATE(ext_msg_val); if (upb_MiniTableField_IsSubMessage(&ext->ext->UPB_PRIVATE(field))) { ext_sub.UPB_PRIVATE(submsg) = &ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg); @@ -8260,7 +8260,7 @@ static void encode_ext(upb_encstate* e, const upb_Extension* ext, sub.UPB_PRIVATE(subenum) = ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(subenum); } - encode_field(e, (upb_Message*)&ext->data, &sub, + encode_field(e, &ext->data.UPB_PRIVATE(ext_msg_val), &sub, &ext->ext->UPB_PRIVATE(field)); } } diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 529e498cca..6e31636b0b 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -1246,6 +1246,56 @@ UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { #include +#ifndef UPB_MESSAGE_INTERNAL_TYPES_H_ +#define UPB_MESSAGE_INTERNAL_TYPES_H_ + +#include + +// Must be last. + +#define UPB_OPAQUE(x) x##_opaque + +struct upb_Message { + union { + uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen + double d; // Forces same size for 32-bit/64-bit builds + }; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(_upb_Message_ShallowFreeze)( + struct upb_Message* msg) { + msg->UPB_OPAQUE(internal) |= 1ULL; +} + +UPB_API_INLINE bool upb_Message_IsFrozen(const struct upb_Message* msg) { + return (msg->UPB_OPAQUE(internal) & 1ULL) != 0; +} + +UPB_INLINE struct upb_Message_Internal* UPB_PRIVATE(_upb_Message_GetInternal)( + const struct upb_Message* msg) { + const uintptr_t tmp = msg->UPB_OPAQUE(internal) & ~1ULL; + return (struct upb_Message_Internal*)tmp; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetInternal)( + struct upb_Message* msg, struct upb_Message_Internal* internal) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + msg->UPB_OPAQUE(internal) = (uintptr_t)internal; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#undef UPB_OPAQUE + + +#endif /* UPB_MESSAGE_INTERNAL_TYPES_H_ */ + // Must be last. #ifdef __cplusplus @@ -1270,6 +1320,14 @@ typedef union { // documentation in kUpb_DecodeOption_ExperimentalAllowUnlinked for more // information. uintptr_t tagged_msg_val; // upb_TaggedMessagePtr + + // For an extension field, we are essentially treating ext->data (a + // upb_MessageValue) as if it were a message with one field that lives at + // offset 0. This works because upb_MessageValue is precisely one value that + // can hold any type of data. Recall that an extension can be of any type + // (scalar, repeated, or message). For a message extension, that will be a + // single upb_Message* at offset 0 of the upb_MessageValue. + struct upb_Message UPB_PRIVATE(ext_msg_val); } upb_MessageValue; UPB_API_INLINE upb_MessageValue upb_MessageValue_Zero(void) { @@ -2345,56 +2403,6 @@ bool UPB_PRIVATE(_upb_Message_Realloc)(struct upb_Message* msg, size_t need, #endif /* UPB_MESSAGE_INTERNAL_MESSAGE_H_ */ -#ifndef UPB_MESSAGE_INTERNAL_TYPES_H_ -#define UPB_MESSAGE_INTERNAL_TYPES_H_ - -#include - -// Must be last. - -#define UPB_OPAQUE(x) x##_opaque - -struct upb_Message { - union { - uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen - double d; // Forces same size for 32-bit/64-bit builds - }; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_INLINE void UPB_PRIVATE(_upb_Message_ShallowFreeze)( - struct upb_Message* msg) { - msg->UPB_OPAQUE(internal) |= 1ULL; -} - -UPB_API_INLINE bool upb_Message_IsFrozen(const struct upb_Message* msg) { - return (msg->UPB_OPAQUE(internal) & 1ULL) != 0; -} - -UPB_INLINE struct upb_Message_Internal* UPB_PRIVATE(_upb_Message_GetInternal)( - const struct upb_Message* msg) { - const uintptr_t tmp = msg->UPB_OPAQUE(internal) & ~1ULL; - return (struct upb_Message_Internal*)tmp; -} - -UPB_INLINE void UPB_PRIVATE(_upb_Message_SetInternal)( - struct upb_Message* msg, struct upb_Message_Internal* internal) { - UPB_ASSERT(!upb_Message_IsFrozen(msg)); - msg->UPB_OPAQUE(internal) = (uintptr_t)internal; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#undef UPB_OPAQUE - - -#endif /* UPB_MESSAGE_INTERNAL_TYPES_H_ */ - // Must be last. typedef struct upb_Message upb_Message;