php/ext/google/protobuf/storage.c
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include <stdint.h>
32 #include <protobuf.h>
33 #include <Zend/zend.h>
34 
35 #include "utf8.h"
36 
37 // -----------------------------------------------------------------------------
38 // Native slot storage.
39 // -----------------------------------------------------------------------------
40 
41 #define DEREF(memory, type) *(type*)(memory)
42 
44  switch (type) {
45  case UPB_TYPE_FLOAT: return 4;
46  case UPB_TYPE_DOUBLE: return 8;
47  case UPB_TYPE_BOOL: return 1;
48  case UPB_TYPE_STRING: return sizeof(void*);
49  case UPB_TYPE_BYTES: return sizeof(void*);
50  case UPB_TYPE_MESSAGE: return sizeof(void*);
51  case UPB_TYPE_ENUM: return 4;
52  case UPB_TYPE_INT32: return 4;
53  case UPB_TYPE_INT64: return 8;
54  case UPB_TYPE_UINT32: return 4;
55  case UPB_TYPE_UINT64: return 8;
56  default: return 0;
57  }
58 }
59 
60 static bool native_slot_is_default(upb_fieldtype_t type, const void* memory) {
61  switch (type) {
62 #define CASE_TYPE(upb_type, c_type) \
63  case UPB_TYPE_##upb_type: { \
64  return DEREF(memory, c_type) == 0; \
65  }
66  CASE_TYPE(INT32, int32_t )
67  CASE_TYPE(UINT32, uint32_t)
68  CASE_TYPE(ENUM, int32_t )
69  CASE_TYPE(INT64, int64_t )
70  CASE_TYPE(UINT64, uint64_t)
71  CASE_TYPE(FLOAT, float )
72  CASE_TYPE(DOUBLE, double )
73  CASE_TYPE(BOOL, int8_t )
74 
75 #undef CASE_TYPE
76  case UPB_TYPE_STRING:
77  case UPB_TYPE_BYTES:
78  return Z_STRLEN_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(memory, CACHED_VALUE*))) ==
79  0;
80  case UPB_TYPE_MESSAGE:
81  return Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(memory, CACHED_VALUE*))) ==
82  IS_NULL;
83  default: return false;
84  }
85 }
86 
87 bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass,
88  void* memory, zval* value PHP_PROTO_TSRMLS_DC) {
89  switch (type) {
90  case UPB_TYPE_STRING:
91  case UPB_TYPE_BYTES: {
93  return false;
94  }
95  if (type == UPB_TYPE_STRING &&
96  !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) {
97  zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
98  return false;
99  }
100 
101  zval* cached_zval = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
102  if (EXPECTED(cached_zval != NULL)) {
103 #if PHP_MAJOR_VERSION < 7
104  REPLACE_ZVAL_VALUE((zval**)memory, value, 1);
105 #else
106  zend_assign_to_variable(cached_zval, value, IS_CV);
107 #endif
108  }
109  break;
110  }
111  case UPB_TYPE_MESSAGE: {
112  if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_NULL) {
113  zend_error(E_USER_ERROR, "Given value is not message.");
114  return false;
115  }
116  if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) {
117  zend_error(E_USER_ERROR, "Given message does not have correct class.");
118  return false;
119  }
120 
121  zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
122  if (EXPECTED(property_ptr != value)) {
123  php_proto_zval_ptr_dtor(property_ptr);
124  }
125 
126 #if PHP_MAJOR_VERSION < 7
127  DEREF(memory, zval*) = value;
128  Z_ADDREF_P(value);
129 #else
130  ZVAL_ZVAL(property_ptr, value, 1, 0);
131 #endif
132  break;
133  }
134 
135 #define CASE_TYPE(upb_type, type, c_type, php_type) \
136  case UPB_TYPE_##upb_type: { \
137  c_type type##_value; \
138  if (protobuf_convert_to_##type(value, &type##_value)) { \
139  DEREF(memory, c_type) = type##_value; \
140  } \
141  break; \
142  }
143  CASE_TYPE(INT32, int32, int32_t, LONG)
144  CASE_TYPE(UINT32, uint32, uint32_t, LONG)
145  CASE_TYPE(ENUM, int32, int32_t, LONG)
146  CASE_TYPE(INT64, int64, int64_t, LONG)
147  CASE_TYPE(UINT64, uint64, uint64_t, LONG)
148  CASE_TYPE(FLOAT, float, float, DOUBLE)
149  CASE_TYPE(DOUBLE, double, double, DOUBLE)
150  CASE_TYPE(BOOL, bool, int8_t, BOOL)
151 
152 #undef CASE_TYPE
153 
154  default:
155  break;
156  }
157 
158  return true;
159 }
160 
162  const zend_class_entry* klass, void* memory,
163  zval* value TSRMLS_DC) {
164 #if PHP_MAJOR_VERSION >= 7
165  if (Z_ISREF_P(value)) {
166  ZVAL_DEREF(value);
167  }
168 #endif
169  switch (type) {
170  case UPB_TYPE_STRING:
171  case UPB_TYPE_BYTES: {
173  return false;
174  }
175  if (type == UPB_TYPE_STRING &&
176  !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) {
177  zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
178  return false;
179  }
180 
181  // Handles repeated/map string field. Memory provided by
182  // RepeatedField/Map is not initialized.
183 #if PHP_MAJOR_VERSION < 7
184  MAKE_STD_ZVAL(DEREF(memory, zval*));
185  PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
186  Z_STRLEN_P(value), 1);
187 #else
188  *(zend_string**)memory =
189  zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0);
190 #endif
191  break;
192  }
193  case UPB_TYPE_MESSAGE: {
194  if (Z_TYPE_P(value) != IS_OBJECT) {
195  zend_error(E_USER_ERROR, "Given value is not message.");
196  return false;
197  }
198  if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) {
199  zend_error(E_USER_ERROR, "Given message does not have correct class.");
200  return false;
201  }
202 #if PHP_MAJOR_VERSION < 7
203  if (EXPECTED(DEREF(memory, zval*) != value)) {
204  DEREF(memory, zval*) = value;
205  Z_ADDREF_P(value);
206  }
207 #else
208  DEREF(memory, zval*) = value;
210 #endif
211  break;
212  }
213  default:
214  return native_slot_set(type, klass, memory, value TSRMLS_CC);
215  }
216  return true;
217 }
218 
219 bool native_slot_set_by_map(upb_fieldtype_t type, const zend_class_entry* klass,
220  void* memory, zval* value TSRMLS_DC) {
221 #if PHP_MAJOR_VERSION >= 7
222  if (Z_ISREF_P(value)) {
223  ZVAL_DEREF(value);
224  }
225 #endif
226  switch (type) {
227  case UPB_TYPE_STRING:
228  case UPB_TYPE_BYTES: {
230  return false;
231  }
232  if (type == UPB_TYPE_STRING &&
233  !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) {
234  zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
235  return false;
236  }
237 
238  // Handles repeated/map string field. Memory provided by
239  // RepeatedField/Map is not initialized.
240 #if PHP_MAJOR_VERSION < 7
241  MAKE_STD_ZVAL(DEREF(memory, zval*));
242  PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
243  Z_STRLEN_P(value), 1);
244 #else
245  *(zend_string**)memory =
246  zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0);
247 #endif
248  break;
249  }
250  case UPB_TYPE_MESSAGE: {
251  if (Z_TYPE_P(value) != IS_OBJECT) {
252  zend_error(E_USER_ERROR, "Given value is not message.");
253  return false;
254  }
255  if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) {
256  zend_error(E_USER_ERROR, "Given message does not have correct class.");
257  return false;
258  }
259 #if PHP_MAJOR_VERSION < 7
260  if (EXPECTED(DEREF(memory, zval*) != value)) {
261  DEREF(memory, zval*) = value;
262  Z_ADDREF_P(value);
263  }
264 #else
265  DEREF(memory, zend_object*) = Z_OBJ_P(value);
267 #endif
268  break;
269  }
270  default:
271  return native_slot_set(type, klass, memory, value TSRMLS_CC);
272  }
273  return true;
274 }
275 
276 void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) {
277  zval* tmp = NULL;
278  switch (type) {
279  case UPB_TYPE_FLOAT:
280  DEREF(memory, float) = 0.0;
281  break;
282  case UPB_TYPE_DOUBLE:
283  DEREF(memory, double) = 0.0;
284  break;
285  case UPB_TYPE_BOOL:
286  DEREF(memory, int8_t) = 0;
287  break;
288  case UPB_TYPE_STRING:
289  case UPB_TYPE_BYTES:
290  case UPB_TYPE_MESSAGE:
291  DEREF(memory, CACHED_VALUE*) = cache;
292  break;
293  case UPB_TYPE_ENUM:
294  case UPB_TYPE_INT32:
295  DEREF(memory, int32_t) = 0;
296  break;
297  case UPB_TYPE_INT64:
298  DEREF(memory, int64_t) = 0;
299  break;
300  case UPB_TYPE_UINT32:
301  DEREF(memory, uint32_t) = 0;
302  break;
303  case UPB_TYPE_UINT64:
304  DEREF(memory, uint64_t) = 0;
305  break;
306  default:
307  break;
308  }
309 }
310 
311 void native_slot_get(upb_fieldtype_t type, const void* memory,
312  CACHED_VALUE* cache TSRMLS_DC) {
313  switch (type) {
314 #define CASE(upb_type, php_type, c_type) \
315  case UPB_TYPE_##upb_type: \
316  PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \
317  ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \
318  return;
319 
320  CASE(FLOAT, DOUBLE, float)
321  CASE(DOUBLE, DOUBLE, double)
322  CASE(BOOL, BOOL, int8_t)
323  CASE(INT32, LONG, int32_t)
324  CASE(ENUM, LONG, uint32_t)
325 
326 #undef CASE
327 
328 #if SIZEOF_LONG == 4
329 #define CASE(upb_type, c_type) \
330  case UPB_TYPE_##upb_type: { \
331  PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \
332  char buffer[MAX_LENGTH_OF_INT64]; \
333  sprintf(buffer, "%lld", DEREF(memory, c_type)); \
334  PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), buffer, 1); \
335  return; \
336  }
337 #else
338 #define CASE(upb_type, c_type) \
339  case UPB_TYPE_##upb_type: { \
340  PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \
341  ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \
342  return; \
343  }
344 #endif
345 CASE(UINT64, uint64_t)
346 CASE(INT64, int64_t)
347 #undef CASE
348 
349  case UPB_TYPE_UINT32: {
350  // Prepend bit-1 for negative numbers, so that uint32 value will be
351  // consistent on both 32-bit and 64-bit architectures.
353  int value = DEREF(memory, int32_t);
354  if (sizeof(int) == 8) {
355  value |= (-((value >> 31) & 0x1) & 0xFFFFFFFF00000000);
356  }
357  ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), value);
358  return;
359  }
360 
361  case UPB_TYPE_STRING:
362  case UPB_TYPE_BYTES: {
363  // For optional string/bytes/message fields, the cache is owned by the
364  // containing message and should have been updated during
365  // setting/decoding. However, oneof accessor call this function by
366  // providing the return value directly, which is not the same as the cache
367  // value.
368  zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
369  if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) {
371  Z_STRLEN_P(value), 1);
372  }
373  break;
374  }
375  case UPB_TYPE_MESSAGE: {
376  // Same as above for string/bytes fields.
377  zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
378  if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) {
379  ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0);
380  }
381  return;
382  }
383  default:
384  return;
385  }
386 }
387 
389  CACHED_VALUE* cache TSRMLS_DC) {
390  switch (type) {
391  case UPB_TYPE_STRING:
392  case UPB_TYPE_BYTES: {
393 #if PHP_MAJOR_VERSION < 7
394  zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
395  if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) {
397  Z_STRVAL_P(value), Z_STRLEN_P(value), 1);
398  }
399 #else
400  ZVAL_NEW_STR(cache, zend_string_dup(*(zend_string**)memory, 0));
401 #endif
402  return;
403  }
404  case UPB_TYPE_MESSAGE: {
405 #if PHP_MAJOR_VERSION < 7
406  zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
407  if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) {
408  ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0);
409  }
410 #else
411  ZVAL_COPY(CACHED_PTR_TO_ZVAL_PTR(cache), memory);
412 #endif
413  return;
414  }
415  default:
416  native_slot_get(type, memory, cache TSRMLS_CC);
417  }
418 }
419 
421  int length, CACHED_VALUE* cache TSRMLS_DC) {
422  switch (type) {
423  case UPB_TYPE_STRING:
424  case UPB_TYPE_BYTES: {
426  return;
427  }
428  default:
429  native_slot_get(type, memory, cache TSRMLS_CC);
430  }
431 }
432 
434  CACHED_VALUE* cache TSRMLS_DC) {
435  switch (type) {
436  case UPB_TYPE_MESSAGE: {
437 #if PHP_MAJOR_VERSION < 7
438  zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
439  if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) {
440  ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0);
441  }
442 #else
443  GC_ADDREF(*(zend_object**)memory);
444  ZVAL_OBJ(cache, *(zend_object**)memory);
445 #endif
446  return;
447  }
448  default:
449  native_slot_get_by_array(type, memory, cache TSRMLS_CC);
450  }
451 }
452 
454  CACHED_VALUE* cache TSRMLS_DC) {
455  switch (type) {
456 #define CASE(upb_type, php_type) \
457  case UPB_TYPE_##upb_type: \
458  PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \
459  ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \
460  return;
461 
462  CASE(FLOAT, DOUBLE)
463  CASE(DOUBLE, DOUBLE)
464  CASE(BOOL, BOOL)
465  CASE(INT32, LONG)
466  CASE(UINT32, LONG)
467  CASE(ENUM, LONG)
468 
469 #undef CASE
470 
471 #if SIZEOF_LONG == 4
472 #define CASE(upb_type) \
473  case UPB_TYPE_##upb_type: { \
474  PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \
475  PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), "0", 1); \
476  return; \
477  }
478 #else
479 #define CASE(upb_type) \
480  case UPB_TYPE_##upb_type: { \
481  PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \
482  ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \
483  return; \
484  }
485 #endif
486 CASE(UINT64)
487 CASE(INT64)
488 #undef CASE
489 
490  case UPB_TYPE_STRING:
491  case UPB_TYPE_BYTES: {
494  break;
495  }
496  case UPB_TYPE_MESSAGE: {
498  ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(cache));
499  return;
500  }
501  default:
502  return;
503  }
504 }
505 
506 // -----------------------------------------------------------------------------
507 // Map field utilities.
508 // ----------------------------------------------------------------------------
509 
511  const upb_msgdef* subdef;
514  return NULL;
515  }
516  subdef = upb_fielddef_msgsubdef(field);
517  return upb_msgdef_mapentry(subdef) ? subdef : NULL;
518 }
519 
521  const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
522  assert(subdef);
523  return subdef;
524 }
525 
528 }
529 
531  const upb_msgdef* subdef = map_entry_msgdef(field);
532  return map_entry_key(subdef);
533 }
534 
536  const upb_msgdef* subdef = map_entry_msgdef(field);
537  return map_entry_value(subdef);
538 }
539 
541  const upb_fielddef* key_field = upb_msgdef_itof(msgdef, MAP_KEY_FIELD);
542  assert(key_field != NULL);
543  return key_field;
544 }
545 
547  const upb_fielddef* value_field = upb_msgdef_itof(msgdef, MAP_VALUE_FIELD);
548  assert(value_field != NULL);
549  return value_field;
550 }
551 
552 const zend_class_entry* field_type_class(
557  return desc->klass;
558  } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
561  return desc->klass;
562  }
563  return NULL;
564 }
565 
566 // -----------------------------------------------------------------------------
567 // Memory layout management.
568 // -----------------------------------------------------------------------------
569 
570 static size_t align_up_to(size_t offset, size_t granularity) {
571  // Granularity must be a power of two.
572  return (offset + granularity - 1) & ~(granularity - 1);
573 }
574 
575 uint32_t* slot_oneof_case(MessageLayout* layout, const void* storage,
576  const upb_fielddef* field) {
577  return (uint32_t*)(((uint8_t*)storage) +
579 }
580 
581 static int slot_property_cache(MessageLayout* layout, const void* storage,
582  const upb_fielddef* field) {
584 }
585 
586 void* slot_memory(MessageLayout* layout, const void* storage,
587  const upb_fielddef* field) {
588  return ((uint8_t*)storage) + layout->fields[upb_fielddef_index(field)].offset;
589 }
590 
593  int nfields = upb_msgdef_numfields(msgdef);
595  upb_msg_oneof_iter oit;
596  size_t off = 0;
597  int i = 0;
598 
599  // Reserve space for unknown fields.
600  off += sizeof(void*);
601 
602  TSRMLS_FETCH();
604  layout->fields = ALLOC_N(MessageField, nfields);
605 
609  size_t field_size;
610 
612  // Oneofs are handled separately below.
613  continue;
614  }
615 
616  // Allocate |field_size| bytes for this field in the layout.
617  field_size = 0;
619  field_size = sizeof(zval*);
620  } else {
622  }
623 
624  // Align current offset up to | size | granularity.
625  off = align_up_to(off, field_size);
629 
630  const char* fieldname = upb_fielddef_name(field);
631 
632 #if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
633  zend_class_entry* old_scope = EG(scope);
634  EG(scope) = desc->klass;
635 #else
636  zend_class_entry* old_scope = EG(fake_scope);
637  EG(fake_scope) = desc->klass;
638 #endif
639 
640 #if PHP_MAJOR_VERSION < 7
641  zval member;
642  ZVAL_STRINGL(&member, fieldname, strlen(fieldname), 0);
643  zend_property_info* property_info =
644  zend_get_property_info(desc->klass, &member, true TSRMLS_CC);
645 #else
646  zend_string* member = zend_string_init(fieldname, strlen(fieldname), 1);
647  zend_property_info* property_info =
648  zend_get_property_info(desc->klass, member, true);
649  zend_string_release(member);
650 #endif
651 
652 #if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
653  EG(scope) = old_scope;
654 #else
655  EG(fake_scope) = old_scope;
656 #endif
657 
659  property_info->offset;
660  off += field_size;
661  }
662 
663  // Handle oneofs now -- we iterate over oneofs specifically and allocate only
664  // one slot per oneof.
665  //
666  // We assign all value slots first, then pack the 'case' fields at the end,
667  // since in the common case (modern 64-bit platform) these are 8 bytes and 4
668  // bytes respectively and we want to avoid alignment overhead.
669  //
670  // Note that we reserve 4 bytes (a uint32) per 'case' slot because the value
671  // space for oneof cases is conceptually as wide as field tag numbers. In
672  // practice, it's unlikely that a oneof would have more than e.g. 256 or 64K
673  // members (8 or 16 bits respectively), so conceivably we could assign
674  // consecutive case numbers and then pick a smaller oneof case slot size, but
675  // the complexity to implement this indirection is probably not worthwhile.
676  for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit);
677  upb_msg_oneof_next(&oit)) {
678  const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
679  upb_oneof_iter fit;
680 
681  // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between
682  // all fields.
683  size_t field_size = NATIVE_SLOT_MAX_SIZE;
684  // Align the offset .
685  off = align_up_to( off, field_size);
686  // Assign all fields in the oneof this same offset.
687  const char* oneofname = upb_oneofdef_name(oneof);
688  for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
689  upb_oneof_next(&fit)) {
690  const upb_fielddef* field = upb_oneof_iter_field(&fit);
692 
693 #if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
694  zend_class_entry* old_scope = EG(scope);
695  EG(scope) = desc->klass;
696 #else
697  zend_class_entry* old_scope = EG(fake_scope);
698  EG(fake_scope) = desc->klass;
699 #endif
700 
701 #if PHP_MAJOR_VERSION < 7
702  zval member;
703  ZVAL_STRINGL(&member, oneofname, strlen(oneofname), 0);
704  zend_property_info* property_info =
705  zend_get_property_info(desc->klass, &member, true TSRMLS_CC);
706 #else
707  zend_string* member = zend_string_init(oneofname, strlen(oneofname), 1);
708  zend_property_info* property_info =
709  zend_get_property_info(desc->klass, member, true);
710  zend_string_release(member);
711 #endif
712 
713 #if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
714  EG(scope) = old_scope;
715 #else
716  EG(fake_scope) = old_scope;
717 #endif
718 
720  property_info->offset;
721  }
722  i++;
723  off += field_size;
724  }
725 
726  // Now the case offset.
727  for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit);
728  upb_msg_oneof_next(&oit)) {
729  const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
730  upb_oneof_iter fit;
731 
732  size_t field_size = sizeof(uint32_t);
733  // Align the offset .
734  off = (off + field_size - 1) & ~(field_size - 1);
735  // Assign all fields in the oneof this same offset.
736  for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
737  upb_oneof_next(&fit)) {
738  const upb_fielddef* field = upb_oneof_iter_field(&fit);
740  }
741  off += field_size;
742  }
743 
744  layout->size = off;
745  layout->msgdef = msgdef;
746 
747  return layout;
748 }
749 
751  FREE(layout->fields);
752  FREE(layout);
753 }
754 
755 void layout_init(MessageLayout* layout, void* storage,
756  zend_object* object PHP_PROTO_TSRMLS_DC) {
757  int i;
759 
760  // Init unknown fields
761  memset(storage, 0, sizeof(void*));
762 
764  upb_msg_field_next(&it), i++) {
766  void* memory = slot_memory(layout, storage, field);
767  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
768  int cache_index = slot_property_cache(layout, storage, field);
769  CACHED_VALUE* property_ptr = OBJ_PROP(object, cache_index);
770 
772  memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
773  *oneof_case = ONEOF_CASE_NONE;
774  } else if (is_map_field(field)) {
775  zval_ptr_dtor(property_ptr);
776 #if PHP_MAJOR_VERSION < 7
777  MAKE_STD_ZVAL(*property_ptr);
778 #endif
780  property_ptr PHP_PROTO_TSRMLS_CC);
781  DEREF(memory, CACHED_VALUE*) = property_ptr;
783  zval_ptr_dtor(property_ptr);
784 #if PHP_MAJOR_VERSION < 7
785  MAKE_STD_ZVAL(*property_ptr);
786 #endif
788  property_ptr PHP_PROTO_TSRMLS_CC);
789  DEREF(memory, CACHED_VALUE*) = property_ptr;
790  } else {
791  native_slot_init(upb_fielddef_type(field), memory, property_ptr);
792  }
793  }
794 }
795 
796 // For non-singular fields, the related memory needs to point to the actual
797 // zval in properties table first.
798 static void* value_memory(const upb_fielddef* field, void* memory) {
799  switch (upb_fielddef_type(field)) {
800  case UPB_TYPE_STRING:
801  case UPB_TYPE_BYTES:
802  case UPB_TYPE_MESSAGE:
803  memory = DEREF(memory, CACHED_VALUE*);
804  break;
805  default:
806  // No operation
807  break;
808  }
809  return memory;
810 }
811 
812 zval* layout_get(MessageLayout* layout, const void* storage,
813  const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC) {
814  void* memory = slot_memory(layout, storage, field);
815  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
816 
818  if (*oneof_case != upb_fielddef_number(field)) {
820  } else {
822  cache TSRMLS_CC);
823  }
824  return CACHED_PTR_TO_ZVAL_PTR(cache);
826  return CACHED_PTR_TO_ZVAL_PTR(cache);
827  } else {
829  cache TSRMLS_CC);
830  return CACHED_PTR_TO_ZVAL_PTR(cache);
831  }
832 }
833 
835  const upb_fielddef* field, zval* val TSRMLS_DC) {
836  void* storage = message_data(header);
837  void* memory = slot_memory(layout, storage, field);
838  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
839 
842  zend_class_entry *ce = NULL;
843 
844  // For non-singular fields, the related memory needs to point to the actual
845  // zval in properties table first.
846  switch (type) {
847  case UPB_TYPE_MESSAGE: {
850  ce = desc->klass;
851  // Intentionally fall through.
852  }
853  case UPB_TYPE_STRING:
854  case UPB_TYPE_BYTES: {
855  int property_cache_index =
856  header->descriptor->layout->fields[upb_fielddef_index(field)]
857  .cache_index;
858  DEREF(memory, CACHED_VALUE*) =
859  OBJ_PROP(&header->std, property_cache_index);
860  memory = DEREF(memory, CACHED_VALUE*);
861  break;
862  }
863  default:
864  break;
865  }
866 
867  native_slot_set(type, ce, memory, val TSRMLS_CC);
868  *oneof_case = upb_fielddef_number(field);
870  // Works for both repeated and map fields
871  memory = DEREF(memory, void**);
872  zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
873 
874  if (EXPECTED(property_ptr != val)) {
875  zend_class_entry *subce = NULL;
876  zval converted_value;
877 
878  if (upb_fielddef_ismap(field)) {
879  const upb_msgdef* mapmsg = upb_fielddef_msgsubdef(field);
880  const upb_fielddef* keyfield = upb_msgdef_ntof(mapmsg, "key", 3);
881  const upb_fielddef* valuefield = upb_msgdef_ntof(mapmsg, "value", 5);
882  if (upb_fielddef_descriptortype(valuefield) ==
884  const upb_msgdef* submsg = upb_fielddef_msgsubdef(valuefield);
885  Descriptor* subdesc =
887  subce = subdesc->klass;
888  }
890  upb_fielddef_descriptortype(valuefield), val,
891  &converted_value);
892  } else {
894  const upb_msgdef* submsg = upb_fielddef_msgsubdef(field);
895  Descriptor* subdesc =
897  subce = subdesc->klass;
898  }
899 
901  &converted_value);
902  }
903 #if PHP_MAJOR_VERSION < 7
904  REPLACE_ZVAL_VALUE((zval**)memory, &converted_value, 1);
905 #else
906  php_proto_zval_ptr_dtor(property_ptr);
907  ZVAL_ZVAL(property_ptr, &converted_value, 1, 0);
908 #endif
909  zval_dtor(&converted_value);
910  }
911  } else {
913  zend_class_entry *ce = NULL;
914  if (type == UPB_TYPE_MESSAGE) {
917  ce = desc->klass;
918  }
919  native_slot_set(type, ce, value_memory(field, memory), val TSRMLS_CC);
920  }
921 }
922 
923 static void native_slot_merge(const upb_fielddef* field, const void* from_memory,
924  void* to_memory PHP_PROTO_TSRMLS_DC) {
926  zend_class_entry* ce = NULL;
927  if (!native_slot_is_default(type, from_memory)) {
928  switch (type) {
929 #define CASE_TYPE(upb_type, c_type) \
930  case UPB_TYPE_##upb_type: { \
931  DEREF(to_memory, c_type) = DEREF(from_memory, c_type); \
932  break; \
933  }
934  CASE_TYPE(INT32, int32_t)
935  CASE_TYPE(UINT32, uint32_t)
936  CASE_TYPE(ENUM, int32_t)
937  CASE_TYPE(INT64, int64_t)
938  CASE_TYPE(UINT64, uint64_t)
939  CASE_TYPE(FLOAT, float)
940  CASE_TYPE(DOUBLE, double)
941  CASE_TYPE(BOOL, int8_t)
942 
943 #undef CASE_TYPE
944  case UPB_TYPE_STRING:
945  case UPB_TYPE_BYTES:
948  from_memory, CACHED_VALUE*)) PHP_PROTO_TSRMLS_CC);
949  break;
950  case UPB_TYPE_MESSAGE: {
953  ce = desc->klass;
954  if (native_slot_is_default(type, to_memory)) {
955 #if PHP_MAJOR_VERSION < 7
956  SEPARATE_ZVAL_IF_NOT_REF((zval**)value_memory(field, to_memory));
957 #endif
959  CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*)), ce);
960  MessageHeader* submsg =
964  }
965 
966  MessageHeader* sub_from =
968  CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*)));
969  MessageHeader* sub_to =
972 
973  layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC);
974  break;
975  }
976  }
977  }
978 }
979 
980 static void native_slot_merge_by_array(const upb_fielddef* field, const void* from_memory,
981  void* to_memory PHP_PROTO_TSRMLS_DC) {
983  switch (type) {
984  case UPB_TYPE_STRING:
985  case UPB_TYPE_BYTES: {
986 #if PHP_MAJOR_VERSION < 7
987  MAKE_STD_ZVAL(DEREF(to_memory, zval*));
988  PHP_PROTO_ZVAL_STRINGL(DEREF(to_memory, zval*),
989  Z_STRVAL_P(*(zval**)from_memory),
990  Z_STRLEN_P(*(zval**)from_memory), 1);
991 #else
992  DEREF(to_memory, zend_string*) =
993  zend_string_dup(*(zend_string**)from_memory, 0);
994 #endif
995  break;
996  }
997  case UPB_TYPE_MESSAGE: {
1000  zend_class_entry* ce = desc->klass;
1001 #if PHP_MAJOR_VERSION < 7
1002  MAKE_STD_ZVAL(DEREF(to_memory, zval*));
1003  CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(DEREF(to_memory, zval*), ce);
1004 #else
1005  DEREF(to_memory, zend_object*) = ce->create_object(ce TSRMLS_CC);
1006 #endif
1012 
1013  layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC);
1014  break;
1015  }
1016  default:
1017  native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC);
1018  break;
1019  }
1020 }
1021 
1024  int i, j;
1026 
1028  upb_msg_field_next(&it), i++) {
1030 
1031  void* to_memory = slot_memory(layout, message_data(to), field);
1032  void* from_memory = slot_memory(layout, message_data(from), field);
1033 
1035  uint32_t oneof_case_offset =
1037  // For a oneof, check that this field is actually present -- skip all the
1038  // below if not.
1039  if (DEREF((message_data(from) + oneof_case_offset), uint32_t) !=
1041  continue;
1042  }
1043  uint32_t* from_oneof_case = slot_oneof_case(layout, message_data(from), field);
1044  uint32_t* to_oneof_case = slot_oneof_case(layout, message_data(to), field);
1045 
1046  // For non-singular fields, the related memory needs to point to the
1047  // actual zval in properties table first.
1048  switch (upb_fielddef_type(field)) {
1049  case UPB_TYPE_MESSAGE:
1050  case UPB_TYPE_STRING:
1051  case UPB_TYPE_BYTES: {
1052  int property_cache_index =
1054  DEREF(to_memory, CACHED_VALUE*) =
1055  OBJ_PROP(&to->std, property_cache_index);
1056  break;
1057  }
1058  default:
1059  break;
1060  }
1061 
1062  *to_oneof_case = *from_oneof_case;
1063 
1064  // Otherwise, fall through to the appropriate singular-field handler
1065  // below.
1066  }
1067 
1068  if (is_map_field(field)) {
1069  int size, key_length, value_length;
1070  MapIter map_it;
1071 
1072  zval* to_map_php =
1074  zval* from_map_php =
1075  CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*));
1076  Map* to_map = UNBOX(Map, to_map_php);
1077  Map* from_map = UNBOX(Map, from_map_php);
1078 
1079  size = upb_strtable_count(&from_map->table);
1080  if (size == 0) continue;
1081 
1082  const upb_msgdef *mapentry_def = upb_fielddef_msgsubdef(field);
1083  const upb_fielddef *value_field = upb_msgdef_itof(mapentry_def, 2);
1084 
1085  for (map_begin(from_map_php, &map_it TSRMLS_CC); !map_done(&map_it);
1086  map_next(&map_it)) {
1087  const char* key = map_iter_key(&map_it, &key_length);
1088  upb_value from_value = map_iter_value(&map_it, &value_length);
1089  upb_value to_value;
1090  void* from_mem = upb_value_memory(&from_value);
1091  void* to_mem = upb_value_memory(&to_value);
1092  memset(to_mem, 0, native_slot_size(to_map->value_type));
1093 
1094  native_slot_merge_by_array(value_field, from_mem,
1095  to_mem PHP_PROTO_TSRMLS_CC);
1096 
1097  map_index_set(to_map, key, key_length, to_value);
1098  }
1099 
1100  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
1101  zval* to_array_php = CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*));
1102  zval* from_array_php = CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*));
1103  RepeatedField* to_array = UNBOX(RepeatedField, to_array_php);
1104  RepeatedField* from_array = UNBOX(RepeatedField, from_array_php);
1105 
1106  int size = zend_hash_num_elements(PHP_PROTO_HASH_OF(from_array->array));
1107  if (size > 0) {
1108  for (j = 0; j < size; j++) {
1109  void* from_memory = NULL;
1110  void* to_memory =
1112  memset(to_memory, 0, native_slot_size(upb_fielddef_type(field)));
1113 
1114  if (to_array->type == UPB_TYPE_MESSAGE) {
1116  PHP_PROTO_HASH_OF(from_array->array), j, (void**)&from_memory);
1117 #if PHP_MAJOR_VERSION >= 7
1118  from_memory = &Z_OBJ_P((zval*)from_memory);
1119 #endif
1120  } else {
1122  PHP_PROTO_HASH_OF(from_array->array), j, (void**)&from_memory);
1123  }
1124 
1125  native_slot_merge_by_array(field, from_memory,
1126  to_memory PHP_PROTO_TSRMLS_CC);
1127  repeated_field_push_native(to_array, to_memory);
1128  FREE(to_memory);
1129  }
1130  }
1131  } else {
1132  native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC);
1133  }
1134  }
1135 }
1136 
1137 const char* layout_get_oneof_case(MessageLayout* layout, const void* storage,
1138  const upb_oneofdef* oneof TSRMLS_DC) {
1139  upb_oneof_iter i;
1140  const upb_fielddef* first_field;
1141 
1142  // Oneof is guaranteed to have at least one field. Get the first field.
1143  for(upb_oneof_begin(&i, oneof); !upb_oneof_done(&i); upb_oneof_next(&i)) {
1144  first_field = upb_oneof_iter_field(&i);
1145  break;
1146  }
1147 
1148  uint32_t* oneof_case = slot_oneof_case(layout, storage, first_field);
1149  if (*oneof_case == 0) {
1150  return "";
1151  }
1152  const upb_fielddef* field = upb_oneofdef_itof(oneof, *oneof_case);
1153  return upb_fielddef_name(field);
1154 }
slot_memory
void * slot_memory(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:586
msgdef
const upb_msgdef * msgdef
Definition: php/ext/google/protobuf/protobuf.h:799
map_entry_key
const upb_fielddef * map_entry_key(const upb_msgdef *msgdef)
Definition: php/ext/google/protobuf/storage.c:540
GC_ADDREF
#define GC_ADDREF(h)
Definition: php/ext/google/protobuf/protobuf.h:54
upb_value_memory
void * upb_value_memory(upb_value *v)
Definition: php/ext/google/protobuf/map.c:52
UNBOX_HASHTABLE_VALUE
#define UNBOX_HASHTABLE_VALUE(class_name, val)
Definition: php/ext/google/protobuf/protobuf.h:236
upb_msg_iter_oneof
const upb_oneofdef * upb_msg_iter_oneof(const upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1867
field_type_class
const zend_class_entry * field_type_class(const upb_fielddef *field PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:552
MessageLayout::size
size_t size
Definition: php/ext/google/protobuf/protobuf.h:930
PHP_PROTO_TSRMLS_DC
#define PHP_PROTO_TSRMLS_DC
Definition: php/ext/google/protobuf/protobuf.h:64
PHP_PROTO_TSRMLS_CC
#define PHP_PROTO_TSRMLS_CC
Definition: php/ext/google/protobuf/protobuf.h:65
native_slot_merge
static void native_slot_merge(const upb_fielddef *field, const void *from_memory, void *to_memory PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:923
custom_data_init
void custom_data_init(const zend_class_entry *ce, MessageHeader *intern PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/message.c:252
Map
Definition: ruby/ext/google/protobuf_c/protobuf.h:442
CACHED_PTR_TO_ZVAL_PTR
#define CACHED_PTR_TO_ZVAL_PTR(VALUE)
Definition: php/ext/google/protobuf/protobuf.h:194
upb_msgdef_mapentry
bool upb_msgdef_mapentry(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1809
MessageField::offset
size_t offset
Definition: php/ext/google/protobuf/protobuf.h:921
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
map_iter_key
const char * map_iter_key(MapIter *iter, int *len)
Definition: php/ext/google/protobuf/map.c:508
length
GLenum GLuint GLenum GLsizei length
Definition: glcorearb.h:2695
upb_fielddef_descriptortype
upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1540
upb_oneofdef_itof
const upb_fielddef * upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num)
Definition: php/ext/google/protobuf/upb.c:1905
FREE
#define FREE(object)
Definition: php/ext/google/protobuf/protobuf.h:1480
MessageHeader
Definition: ruby/ext/google/protobuf_c/protobuf.h:551
upb_msg_field_begin
void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1823
upb_value
Definition: php/ext/google/protobuf/upb.h:2656
message_data
void * message_data(MessageHeader *msg)
Definition: php/ext/google/protobuf/message.c:248
map_field_value
const upb_fielddef * map_field_value(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:535
UPB_TYPE_INT32
@ UPB_TYPE_INT32
Definition: php/ext/google/protobuf/upb.h:415
map_field_create_with_field
void map_field_create_with_field(const zend_class_entry *ce, const upb_fielddef *field, CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC)
check_map_field
void check_map_field(const zend_class_entry *klass, PHP_PROTO_LONG key_type, PHP_PROTO_LONG value_type, zval *val, zval *return_value)
Definition: type_check.c:524
map_index_set
bool map_index_set(Map *intern, const char *keyval, int length, upb_value v)
Definition: php/ext/google/protobuf/map.c:330
layout_get
zval * layout_get(MessageLayout *layout, const void *storage, const upb_fielddef *field, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:812
DEREF
#define DEREF(memory, type)
Definition: php/ext/google/protobuf/storage.c:41
google::protobuf::uint32
uint32_t uint32
Definition: protobuf/src/google/protobuf/stubs/port.h:155
desc
#define desc
Definition: extension_set.h:342
repeated_field_create_with_field
void repeated_field_create_with_field(zend_class_entry *ce, const upb_fielddef *field, CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC)
Definition: array.c:262
MessageField
Definition: php/ext/google/protobuf/protobuf.h:920
native_slot_size
size_t native_slot_size(upb_fieldtype_t type)
Definition: php/ext/google/protobuf/storage.c:43
native_slot_merge_by_array
static void native_slot_merge_by_array(const upb_fielddef *field, const void *from_memory, void *to_memory PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:980
CACHED_VALUE
#define CACHED_VALUE
Definition: php/ext/google/protobuf/protobuf.h:192
layout_merge
void layout_merge(MessageLayout *layout, MessageHeader *from, MessageHeader *to PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:1022
MapIter
struct MapIter MapIter
Definition: php/ext/google/protobuf/protobuf.h:647
PHP_PROTO_HASHTABLE_VALUE
#define PHP_PROTO_HASHTABLE_VALUE
Definition: php/ext/google/protobuf/protobuf.h:240
upb_fielddef_enumsubdef
const upb_enumdef * upb_fielddef_enumsubdef(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1682
Z_OBJ_P
#define Z_OBJ_P(zval_p)
Definition: php/ext/google/protobuf/protobuf.h:1488
map_iter_value
upb_value map_iter_value(MapIter *iter, int *len)
Definition: php/ext/google/protobuf/map.c:513
CASE
#define CASE(upb_type, php_type, c_type)
map_done
bool map_done(MapIter *iter)
Definition: php/ext/google/protobuf/map.c:504
UPB_TYPE_FLOAT
@ UPB_TYPE_FLOAT
Definition: php/ext/google/protobuf/upb.h:414
create_layout
MessageLayout * create_layout(const upb_msgdef *msgdef)
Definition: php/ext/google/protobuf/storage.c:591
native_slot_set_by_array
bool native_slot_set_by_array(upb_fieldtype_t type, const zend_class_entry *klass, void *memory, zval *value TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:161
layout_set
void layout_set(MessageLayout *layout, MessageHeader *header, const upb_fielddef *field, zval *val TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:834
slot_oneof_case
uint32_t * slot_oneof_case(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:575
free_layout
void free_layout(MessageLayout *layout)
Definition: php/ext/google/protobuf/storage.c:750
php_proto_zend_hash_index_find_mem
#define php_proto_zend_hash_index_find_mem(ht, h, pDest)
Definition: php/ext/google/protobuf/protobuf.h:108
value_memory
static void * value_memory(const upb_fielddef *field, void *memory)
Definition: php/ext/google/protobuf/storage.c:798
CASE_TYPE
#define CASE_TYPE(upb_type, c_type)
Descriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:113
layout
MessageLayout * layout
Definition: php/ext/google/protobuf/protobuf.h:800
ALLOC
#define ALLOC(class_name)
Definition: php/ext/google/protobuf/protobuf.h:1477
upb_oneofdef
Definition: php/ext/google/protobuf/upb.c:1176
UNBOX
#define UNBOX(class_name, val)
Definition: php/ext/google/protobuf/protobuf.h:233
UPB_TYPE_UINT32
@ UPB_TYPE_UINT32
Definition: php/ext/google/protobuf/upb.h:416
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
ONEOF_CASE_NONE
#define ONEOF_CASE_NONE
Definition: php/ext/google/protobuf/protobuf.h:1188
ALLOC_N
#define ALLOC_N(class_name, n)
Definition: php/ext/google/protobuf/protobuf.h:1479
upb_inttable_iter
Definition: php/ext/google/protobuf/upb.h:3088
offset
GLintptr offset
Definition: glcorearb.h:2944
native_slot_init
void native_slot_init(upb_fieldtype_t type, void *memory, CACHED_VALUE *cache)
Definition: php/ext/google/protobuf/storage.c:276
MessageLayout::fields
MessageField * fields
Definition: php/ext/google/protobuf/protobuf.h:929
upb_fielddef_containingoneof
const upb_oneofdef * upb_fielddef_containingoneof(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1619
upb_fielddef_ismap
bool upb_fielddef_ismap(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1704
upb_msg_oneof_begin
void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1846
is_map_field
bool is_map_field(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:526
PHP_PROTO_HASH_OF
#define PHP_PROTO_HASH_OF(array)
Definition: php/ext/google/protobuf/protobuf.h:84
PHP_PROTO_ZVAL_STRINGL
#define PHP_PROTO_ZVAL_STRINGL(zval_ptr, s, len, copy)
Definition: php/ext/google/protobuf/protobuf.h:71
UPB_TYPE_DOUBLE
@ UPB_TYPE_DOUBLE
Definition: php/ext/google/protobuf/upb.h:423
UPB_TYPE_STRING
@ UPB_TYPE_STRING
Definition: php/ext/google/protobuf/upb.h:419
upb_oneofdef_name
const char * upb_oneofdef_name(const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1882
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
size
#define size
Definition: glcorearb.h:2944
upb_fielddef_name
const char * upb_fielddef_name(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1568
php_proto_zval_ptr_dtor
php_proto_zval_ptr_dtor(intern->array)
upb_fielddef
Definition: php/ext/google/protobuf/upb.c:1118
EnumDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:137
OBJ_PROP
#define OBJ_PROP(OBJECT, OFFSET)
Definition: php/ext/google/protobuf/protobuf.h:207
upb_msg_oneof_done
bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1863
UPB_TYPE_MESSAGE
@ UPB_TYPE_MESSAGE
Definition: php/ext/google/protobuf/upb.h:421
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
UPB_TYPE_ENUM
@ UPB_TYPE_ENUM
Definition: php/ext/google/protobuf/upb.h:417
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
Map::table
upb_strtable table
Definition: ruby/ext/google/protobuf_c/protobuf.h:447
tryget_map_entry_msgdef
const upb_msgdef * tryget_map_entry_msgdef(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:510
native_slot_get_default
void native_slot_get_default(upb_fieldtype_t type, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:453
check_repeated_field
void check_repeated_field(const zend_class_entry *klass, PHP_PROTO_LONG type, zval *val, zval *return_value)
Definition: type_check.c:451
UPB_TYPE_UINT64
@ UPB_TYPE_UINT64
Definition: php/ext/google/protobuf/upb.h:425
repeated_field_type
zend_class_entry * repeated_field_type
Definition: array.c:91
protobuf.h
i
int i
Definition: gmock-matchers_test.cc:764
layout_get_oneof_case
const char * layout_get_oneof_case(MessageLayout *layout, const void *storage, const upb_oneofdef *oneof TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:1137
upb_oneof_next
void upb_oneof_next(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1915
map_field_key
const upb_fielddef * map_field_key(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:530
upb_msg_iter_field
upb_fielddef * upb_msg_iter_field(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1833
upb_fielddef_type
upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1505
map_next
void map_next(MapIter *iter)
Definition: php/ext/google/protobuf/map.c:500
UPB_DESCRIPTOR_TYPE_MESSAGE
@ UPB_DESCRIPTOR_TYPE_MESSAGE
Definition: php/ext/google/protobuf/upb.h:447
type
GLenum type
Definition: glcorearb.h:2695
is_structurally_valid_utf8
bool is_structurally_valid_utf8(const char *buf, int len)
Definition: utf8.c:50
upb_oneof_iter_field
upb_fielddef * upb_oneof_iter_field(const upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1923
upb_oneof_begin
void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1911
ZVAL_OBJ
#define ZVAL_OBJ(zval_ptr, call_create)
Definition: php/ext/google/protobuf/protobuf.h:229
native_slot_is_default
static bool native_slot_is_default(upb_fieldtype_t type, const void *memory)
Definition: php/ext/google/protobuf/storage.c:60
utf8.h
upb_fielddef_msgsubdef
const upb_msgdef * upb_fielddef_msgsubdef(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1677
upb_msg_field_next
void upb_msg_field_next(upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1827
native_slot_get_by_map_value
void native_slot_get_by_map_value(upb_fieldtype_t type, const void *memory, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:433
MessageLayout::msgdef
const upb_msgdef * msgdef
Definition: php/ext/google/protobuf/protobuf.h:928
repeated_field_push_native
void repeated_field_push_native(RepeatedField *intern, void *value)
Definition: array.c:252
UPB_LABEL_REPEATED
@ UPB_LABEL_REPEATED
Definition: php/ext/google/protobuf/upb.h:432
get_def_obj
PHP_PROTO_HASHTABLE_VALUE get_def_obj(const void *def)
Definition: php/ext/google/protobuf/protobuf.c:112
upb_msgdef_numfields
int upb_msgdef_numfields(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1799
native_slot_set_by_map
bool native_slot_set_by_map(upb_fieldtype_t type, const zend_class_entry *klass, void *memory, zval *value TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:219
align_up_to
static size_t align_up_to(size_t offset, size_t granularity)
Definition: php/ext/google/protobuf/storage.c:570
map_begin
void map_begin(zval *map_php, MapIter *iter TSRMLS_DC)
Definition: php/ext/google/protobuf/map.c:495
NATIVE_SLOT_MAX_SIZE
#define NATIVE_SLOT_MAX_SIZE
Definition: php/ext/google/protobuf/protobuf.h:1021
size
GLsizeiptr size
Definition: glcorearb.h:2943
native_slot_get_by_array
void native_slot_get_by_array(upb_fieldtype_t type, const void *memory, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:388
upb_msg_field_done
bool upb_msg_field_done(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1829
upb_msgdef_itof
const upb_fielddef * upb_msgdef_itof(const upb_msgdef *m, uint32_t i)
Definition: php/ext/google/protobuf/upb.c:1757
MessageField::cache_index
int cache_index
Definition: php/ext/google/protobuf/protobuf.h:922
MESSAGE_FIELD_NO_CASE
#define MESSAGE_FIELD_NO_CASE
Definition: php/ext/google/protobuf/protobuf.h:918
CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR
#define CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(zval_ptr, class_type)
Definition: php/ext/google/protobuf/protobuf.h:199
UPB_TYPE_BYTES
@ UPB_TYPE_BYTES
Definition: php/ext/google/protobuf/upb.h:420
native_slot_get
void native_slot_get(upb_fieldtype_t type, const void *memory, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:311
upb_fielddef_number
uint32_t upb_fielddef_number(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1552
upb_fielddef_label
upb_label_t upb_fielddef_label(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1548
UPB_TYPE_INT64
@ UPB_TYPE_INT64
Definition: php/ext/google/protobuf/upb.h:424
upb_oneof_done
bool upb_oneof_done(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1919
MessageLayout
Definition: php/ext/google/protobuf/protobuf.h:927
map_entry_value
const upb_fielddef * map_entry_value(const upb_msgdef *msgdef)
Definition: php/ext/google/protobuf/storage.c:546
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
slot_property_cache
static int slot_property_cache(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:581
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
MAP_KEY_FIELD
#define MAP_KEY_FIELD
Definition: php/ext/google/protobuf/protobuf.h:1093
native_slot_set
bool native_slot_set(upb_fieldtype_t type, const zend_class_entry *klass, void *memory, zval *value PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:87
php_proto_zend_hash_index_find_zval
#define php_proto_zend_hash_index_find_zval(ht, h, pDest)
Definition: php/ext/google/protobuf/protobuf.h:102
header
const std::string header
Descriptor::klass
VALUE klass
Definition: ruby/ext/google/protobuf_c/protobuf.h:116
upb_strtable_iter
Definition: php/ext/google/protobuf/upb.h:3061
native_slot_get_by_map_key
void native_slot_get_by_map_key(upb_fieldtype_t type, const void *memory, int length, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:420
upb_msg_oneof_next
void upb_msg_oneof_next(upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1855
Map::value_type
upb_fieldtype_t value_type
Definition: ruby/ext/google/protobuf_c/protobuf.h:444
UPB_TYPE_BOOL
@ UPB_TYPE_BOOL
Definition: php/ext/google/protobuf/upb.h:412
upb_strtable_count
UPB_INLINE size_t upb_strtable_count(const upb_strtable *t)
Definition: php/ext/google/protobuf/upb.h:2894
protobuf_convert_to_string
bool protobuf_convert_to_string(zval *from)
Definition: type_check.c:375
layout_init
void layout_init(MessageLayout *layout, void *storage, zend_object *object PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:755
map_entry_msgdef
const upb_msgdef * map_entry_msgdef(const upb_fielddef *field)
Definition: php/ext/google/protobuf/storage.c:520
MAP_VALUE_FIELD
#define MAP_VALUE_FIELD
Definition: php/ext/google/protobuf/protobuf.h:1094
MessageField::case_offset
size_t case_offset
Definition: php/ext/google/protobuf/protobuf.h:924
map_field_type
zend_class_entry * map_field_type
Definition: php/ext/google/protobuf/map.c:159
upb_fielddef_index
uint32_t upb_fielddef_index(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1544
klass
zend_class_entry * klass
Definition: php/ext/google/protobuf/protobuf.h:801
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF
#define PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(value)
Definition: php/ext/google/protobuf/protobuf.h:202
upb_msgdef
Definition: php/ext/google/protobuf/upb.c:1146
upb_fieldtype_t
upb_fieldtype_t
Definition: php/ext/google/protobuf/upb.h:410
upb_msgdef_ntof
const upb_fielddef * upb_msgdef_ntof(const upb_msgdef *m, const char *name, size_t len)
Definition: php/ext/google/protobuf/upb.c:1763
RepeatedField
Definition: ruby/ext/google/protobuf_c/protobuf.h:395


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:59