ruby_memprofiler_pprof 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +7 -0
  2. data/ext/ruby_memprofiler_pprof/backtrace.c +429 -0
  3. data/ext/ruby_memprofiler_pprof/collector.c +1055 -0
  4. data/ext/ruby_memprofiler_pprof/compat.c +182 -0
  5. data/ext/ruby_memprofiler_pprof/extconf.rb +72 -0
  6. data/ext/ruby_memprofiler_pprof/pprof.upb.c +170 -0
  7. data/ext/ruby_memprofiler_pprof/pprof.upb.h +848 -0
  8. data/ext/ruby_memprofiler_pprof/pprof_out.c +285 -0
  9. data/ext/ruby_memprofiler_pprof/ruby_memprofiler_pprof.c +11 -0
  10. data/ext/ruby_memprofiler_pprof/ruby_memprofiler_pprof.h +301 -0
  11. data/ext/ruby_memprofiler_pprof/strtab.c +391 -0
  12. data/ext/ruby_memprofiler_pprof/vendor/upb/BUILD +719 -0
  13. data/ext/ruby_memprofiler_pprof/vendor/upb/CONTRIBUTING.md +37 -0
  14. data/ext/ruby_memprofiler_pprof/vendor/upb/DESIGN.md +201 -0
  15. data/ext/ruby_memprofiler_pprof/vendor/upb/LICENSE +26 -0
  16. data/ext/ruby_memprofiler_pprof/vendor/upb/README.md +78 -0
  17. data/ext/ruby_memprofiler_pprof/vendor/upb/WORKSPACE +58 -0
  18. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/BUILD +53 -0
  19. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/amalgamate.py +129 -0
  20. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/build_defs.bzl +160 -0
  21. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/lua.BUILD +127 -0
  22. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/protobuf.patch +54 -0
  23. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/py_proto_library.bzl +137 -0
  24. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/python_downloads.bzl +84 -0
  25. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/system_python.bzl +101 -0
  26. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/upb_proto_library.bzl +388 -0
  27. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/workspace_deps.bzl +89 -0
  28. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/BUILD +252 -0
  29. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/BUILD.googleapis +54 -0
  30. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/benchmark.cc +333 -0
  31. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/build_defs.bzl +88 -0
  32. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/compare.py +118 -0
  33. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/descriptor.proto +888 -0
  34. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/descriptor_sv.proto +890 -0
  35. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/empty.proto +6 -0
  36. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_protobuf_binary_cc.py +64 -0
  37. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_synthetic_protos.py +118 -0
  38. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_upb_binary_c.py +65 -0
  39. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/BUILD.bazel +102 -0
  40. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/README.md +23 -0
  41. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/build_defs.bzl +73 -0
  42. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/make_cmakelists.py +340 -0
  43. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/staleness_test.py +57 -0
  44. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/staleness_test_lib.py +186 -0
  45. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/render.py +43 -0
  46. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/style-guide.md +65 -0
  47. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/vs-cpp-protos.md +255 -0
  48. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/wrapping-upb.md +444 -0
  49. data/ext/ruby_memprofiler_pprof/vendor/upb/python/BUILD +216 -0
  50. data/ext/ruby_memprofiler_pprof/vendor/upb/python/convert.c +394 -0
  51. data/ext/ruby_memprofiler_pprof/vendor/upb/python/convert.h +63 -0
  52. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor.c +1694 -0
  53. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor.h +80 -0
  54. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_containers.c +704 -0
  55. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_containers.h +114 -0
  56. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_pool.c +650 -0
  57. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_pool.h +48 -0
  58. data/ext/ruby_memprofiler_pprof/vendor/upb/python/dist/BUILD.bazel +193 -0
  59. data/ext/ruby_memprofiler_pprof/vendor/upb/python/dist/dist.bzl +190 -0
  60. data/ext/ruby_memprofiler_pprof/vendor/upb/python/extension_dict.c +247 -0
  61. data/ext/ruby_memprofiler_pprof/vendor/upb/python/extension_dict.h +39 -0
  62. data/ext/ruby_memprofiler_pprof/vendor/upb/python/map.c +522 -0
  63. data/ext/ruby_memprofiler_pprof/vendor/upb/python/map.h +66 -0
  64. data/ext/ruby_memprofiler_pprof/vendor/upb/python/message.c +1909 -0
  65. data/ext/ruby_memprofiler_pprof/vendor/upb/python/message.h +101 -0
  66. data/ext/ruby_memprofiler_pprof/vendor/upb/python/minimal_test.py +183 -0
  67. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/BUILD +70 -0
  68. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/README.md +11 -0
  69. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_database_test_wrapper.py +30 -0
  70. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_pool_test_wrapper.py +45 -0
  71. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_test_wrapper.py +46 -0
  72. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/generator_test_wrapper.py +30 -0
  73. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/json_format_test_wrapper.py +30 -0
  74. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/keywords_test_wrapper.py +30 -0
  75. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/message_factory_test_wrapper.py +37 -0
  76. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/message_test_wrapper.py +52 -0
  77. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/proto_builder_test_wrapper.py +32 -0
  78. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/pyproto_test_wrapper.bzl +36 -0
  79. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/reflection_test_wrapper.py +45 -0
  80. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/service_reflection_test_wrapper.py +30 -0
  81. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/symbol_database_test_wrapper.py +30 -0
  82. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/text_encoding_test_wrapper.py +30 -0
  83. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/text_format_test_wrapper.py +30 -0
  84. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/unknown_fields_test_wrapper.py +30 -0
  85. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/well_known_types_test_wrapper.py +36 -0
  86. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/wire_format_test_wrapper.py +30 -0
  87. data/ext/ruby_memprofiler_pprof/vendor/upb/python/protobuf.c +350 -0
  88. data/ext/ruby_memprofiler_pprof/vendor/upb/python/protobuf.h +230 -0
  89. data/ext/ruby_memprofiler_pprof/vendor/upb/python/py_extension.bzl +55 -0
  90. data/ext/ruby_memprofiler_pprof/vendor/upb/python/python_api.h +61 -0
  91. data/ext/ruby_memprofiler_pprof/vendor/upb/python/repeated.c +828 -0
  92. data/ext/ruby_memprofiler_pprof/vendor/upb/python/repeated.h +69 -0
  93. data/ext/ruby_memprofiler_pprof/vendor/upb/python/unknown_fields.c +404 -0
  94. data/ext/ruby_memprofiler_pprof/vendor/upb/python/unknown_fields.h +39 -0
  95. data/ext/ruby_memprofiler_pprof/vendor/upb/python/version_script.lds +6 -0
  96. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/LICENSE +32 -0
  97. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/README.google +9 -0
  98. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/console.lua +156 -0
  99. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/lunit.lua +725 -0
  100. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/BUILD +19 -0
  101. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/LICENSE +21 -0
  102. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/naive.c +92 -0
  103. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/range2-neon.c +157 -0
  104. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/range2-sse.c +170 -0
  105. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/utf8_range.h +9 -0
  106. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/BUILD.bazel +129 -0
  107. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/README.md +8 -0
  108. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/def.c +939 -0
  109. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/lua_proto_library.bzl +138 -0
  110. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/main.c +83 -0
  111. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/msg.c +1118 -0
  112. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/test.proto +69 -0
  113. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/test_upb.lua +846 -0
  114. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.c +258 -0
  115. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.h +132 -0
  116. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.lua +58 -0
  117. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upbc.cc +134 -0
  118. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/collections.c +192 -0
  119. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/collections.h +174 -0
  120. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/conformance_upb.c +346 -0
  121. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/conformance_upb_failures.txt +1 -0
  122. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode.c +1221 -0
  123. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode.h +94 -0
  124. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_fast.c +1055 -0
  125. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_fast.h +153 -0
  126. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_internal.h +211 -0
  127. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.c +3262 -0
  128. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.h +414 -0
  129. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.hpp +438 -0
  130. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/empty.proto +1 -0
  131. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/encode.c +604 -0
  132. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/encode.h +71 -0
  133. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/fuzz/BUILD +13 -0
  134. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/fuzz/file_descriptor_parsenew_fuzzer.cc +43 -0
  135. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_decode.c +1509 -0
  136. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_decode.h +47 -0
  137. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_encode.c +776 -0
  138. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_encode.h +62 -0
  139. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.c +1147 -0
  140. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.h +189 -0
  141. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.hpp +112 -0
  142. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors.c +363 -0
  143. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors.h +263 -0
  144. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors_internal.h +59 -0
  145. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors_test.cc +425 -0
  146. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_test.cc +230 -0
  147. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg.c +428 -0
  148. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg.h +114 -0
  149. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_internal.h +836 -0
  150. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_test.cc +491 -0
  151. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_test.proto +195 -0
  152. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/port_def.inc +261 -0
  153. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/port_undef.inc +62 -0
  154. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.c +323 -0
  155. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.h +109 -0
  156. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.hpp +37 -0
  157. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/table.c +926 -0
  158. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/table_internal.h +385 -0
  159. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test.proto +74 -0
  160. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_cpp.cc +186 -0
  161. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_cpp.proto +12 -0
  162. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_generated_code.cc +977 -0
  163. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_table.cc +580 -0
  164. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/text_encode.c +472 -0
  165. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/text_encode.h +64 -0
  166. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.c +362 -0
  167. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.h +378 -0
  168. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.hpp +115 -0
  169. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb_internal.h +68 -0
  170. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/BUILD +121 -0
  171. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/README.md +7 -0
  172. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare.c +300 -0
  173. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare.h +66 -0
  174. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare_test.cc +236 -0
  175. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto.c +572 -0
  176. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto.h +62 -0
  177. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_public_import_test.proto +32 -0
  178. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_regular_import_test.proto +36 -0
  179. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_test.cc +143 -0
  180. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_test.proto +119 -0
  181. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_weak_import_test.proto +28 -0
  182. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_wweak_import_test.proto +28 -0
  183. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields.c +311 -0
  184. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields.h +94 -0
  185. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields_test.cc +202 -0
  186. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields_test.proto +48 -0
  187. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/BUILD +78 -0
  188. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/common.cc +77 -0
  189. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/common.h +112 -0
  190. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/protoc-gen-upb.cc +1997 -0
  191. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/protoc-gen-upbdefs.cc +193 -0
  192. data/lib/ruby_memprofiler_pprof/atfork.rb +77 -0
  193. data/lib/ruby_memprofiler_pprof/block_flusher.rb +61 -0
  194. data/lib/ruby_memprofiler_pprof/file_flusher.rb +45 -0
  195. data/lib/ruby_memprofiler_pprof/profile_app.rb +30 -0
  196. data/lib/ruby_memprofiler_pprof/profile_data.rb +18 -0
  197. data/lib/ruby_memprofiler_pprof/version.rb +5 -0
  198. data/lib/ruby_memprofiler_pprof.rb +8 -0
  199. data/libexec/ruby_memprofiler_pprof_profile +16 -0
  200. metadata +257 -0
@@ -0,0 +1,1221 @@
1
+ /*
2
+ * Copyright (c) 2009-2021, Google LLC
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ * * Redistributions of source code must retain the above copyright
8
+ * notice, this list of conditions and the following disclaimer.
9
+ * * Redistributions in binary form must reproduce the above copyright
10
+ * notice, this list of conditions and the following disclaimer in the
11
+ * documentation and/or other materials provided with the distribution.
12
+ * * Neither the name of Google LLC nor the
13
+ * names of its contributors may be used to endorse or promote products
14
+ * derived from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #include "upb/decode.h"
29
+
30
+ #include <setjmp.h>
31
+ #include <string.h>
32
+
33
+ #include "upb/decode_internal.h"
34
+ #include "upb/upb.h"
35
+ #include "upb/upb_internal.h"
36
+
37
+ /* Must be last. */
38
+ #include "upb/port_def.inc"
39
+
40
+ /* Maps descriptor type -> elem_size_lg2. */
41
+ static const uint8_t desctype_to_elem_size_lg2[] = {
42
+ -1, /* invalid descriptor type */
43
+ 3, /* DOUBLE */
44
+ 2, /* FLOAT */
45
+ 3, /* INT64 */
46
+ 3, /* UINT64 */
47
+ 2, /* INT32 */
48
+ 3, /* FIXED64 */
49
+ 2, /* FIXED32 */
50
+ 0, /* BOOL */
51
+ UPB_SIZE(3, 4), /* STRING */
52
+ UPB_SIZE(2, 3), /* GROUP */
53
+ UPB_SIZE(2, 3), /* MESSAGE */
54
+ UPB_SIZE(3, 4), /* BYTES */
55
+ 2, /* UINT32 */
56
+ 2, /* ENUM */
57
+ 2, /* SFIXED32 */
58
+ 3, /* SFIXED64 */
59
+ 2, /* SINT32 */
60
+ 3, /* SINT64 */
61
+ };
62
+
63
+ /* Maps descriptor type -> upb map size. */
64
+ static const uint8_t desctype_to_mapsize[] = {
65
+ -1, /* invalid descriptor type */
66
+ 8, /* DOUBLE */
67
+ 4, /* FLOAT */
68
+ 8, /* INT64 */
69
+ 8, /* UINT64 */
70
+ 4, /* INT32 */
71
+ 8, /* FIXED64 */
72
+ 4, /* FIXED32 */
73
+ 1, /* BOOL */
74
+ UPB_MAPTYPE_STRING, /* STRING */
75
+ sizeof(void*), /* GROUP */
76
+ sizeof(void*), /* MESSAGE */
77
+ UPB_MAPTYPE_STRING, /* BYTES */
78
+ 4, /* UINT32 */
79
+ 4, /* ENUM */
80
+ 4, /* SFIXED32 */
81
+ 8, /* SFIXED64 */
82
+ 4, /* SINT32 */
83
+ 8, /* SINT64 */
84
+ };
85
+
86
+ static const unsigned FIXED32_OK_MASK = (1 << kUpb_FieldType_Float) |
87
+ (1 << kUpb_FieldType_Fixed32) |
88
+ (1 << kUpb_FieldType_SFixed32);
89
+
90
+ static const unsigned FIXED64_OK_MASK = (1 << kUpb_FieldType_Double) |
91
+ (1 << kUpb_FieldType_Fixed64) |
92
+ (1 << kUpb_FieldType_SFixed64);
93
+
94
+ /* Three fake field types for MessageSet. */
95
+ #define TYPE_MSGSET_ITEM 19
96
+ #define TYPE_COUNT 19
97
+
98
+ /* Op: an action to be performed for a wire-type/field-type combination. */
99
+ #define OP_UNKNOWN -1 /* Unknown field. */
100
+ #define OP_MSGSET_ITEM -2
101
+ #define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */
102
+ #define OP_ENUM 1
103
+ #define OP_STRING 4
104
+ #define OP_BYTES 5
105
+ #define OP_SUBMSG 6
106
+ /* Scalar fields use only ops above. Repeated fields can use any op. */
107
+ #define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */
108
+ #define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */
109
+ #define OP_PACKED_ENUM 13
110
+
111
+ static const int8_t varint_ops[] = {
112
+ OP_UNKNOWN, /* field not found */
113
+ OP_UNKNOWN, /* DOUBLE */
114
+ OP_UNKNOWN, /* FLOAT */
115
+ OP_SCALAR_LG2(3), /* INT64 */
116
+ OP_SCALAR_LG2(3), /* UINT64 */
117
+ OP_SCALAR_LG2(2), /* INT32 */
118
+ OP_UNKNOWN, /* FIXED64 */
119
+ OP_UNKNOWN, /* FIXED32 */
120
+ OP_SCALAR_LG2(0), /* BOOL */
121
+ OP_UNKNOWN, /* STRING */
122
+ OP_UNKNOWN, /* GROUP */
123
+ OP_UNKNOWN, /* MESSAGE */
124
+ OP_UNKNOWN, /* BYTES */
125
+ OP_SCALAR_LG2(2), /* UINT32 */
126
+ OP_ENUM, /* ENUM */
127
+ OP_UNKNOWN, /* SFIXED32 */
128
+ OP_UNKNOWN, /* SFIXED64 */
129
+ OP_SCALAR_LG2(2), /* SINT32 */
130
+ OP_SCALAR_LG2(3), /* SINT64 */
131
+ OP_UNKNOWN, /* MSGSET_ITEM */
132
+ };
133
+
134
+ static const int8_t delim_ops[] = {
135
+ /* For non-repeated field type. */
136
+ OP_UNKNOWN, /* field not found */
137
+ OP_UNKNOWN, /* DOUBLE */
138
+ OP_UNKNOWN, /* FLOAT */
139
+ OP_UNKNOWN, /* INT64 */
140
+ OP_UNKNOWN, /* UINT64 */
141
+ OP_UNKNOWN, /* INT32 */
142
+ OP_UNKNOWN, /* FIXED64 */
143
+ OP_UNKNOWN, /* FIXED32 */
144
+ OP_UNKNOWN, /* BOOL */
145
+ OP_STRING, /* STRING */
146
+ OP_UNKNOWN, /* GROUP */
147
+ OP_SUBMSG, /* MESSAGE */
148
+ OP_BYTES, /* BYTES */
149
+ OP_UNKNOWN, /* UINT32 */
150
+ OP_UNKNOWN, /* ENUM */
151
+ OP_UNKNOWN, /* SFIXED32 */
152
+ OP_UNKNOWN, /* SFIXED64 */
153
+ OP_UNKNOWN, /* SINT32 */
154
+ OP_UNKNOWN, /* SINT64 */
155
+ OP_UNKNOWN, /* MSGSET_ITEM */
156
+ /* For repeated field type. */
157
+ OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */
158
+ OP_FIXPCK_LG2(2), /* REPEATED FLOAT */
159
+ OP_VARPCK_LG2(3), /* REPEATED INT64 */
160
+ OP_VARPCK_LG2(3), /* REPEATED UINT64 */
161
+ OP_VARPCK_LG2(2), /* REPEATED INT32 */
162
+ OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */
163
+ OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */
164
+ OP_VARPCK_LG2(0), /* REPEATED BOOL */
165
+ OP_STRING, /* REPEATED STRING */
166
+ OP_SUBMSG, /* REPEATED GROUP */
167
+ OP_SUBMSG, /* REPEATED MESSAGE */
168
+ OP_BYTES, /* REPEATED BYTES */
169
+ OP_VARPCK_LG2(2), /* REPEATED UINT32 */
170
+ OP_PACKED_ENUM, /* REPEATED ENUM */
171
+ OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */
172
+ OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */
173
+ OP_VARPCK_LG2(2), /* REPEATED SINT32 */
174
+ OP_VARPCK_LG2(3), /* REPEATED SINT64 */
175
+ /* Omitting MSGSET_*, because we never emit a repeated msgset type */
176
+ };
177
+
178
+ typedef union {
179
+ bool bool_val;
180
+ uint32_t uint32_val;
181
+ uint64_t uint64_val;
182
+ uint32_t size;
183
+ } wireval;
184
+
185
+ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
186
+ const upb_MiniTable* layout);
187
+
188
+ UPB_NORETURN static void* decode_err(upb_Decoder* d, upb_DecodeStatus status) {
189
+ assert(status != kUpb_DecodeStatus_Ok);
190
+ UPB_LONGJMP(d->err, status);
191
+ }
192
+
193
+ const char* fastdecode_err(upb_Decoder* d, int status) {
194
+ assert(status != kUpb_DecodeStatus_Ok);
195
+ UPB_LONGJMP(d->err, status);
196
+ return NULL;
197
+ }
198
+ static void decode_verifyutf8(upb_Decoder* d, const char* buf, int len) {
199
+ if (!decode_verifyutf8_inl(buf, len))
200
+ decode_err(d, kUpb_DecodeStatus_BadUtf8);
201
+ }
202
+
203
+ static bool decode_reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {
204
+ bool need_realloc = arr->size - arr->len < elem;
205
+ if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) {
206
+ decode_err(d, kUpb_DecodeStatus_OutOfMemory);
207
+ }
208
+ return need_realloc;
209
+ }
210
+
211
+ typedef struct {
212
+ const char* ptr;
213
+ uint64_t val;
214
+ } decode_vret;
215
+
216
+ UPB_NOINLINE
217
+ static decode_vret decode_longvarint64(const char* ptr, uint64_t val) {
218
+ decode_vret ret = {NULL, 0};
219
+ uint64_t byte;
220
+ int i;
221
+ for (i = 1; i < 10; i++) {
222
+ byte = (uint8_t)ptr[i];
223
+ val += (byte - 1) << (i * 7);
224
+ if (!(byte & 0x80)) {
225
+ ret.ptr = ptr + i + 1;
226
+ ret.val = val;
227
+ return ret;
228
+ }
229
+ }
230
+ return ret;
231
+ }
232
+
233
+ UPB_FORCEINLINE
234
+ static const char* decode_varint64(upb_Decoder* d, const char* ptr,
235
+ uint64_t* val) {
236
+ uint64_t byte = (uint8_t)*ptr;
237
+ if (UPB_LIKELY((byte & 0x80) == 0)) {
238
+ *val = byte;
239
+ return ptr + 1;
240
+ } else {
241
+ decode_vret res = decode_longvarint64(ptr, byte);
242
+ if (!res.ptr) return decode_err(d, kUpb_DecodeStatus_Malformed);
243
+ *val = res.val;
244
+ return res.ptr;
245
+ }
246
+ }
247
+
248
+ UPB_FORCEINLINE
249
+ static const char* decode_tag(upb_Decoder* d, const char* ptr, uint32_t* val) {
250
+ uint64_t byte = (uint8_t)*ptr;
251
+ if (UPB_LIKELY((byte & 0x80) == 0)) {
252
+ *val = byte;
253
+ return ptr + 1;
254
+ } else {
255
+ const char* start = ptr;
256
+ decode_vret res = decode_longvarint64(ptr, byte);
257
+ if (!res.ptr || res.ptr - start > 5 || res.val > UINT32_MAX) {
258
+ return decode_err(d, kUpb_DecodeStatus_Malformed);
259
+ }
260
+ *val = res.val;
261
+ return res.ptr;
262
+ }
263
+ }
264
+
265
+ UPB_FORCEINLINE
266
+ static const char* upb_Decoder_DecodeSize(upb_Decoder* d, const char* ptr,
267
+ uint32_t* size) {
268
+ uint64_t size64;
269
+ ptr = decode_varint64(d, ptr, &size64);
270
+ if (size64 >= INT32_MAX || ptr - d->end + (int)size64 > d->limit) {
271
+ decode_err(d, kUpb_DecodeStatus_Malformed);
272
+ }
273
+ *size = size64;
274
+ return ptr;
275
+ }
276
+
277
+ static void decode_munge_int32(wireval* val) {
278
+ if (!_upb_IsLittleEndian()) {
279
+ /* The next stage will memcpy(dst, &val, 4) */
280
+ val->uint32_val = val->uint64_val;
281
+ }
282
+ }
283
+
284
+ static void decode_munge(int type, wireval* val) {
285
+ switch (type) {
286
+ case kUpb_FieldType_Bool:
287
+ val->bool_val = val->uint64_val != 0;
288
+ break;
289
+ case kUpb_FieldType_SInt32: {
290
+ uint32_t n = val->uint64_val;
291
+ val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1);
292
+ break;
293
+ }
294
+ case kUpb_FieldType_SInt64: {
295
+ uint64_t n = val->uint64_val;
296
+ val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1);
297
+ break;
298
+ }
299
+ case kUpb_FieldType_Int32:
300
+ case kUpb_FieldType_UInt32:
301
+ case kUpb_FieldType_Enum:
302
+ decode_munge_int32(val);
303
+ break;
304
+ }
305
+ }
306
+
307
+ static upb_Message* decode_newsubmsg(upb_Decoder* d,
308
+ const upb_MiniTable_Sub* subs,
309
+ const upb_MiniTable_Field* field) {
310
+ const upb_MiniTable* subl = subs[field->submsg_index].submsg;
311
+ upb_Message* msg = _upb_Message_New_inl(subl, &d->arena);
312
+ if (!msg) decode_err(d, kUpb_DecodeStatus_OutOfMemory);
313
+ return msg;
314
+ }
315
+
316
+ UPB_NOINLINE
317
+ const char* decode_isdonefallback(upb_Decoder* d, const char* ptr,
318
+ int overrun) {
319
+ int status;
320
+ ptr = decode_isdonefallback_inl(d, ptr, overrun, &status);
321
+ if (ptr == NULL) {
322
+ return decode_err(d, status);
323
+ }
324
+ return ptr;
325
+ }
326
+
327
+ static const char* decode_readstr(upb_Decoder* d, const char* ptr, int size,
328
+ upb_StringView* str) {
329
+ if (d->options & kUpb_DecodeOption_AliasString) {
330
+ str->data = ptr;
331
+ } else {
332
+ char* data = upb_Arena_Malloc(&d->arena, size);
333
+ if (!data) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
334
+ memcpy(data, ptr, size);
335
+ str->data = data;
336
+ }
337
+ str->size = size;
338
+ return ptr + size;
339
+ }
340
+
341
+ UPB_FORCEINLINE
342
+ static const char* decode_tosubmsg2(upb_Decoder* d, const char* ptr,
343
+ upb_Message* submsg,
344
+ const upb_MiniTable* subl, int size) {
345
+ int saved_delta = decode_pushlimit(d, ptr, size);
346
+ if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded);
347
+ ptr = decode_msg(d, ptr, submsg, subl);
348
+ if (d->end_group != DECODE_NOGROUP)
349
+ return decode_err(d, kUpb_DecodeStatus_Malformed);
350
+ decode_poplimit(d, ptr, saved_delta);
351
+ d->depth++;
352
+ return ptr;
353
+ }
354
+
355
+ UPB_FORCEINLINE
356
+ static const char* decode_tosubmsg(upb_Decoder* d, const char* ptr,
357
+ upb_Message* submsg,
358
+ const upb_MiniTable_Sub* subs,
359
+ const upb_MiniTable_Field* field, int size) {
360
+ return decode_tosubmsg2(d, ptr, submsg, subs[field->submsg_index].submsg,
361
+ size);
362
+ }
363
+
364
+ UPB_FORCEINLINE
365
+ static const char* decode_group(upb_Decoder* d, const char* ptr,
366
+ upb_Message* submsg, const upb_MiniTable* subl,
367
+ uint32_t number) {
368
+ if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded);
369
+ if (decode_isdone(d, &ptr)) {
370
+ return decode_err(d, kUpb_DecodeStatus_Malformed);
371
+ }
372
+ ptr = decode_msg(d, ptr, submsg, subl);
373
+ if (d->end_group != number) return decode_err(d, kUpb_DecodeStatus_Malformed);
374
+ d->end_group = DECODE_NOGROUP;
375
+ d->depth++;
376
+ return ptr;
377
+ }
378
+
379
+ UPB_FORCEINLINE
380
+ static const char* decode_togroup(upb_Decoder* d, const char* ptr,
381
+ upb_Message* submsg,
382
+ const upb_MiniTable_Sub* subs,
383
+ const upb_MiniTable_Field* field) {
384
+ const upb_MiniTable* subl = subs[field->submsg_index].submsg;
385
+ return decode_group(d, ptr, submsg, subl, field->number);
386
+ }
387
+
388
+ static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) {
389
+ do {
390
+ uint8_t byte = val & 0x7fU;
391
+ val >>= 7;
392
+ if (val) byte |= 0x80U;
393
+ *(ptr++) = byte;
394
+ } while (val);
395
+ return ptr;
396
+ }
397
+
398
+ static void upb_Decode_AddUnknownVarints(upb_Decoder* d, upb_Message* msg,
399
+ uint32_t val1, uint32_t val2) {
400
+ char buf[20];
401
+ char* end = buf;
402
+ end = upb_Decoder_EncodeVarint32(val1, end);
403
+ end = upb_Decoder_EncodeVarint32(val2, end);
404
+
405
+ if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) {
406
+ decode_err(d, kUpb_DecodeStatus_OutOfMemory);
407
+ }
408
+ }
409
+
410
+ UPB_NOINLINE
411
+ static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr,
412
+ upb_Message* msg, const upb_MiniTable_Enum* e,
413
+ const upb_MiniTable_Field* field,
414
+ uint32_t v) {
415
+ // OPT: binary search long lists?
416
+ int n = e->value_count;
417
+ for (int i = 0; i < n; i++) {
418
+ if ((uint32_t)e->values[i] == v) return true;
419
+ }
420
+
421
+ // Unrecognized enum goes into unknown fields.
422
+ // For packed fields the tag could be arbitrarily far in the past, so we
423
+ // just re-encode the tag and value here.
424
+ uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint;
425
+ upb_Decode_AddUnknownVarints(d, msg, tag, v);
426
+ return false;
427
+ }
428
+
429
+ UPB_FORCEINLINE
430
+ static bool decode_checkenum(upb_Decoder* d, const char* ptr, upb_Message* msg,
431
+ const upb_MiniTable_Enum* e,
432
+ const upb_MiniTable_Field* field, wireval* val) {
433
+ uint32_t v = val->uint32_val;
434
+
435
+ if (UPB_LIKELY(v < 64) && UPB_LIKELY(((1ULL << v) & e->mask))) return true;
436
+
437
+ return decode_checkenum_slow(d, ptr, msg, e, field, v);
438
+ }
439
+
440
+ UPB_NOINLINE
441
+ static const char* decode_enum_toarray(upb_Decoder* d, const char* ptr,
442
+ upb_Message* msg, upb_Array* arr,
443
+ const upb_MiniTable_Sub* subs,
444
+ const upb_MiniTable_Field* field,
445
+ wireval* val) {
446
+ const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum;
447
+ if (!decode_checkenum(d, ptr, msg, e, field, val)) return ptr;
448
+ void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void);
449
+ arr->len++;
450
+ memcpy(mem, val, 4);
451
+ return ptr;
452
+ }
453
+
454
+ UPB_FORCEINLINE
455
+ static const char* decode_fixed_packed(upb_Decoder* d, const char* ptr,
456
+ upb_Array* arr, wireval* val,
457
+ const upb_MiniTable_Field* field,
458
+ int lg2) {
459
+ int mask = (1 << lg2) - 1;
460
+ size_t count = val->size >> lg2;
461
+ if ((val->size & mask) != 0) {
462
+ // Length isn't a round multiple of elem size.
463
+ return decode_err(d, kUpb_DecodeStatus_Malformed);
464
+ }
465
+ decode_reserve(d, arr, count);
466
+ void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
467
+ arr->len += count;
468
+ // Note: if/when the decoder supports multi-buffer input, we will need to
469
+ // handle buffer seams here.
470
+ if (_upb_IsLittleEndian()) {
471
+ memcpy(mem, ptr, val->size);
472
+ ptr += val->size;
473
+ } else {
474
+ const char* end = ptr + val->size;
475
+ char* dst = mem;
476
+ while (ptr < end) {
477
+ if (lg2 == 2) {
478
+ uint32_t val;
479
+ memcpy(&val, ptr, sizeof(val));
480
+ val = _upb_BigEndian_Swap32(val);
481
+ memcpy(dst, &val, sizeof(val));
482
+ } else {
483
+ UPB_ASSERT(lg2 == 3);
484
+ uint64_t val;
485
+ memcpy(&val, ptr, sizeof(val));
486
+ val = _upb_BigEndian_Swap64(val);
487
+ memcpy(dst, &val, sizeof(val));
488
+ }
489
+ ptr += 1 << lg2;
490
+ dst += 1 << lg2;
491
+ }
492
+ }
493
+
494
+ return ptr;
495
+ }
496
+
497
+ UPB_FORCEINLINE
498
+ static const char* decode_varint_packed(upb_Decoder* d, const char* ptr,
499
+ upb_Array* arr, wireval* val,
500
+ const upb_MiniTable_Field* field,
501
+ int lg2) {
502
+ int scale = 1 << lg2;
503
+ int saved_limit = decode_pushlimit(d, ptr, val->size);
504
+ char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
505
+ while (!decode_isdone(d, &ptr)) {
506
+ wireval elem;
507
+ ptr = decode_varint64(d, ptr, &elem.uint64_val);
508
+ decode_munge(field->descriptortype, &elem);
509
+ if (decode_reserve(d, arr, 1)) {
510
+ out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
511
+ }
512
+ arr->len++;
513
+ memcpy(out, &elem, scale);
514
+ out += scale;
515
+ }
516
+ decode_poplimit(d, ptr, saved_limit);
517
+ return ptr;
518
+ }
519
+
520
+ UPB_NOINLINE
521
+ static const char* decode_enum_packed(upb_Decoder* d, const char* ptr,
522
+ upb_Message* msg, upb_Array* arr,
523
+ const upb_MiniTable_Sub* subs,
524
+ const upb_MiniTable_Field* field,
525
+ wireval* val) {
526
+ const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum;
527
+ int saved_limit = decode_pushlimit(d, ptr, val->size);
528
+ char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void);
529
+ while (!decode_isdone(d, &ptr)) {
530
+ wireval elem;
531
+ ptr = decode_varint64(d, ptr, &elem.uint64_val);
532
+ decode_munge_int32(&elem);
533
+ if (!decode_checkenum(d, ptr, msg, e, field, &elem)) {
534
+ continue;
535
+ }
536
+ if (decode_reserve(d, arr, 1)) {
537
+ out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len * 4, void);
538
+ }
539
+ arr->len++;
540
+ memcpy(out, &elem, 4);
541
+ out += 4;
542
+ }
543
+ decode_poplimit(d, ptr, saved_limit);
544
+ return ptr;
545
+ }
546
+
547
+ static const char* decode_toarray(upb_Decoder* d, const char* ptr,
548
+ upb_Message* msg,
549
+ const upb_MiniTable_Sub* subs,
550
+ const upb_MiniTable_Field* field,
551
+ wireval* val, int op) {
552
+ upb_Array** arrp = UPB_PTR_AT(msg, field->offset, void);
553
+ upb_Array* arr = *arrp;
554
+ void* mem;
555
+
556
+ if (arr) {
557
+ decode_reserve(d, arr, 1);
558
+ } else {
559
+ size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype];
560
+ arr = _upb_Array_New(&d->arena, 4, lg2);
561
+ if (!arr) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
562
+ *arrp = arr;
563
+ }
564
+
565
+ switch (op) {
566
+ case OP_SCALAR_LG2(0):
567
+ case OP_SCALAR_LG2(2):
568
+ case OP_SCALAR_LG2(3):
569
+ /* Append scalar value. */
570
+ mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
571
+ arr->len++;
572
+ memcpy(mem, val, 1 << op);
573
+ return ptr;
574
+ case OP_STRING:
575
+ decode_verifyutf8(d, ptr, val->size);
576
+ /* Fallthrough. */
577
+ case OP_BYTES: {
578
+ /* Append bytes. */
579
+ upb_StringView* str = (upb_StringView*)_upb_array_ptr(arr) + arr->len;
580
+ arr->len++;
581
+ return decode_readstr(d, ptr, val->size, str);
582
+ }
583
+ case OP_SUBMSG: {
584
+ /* Append submessage / group. */
585
+ upb_Message* submsg = decode_newsubmsg(d, subs, field);
586
+ *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void*), upb_Message*) =
587
+ submsg;
588
+ arr->len++;
589
+ if (UPB_UNLIKELY(field->descriptortype == kUpb_FieldType_Group)) {
590
+ return decode_togroup(d, ptr, submsg, subs, field);
591
+ } else {
592
+ return decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
593
+ }
594
+ }
595
+ case OP_FIXPCK_LG2(2):
596
+ case OP_FIXPCK_LG2(3):
597
+ return decode_fixed_packed(d, ptr, arr, val, field,
598
+ op - OP_FIXPCK_LG2(0));
599
+ case OP_VARPCK_LG2(0):
600
+ case OP_VARPCK_LG2(2):
601
+ case OP_VARPCK_LG2(3):
602
+ return decode_varint_packed(d, ptr, arr, val, field,
603
+ op - OP_VARPCK_LG2(0));
604
+ case OP_ENUM:
605
+ return decode_enum_toarray(d, ptr, msg, arr, subs, field, val);
606
+ case OP_PACKED_ENUM:
607
+ return decode_enum_packed(d, ptr, msg, arr, subs, field, val);
608
+ default:
609
+ UPB_UNREACHABLE();
610
+ }
611
+ }
612
+
613
+ static const char* decode_tomap(upb_Decoder* d, const char* ptr,
614
+ upb_Message* msg, const upb_MiniTable_Sub* subs,
615
+ const upb_MiniTable_Field* field,
616
+ wireval* val) {
617
+ upb_Map** map_p = UPB_PTR_AT(msg, field->offset, upb_Map*);
618
+ upb_Map* map = *map_p;
619
+ upb_MapEntry ent;
620
+ const upb_MiniTable* entry = subs[field->submsg_index].submsg;
621
+
622
+ if (!map) {
623
+ /* Lazily create map. */
624
+ const upb_MiniTable_Field* key_field = &entry->fields[0];
625
+ const upb_MiniTable_Field* val_field = &entry->fields[1];
626
+ char key_size = desctype_to_mapsize[key_field->descriptortype];
627
+ char val_size = desctype_to_mapsize[val_field->descriptortype];
628
+ UPB_ASSERT(key_field->offset == 0);
629
+ UPB_ASSERT(val_field->offset == sizeof(upb_StringView));
630
+ map = _upb_Map_New(&d->arena, key_size, val_size);
631
+ *map_p = map;
632
+ }
633
+
634
+ /* Parse map entry. */
635
+ memset(&ent, 0, sizeof(ent));
636
+
637
+ if (entry->fields[1].descriptortype == kUpb_FieldType_Message ||
638
+ entry->fields[1].descriptortype == kUpb_FieldType_Group) {
639
+ /* Create proactively to handle the case where it doesn't appear. */
640
+ ent.v.val =
641
+ upb_value_ptr(_upb_Message_New(entry->subs[0].submsg, &d->arena));
642
+ }
643
+
644
+ const char* start = ptr;
645
+ ptr = decode_tosubmsg(d, ptr, &ent.k, subs, field, val->size);
646
+ // check if ent had any unknown fields
647
+ size_t size;
648
+ upb_Message_GetUnknown(&ent.k, &size);
649
+ if (size != 0) {
650
+ uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Delimited;
651
+ upb_Decode_AddUnknownVarints(d, msg, tag, (uint32_t)(ptr - start));
652
+ if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) {
653
+ decode_err(d, kUpb_DecodeStatus_OutOfMemory);
654
+ }
655
+ } else {
656
+ if (_upb_Map_Insert(map, &ent.k, map->key_size, &ent.v, map->val_size,
657
+ &d->arena) == _kUpb_MapInsertStatus_OutOfMemory) {
658
+ decode_err(d, kUpb_DecodeStatus_OutOfMemory);
659
+ }
660
+ }
661
+ return ptr;
662
+ }
663
+
664
+ static const char* decode_tomsg(upb_Decoder* d, const char* ptr,
665
+ upb_Message* msg, const upb_MiniTable_Sub* subs,
666
+ const upb_MiniTable_Field* field, wireval* val,
667
+ int op) {
668
+ void* mem = UPB_PTR_AT(msg, field->offset, void);
669
+ int type = field->descriptortype;
670
+
671
+ if (UPB_UNLIKELY(op == OP_ENUM) &&
672
+ !decode_checkenum(d, ptr, msg, subs[field->submsg_index].subenum, field,
673
+ val)) {
674
+ return ptr;
675
+ }
676
+
677
+ /* Set presence if necessary. */
678
+ if (field->presence > 0) {
679
+ _upb_sethas_field(msg, field);
680
+ } else if (field->presence < 0) {
681
+ /* Oneof case */
682
+ uint32_t* oneof_case = _upb_oneofcase_field(msg, field);
683
+ if (op == OP_SUBMSG && *oneof_case != field->number) {
684
+ memset(mem, 0, sizeof(void*));
685
+ }
686
+ *oneof_case = field->number;
687
+ }
688
+
689
+ /* Store into message. */
690
+ switch (op) {
691
+ case OP_SUBMSG: {
692
+ upb_Message** submsgp = mem;
693
+ upb_Message* submsg = *submsgp;
694
+ if (!submsg) {
695
+ submsg = decode_newsubmsg(d, subs, field);
696
+ *submsgp = submsg;
697
+ }
698
+ if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) {
699
+ ptr = decode_togroup(d, ptr, submsg, subs, field);
700
+ } else {
701
+ ptr = decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
702
+ }
703
+ break;
704
+ }
705
+ case OP_STRING:
706
+ decode_verifyutf8(d, ptr, val->size);
707
+ /* Fallthrough. */
708
+ case OP_BYTES:
709
+ return decode_readstr(d, ptr, val->size, mem);
710
+ case OP_SCALAR_LG2(3):
711
+ memcpy(mem, val, 8);
712
+ break;
713
+ case OP_ENUM:
714
+ case OP_SCALAR_LG2(2):
715
+ memcpy(mem, val, 4);
716
+ break;
717
+ case OP_SCALAR_LG2(0):
718
+ memcpy(mem, val, 1);
719
+ break;
720
+ default:
721
+ UPB_UNREACHABLE();
722
+ }
723
+
724
+ return ptr;
725
+ }
726
+
727
+ UPB_NOINLINE
728
+ const char* decode_checkrequired(upb_Decoder* d, const char* ptr,
729
+ const upb_Message* msg,
730
+ const upb_MiniTable* l) {
731
+ assert(l->required_count);
732
+ if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) {
733
+ return ptr;
734
+ }
735
+ uint64_t msg_head;
736
+ memcpy(&msg_head, msg, 8);
737
+ msg_head = _upb_BigEndian_Swap64(msg_head);
738
+ if (upb_MiniTable_requiredmask(l) & ~msg_head) {
739
+ d->missing_required = true;
740
+ }
741
+ return ptr;
742
+ }
743
+
744
+ UPB_FORCEINLINE
745
+ static bool decode_tryfastdispatch(upb_Decoder* d, const char** ptr,
746
+ upb_Message* msg,
747
+ const upb_MiniTable* layout) {
748
+ #if UPB_FASTTABLE
749
+ if (layout && layout->table_mask != (unsigned char)-1) {
750
+ uint16_t tag = fastdecode_loadtag(*ptr);
751
+ intptr_t table = decode_totable(layout);
752
+ *ptr = fastdecode_tagdispatch(d, *ptr, msg, table, 0, tag);
753
+ return true;
754
+ }
755
+ #endif
756
+ return false;
757
+ }
758
+
759
+ static const char* upb_Decoder_SkipField(upb_Decoder* d, const char* ptr,
760
+ uint32_t tag) {
761
+ int field_number = tag >> 3;
762
+ int wire_type = tag & 7;
763
+ switch (wire_type) {
764
+ case kUpb_WireType_Varint: {
765
+ uint64_t val;
766
+ return decode_varint64(d, ptr, &val);
767
+ }
768
+ case kUpb_WireType_64Bit:
769
+ return ptr + 8;
770
+ case kUpb_WireType_32Bit:
771
+ return ptr + 4;
772
+ case kUpb_WireType_Delimited: {
773
+ uint32_t size;
774
+ ptr = upb_Decoder_DecodeSize(d, ptr, &size);
775
+ return ptr + size;
776
+ }
777
+ case kUpb_WireType_StartGroup:
778
+ return decode_group(d, ptr, NULL, NULL, field_number);
779
+ default:
780
+ decode_err(d, kUpb_DecodeStatus_Malformed);
781
+ }
782
+ }
783
+
784
+ enum {
785
+ kStartItemTag = ((1 << 3) | kUpb_WireType_StartGroup),
786
+ kEndItemTag = ((1 << 3) | kUpb_WireType_EndGroup),
787
+ kTypeIdTag = ((2 << 3) | kUpb_WireType_Varint),
788
+ kMessageTag = ((3 << 3) | kUpb_WireType_Delimited),
789
+ };
790
+
791
+ static void upb_Decoder_AddKnownMessageSetItem(
792
+ upb_Decoder* d, upb_Message* msg, const upb_MiniTable_Extension* item_mt,
793
+ const char* data, uint32_t size) {
794
+ upb_Message_Extension* ext =
795
+ _upb_Message_GetOrCreateExtension(msg, item_mt, &d->arena);
796
+ if (UPB_UNLIKELY(!ext)) decode_err(d, kUpb_DecodeStatus_OutOfMemory);
797
+ upb_Message* submsg = decode_newsubmsg(d, &ext->ext->sub, &ext->ext->field);
798
+ upb_DecodeStatus status = upb_Decode(data, size, submsg, item_mt->sub.submsg,
799
+ d->extreg, d->options, &d->arena);
800
+ memcpy(&ext->data, &submsg, sizeof(submsg));
801
+ if (status != kUpb_DecodeStatus_Ok) decode_err(d, status);
802
+ }
803
+
804
+ static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d,
805
+ upb_Message* msg,
806
+ uint32_t type_id,
807
+ const char* message_data,
808
+ uint32_t message_size) {
809
+ char buf[60];
810
+ char* ptr = buf;
811
+ ptr = upb_Decoder_EncodeVarint32(kStartItemTag, ptr);
812
+ ptr = upb_Decoder_EncodeVarint32(kTypeIdTag, ptr);
813
+ ptr = upb_Decoder_EncodeVarint32(type_id, ptr);
814
+ ptr = upb_Decoder_EncodeVarint32(kMessageTag, ptr);
815
+ ptr = upb_Decoder_EncodeVarint32(message_size, ptr);
816
+ char* split = ptr;
817
+
818
+ ptr = upb_Decoder_EncodeVarint32(kEndItemTag, ptr);
819
+ char* end = ptr;
820
+
821
+ if (!_upb_Message_AddUnknown(msg, buf, split - buf, &d->arena) ||
822
+ !_upb_Message_AddUnknown(msg, message_data, message_size, &d->arena) ||
823
+ !_upb_Message_AddUnknown(msg, split, end - split, &d->arena)) {
824
+ decode_err(d, kUpb_DecodeStatus_OutOfMemory);
825
+ }
826
+ }
827
+
828
+ static void upb_Decoder_AddMessageSetItem(upb_Decoder* d, upb_Message* msg,
829
+ const upb_MiniTable* layout,
830
+ uint32_t type_id, const char* data,
831
+ uint32_t size) {
832
+ const upb_MiniTable_Extension* item_mt =
833
+ _upb_extreg_get(d->extreg, layout, type_id);
834
+ if (item_mt) {
835
+ upb_Decoder_AddKnownMessageSetItem(d, msg, item_mt, data, size);
836
+ } else {
837
+ upb_Decoder_AddUnknownMessageSetItem(d, msg, type_id, data, size);
838
+ }
839
+ }
840
+
841
+ static const char* upb_Decoder_DecodeMessageSetItem(
842
+ upb_Decoder* d, const char* ptr, upb_Message* msg,
843
+ const upb_MiniTable* layout) {
844
+ uint32_t type_id = 0;
845
+ upb_StringView preserved = {NULL, 0};
846
+ typedef enum {
847
+ kUpb_HaveId = 1 << 0,
848
+ kUpb_HavePayload = 1 << 1,
849
+ } StateMask;
850
+ StateMask state_mask = 0;
851
+ while (!decode_isdone(d, &ptr)) {
852
+ uint32_t tag;
853
+ ptr = decode_tag(d, ptr, &tag);
854
+ switch (tag) {
855
+ case kEndItemTag:
856
+ return ptr;
857
+ case kTypeIdTag: {
858
+ uint64_t tmp;
859
+ ptr = decode_varint64(d, ptr, &tmp);
860
+ if (state_mask & kUpb_HaveId) break; // Ignore dup.
861
+ state_mask |= kUpb_HaveId;
862
+ type_id = tmp;
863
+ if (state_mask & kUpb_HavePayload) {
864
+ upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, preserved.data,
865
+ preserved.size);
866
+ }
867
+ break;
868
+ }
869
+ case kMessageTag: {
870
+ uint32_t size;
871
+ ptr = upb_Decoder_DecodeSize(d, ptr, &size);
872
+ const char* data = ptr;
873
+ ptr += size;
874
+ if (state_mask & kUpb_HavePayload) break; // Ignore dup.
875
+ state_mask |= kUpb_HavePayload;
876
+ if (state_mask & kUpb_HaveId) {
877
+ upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, data, size);
878
+ } else {
879
+ // Out of order, we must preserve the payload.
880
+ preserved.data = data;
881
+ preserved.size = size;
882
+ }
883
+ break;
884
+ }
885
+ default:
886
+ // We do not preserve unexpected fields inside a message set item.
887
+ ptr = upb_Decoder_SkipField(d, ptr, tag);
888
+ break;
889
+ }
890
+ }
891
+ decode_err(d, kUpb_DecodeStatus_Malformed);
892
+ }
893
+
894
+ static const upb_MiniTable_Field* decode_findfield(upb_Decoder* d,
895
+ const upb_MiniTable* l,
896
+ uint32_t field_number,
897
+ int* last_field_index) {
898
+ static upb_MiniTable_Field none = {0, 0, 0, 0, 0, 0};
899
+ if (l == NULL) return &none;
900
+
901
+ size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
902
+ if (idx < l->dense_below) {
903
+ /* Fastest case: index into dense fields. */
904
+ goto found;
905
+ }
906
+
907
+ if (l->dense_below < l->field_count) {
908
+ /* Linear search non-dense fields. Resume scanning from last_field_index
909
+ * since fields are usually in order. */
910
+ int last = *last_field_index;
911
+ for (idx = last; idx < l->field_count; idx++) {
912
+ if (l->fields[idx].number == field_number) {
913
+ goto found;
914
+ }
915
+ }
916
+
917
+ for (idx = l->dense_below; idx < last; idx++) {
918
+ if (l->fields[idx].number == field_number) {
919
+ goto found;
920
+ }
921
+ }
922
+ }
923
+
924
+ if (d->extreg) {
925
+ switch (l->ext) {
926
+ case kUpb_ExtMode_Extendable: {
927
+ const upb_MiniTable_Extension* ext =
928
+ _upb_extreg_get(d->extreg, l, field_number);
929
+ if (ext) return &ext->field;
930
+ break;
931
+ }
932
+ case kUpb_ExtMode_IsMessageSet:
933
+ if (field_number == _UPB_MSGSET_ITEM) {
934
+ static upb_MiniTable_Field item = {0, 0, 0, 0, TYPE_MSGSET_ITEM, 0};
935
+ return &item;
936
+ }
937
+ break;
938
+ }
939
+ }
940
+
941
+ return &none; /* Unknown field. */
942
+
943
+ found:
944
+ UPB_ASSERT(l->fields[idx].number == field_number);
945
+ *last_field_index = idx;
946
+ return &l->fields[idx];
947
+ }
948
+
949
+ UPB_FORCEINLINE
950
+ static const char* decode_wireval(upb_Decoder* d, const char* ptr,
951
+ const upb_MiniTable_Field* field,
952
+ int wire_type, wireval* val, int* op) {
953
+ switch (wire_type) {
954
+ case kUpb_WireType_Varint:
955
+ ptr = decode_varint64(d, ptr, &val->uint64_val);
956
+ *op = varint_ops[field->descriptortype];
957
+ decode_munge(field->descriptortype, val);
958
+ return ptr;
959
+ case kUpb_WireType_32Bit:
960
+ memcpy(&val->uint32_val, ptr, 4);
961
+ val->uint32_val = _upb_BigEndian_Swap32(val->uint32_val);
962
+ *op = OP_SCALAR_LG2(2);
963
+ if (((1 << field->descriptortype) & FIXED32_OK_MASK) == 0) {
964
+ *op = OP_UNKNOWN;
965
+ }
966
+ return ptr + 4;
967
+ case kUpb_WireType_64Bit:
968
+ memcpy(&val->uint64_val, ptr, 8);
969
+ val->uint64_val = _upb_BigEndian_Swap64(val->uint64_val);
970
+ *op = OP_SCALAR_LG2(3);
971
+ if (((1 << field->descriptortype) & FIXED64_OK_MASK) == 0) {
972
+ *op = OP_UNKNOWN;
973
+ }
974
+ return ptr + 8;
975
+ case kUpb_WireType_Delimited: {
976
+ int ndx = field->descriptortype;
977
+ if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += TYPE_COUNT;
978
+ ptr = upb_Decoder_DecodeSize(d, ptr, &val->size);
979
+ *op = delim_ops[ndx];
980
+ return ptr;
981
+ }
982
+ case kUpb_WireType_StartGroup:
983
+ val->uint32_val = field->number;
984
+ if (field->descriptortype == kUpb_FieldType_Group) {
985
+ *op = OP_SUBMSG;
986
+ } else if (field->descriptortype == TYPE_MSGSET_ITEM) {
987
+ *op = OP_MSGSET_ITEM;
988
+ } else {
989
+ *op = OP_UNKNOWN;
990
+ }
991
+ return ptr;
992
+ default:
993
+ break;
994
+ }
995
+ return decode_err(d, kUpb_DecodeStatus_Malformed);
996
+ }
997
+
998
+ UPB_FORCEINLINE
999
+ static const char* decode_known(upb_Decoder* d, const char* ptr,
1000
+ upb_Message* msg, const upb_MiniTable* layout,
1001
+ const upb_MiniTable_Field* field, int op,
1002
+ wireval* val) {
1003
+ const upb_MiniTable_Sub* subs = layout->subs;
1004
+ uint8_t mode = field->mode;
1005
+
1006
+ if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) {
1007
+ const upb_MiniTable_Extension* ext_layout =
1008
+ (const upb_MiniTable_Extension*)field;
1009
+ upb_Message_Extension* ext =
1010
+ _upb_Message_GetOrCreateExtension(msg, ext_layout, &d->arena);
1011
+ if (UPB_UNLIKELY(!ext)) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
1012
+ msg = &ext->data;
1013
+ subs = &ext->ext->sub;
1014
+ }
1015
+
1016
+ switch (mode & kUpb_FieldMode_Mask) {
1017
+ case kUpb_FieldMode_Array:
1018
+ return decode_toarray(d, ptr, msg, subs, field, val, op);
1019
+ case kUpb_FieldMode_Map:
1020
+ return decode_tomap(d, ptr, msg, subs, field, val);
1021
+ case kUpb_FieldMode_Scalar:
1022
+ return decode_tomsg(d, ptr, msg, subs, field, val, op);
1023
+ default:
1024
+ UPB_UNREACHABLE();
1025
+ }
1026
+ }
1027
+
1028
+ static const char* decode_reverse_skip_varint(const char* ptr, uint32_t val) {
1029
+ uint32_t seen = 0;
1030
+ do {
1031
+ ptr--;
1032
+ seen <<= 7;
1033
+ seen |= *ptr & 0x7f;
1034
+ } while (seen != val);
1035
+ return ptr;
1036
+ }
1037
+
1038
+ static const char* decode_unknown(upb_Decoder* d, const char* ptr,
1039
+ upb_Message* msg, int field_number,
1040
+ int wire_type, wireval val) {
1041
+ if (field_number == 0) return decode_err(d, kUpb_DecodeStatus_Malformed);
1042
+
1043
+ // Since unknown fields are the uncommon case, we do a little extra work here
1044
+ // to walk backwards through the buffer to find the field start. This frees
1045
+ // up a register in the fast paths (when the field is known), which leads to
1046
+ // significant speedups in benchmarks.
1047
+ const char* start = ptr;
1048
+
1049
+ if (wire_type == kUpb_WireType_Delimited) ptr += val.size;
1050
+ if (msg) {
1051
+ switch (wire_type) {
1052
+ case kUpb_WireType_Varint:
1053
+ case kUpb_WireType_Delimited:
1054
+ start--;
1055
+ while (start[-1] & 0x80) start--;
1056
+ break;
1057
+ case kUpb_WireType_32Bit:
1058
+ start -= 4;
1059
+ break;
1060
+ case kUpb_WireType_64Bit:
1061
+ start -= 8;
1062
+ break;
1063
+ default:
1064
+ break;
1065
+ }
1066
+
1067
+ assert(start == d->debug_valstart);
1068
+ uint32_t tag = ((uint32_t)field_number << 3) | wire_type;
1069
+ start = decode_reverse_skip_varint(start, tag);
1070
+ assert(start == d->debug_tagstart);
1071
+
1072
+ if (wire_type == kUpb_WireType_StartGroup) {
1073
+ d->unknown = start;
1074
+ d->unknown_msg = msg;
1075
+ ptr = decode_group(d, ptr, NULL, NULL, field_number);
1076
+ start = d->unknown;
1077
+ d->unknown_msg = NULL;
1078
+ d->unknown = NULL;
1079
+ }
1080
+ if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) {
1081
+ return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
1082
+ }
1083
+ } else if (wire_type == kUpb_WireType_StartGroup) {
1084
+ ptr = decode_group(d, ptr, NULL, NULL, field_number);
1085
+ }
1086
+ return ptr;
1087
+ }
1088
+
1089
+ UPB_NOINLINE
1090
+ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
1091
+ const upb_MiniTable* layout) {
1092
+ int last_field_index = 0;
1093
+
1094
+ #if UPB_FASTTABLE
1095
+ // The first time we want to skip fast dispatch, because we may have just been
1096
+ // invoked by the fast parser to handle a case that it bailed on.
1097
+ if (!decode_isdone(d, &ptr)) goto nofast;
1098
+ #endif
1099
+
1100
+ while (!decode_isdone(d, &ptr)) {
1101
+ uint32_t tag;
1102
+ const upb_MiniTable_Field* field;
1103
+ int field_number;
1104
+ int wire_type;
1105
+ wireval val;
1106
+ int op;
1107
+
1108
+ if (decode_tryfastdispatch(d, &ptr, msg, layout)) break;
1109
+
1110
+ #if UPB_FASTTABLE
1111
+ nofast:
1112
+ #endif
1113
+
1114
+ #ifndef NDEBUG
1115
+ d->debug_tagstart = ptr;
1116
+ #endif
1117
+
1118
+ UPB_ASSERT(ptr < d->limit_ptr);
1119
+ ptr = decode_tag(d, ptr, &tag);
1120
+ field_number = tag >> 3;
1121
+ wire_type = tag & 7;
1122
+
1123
+ #ifndef NDEBUG
1124
+ d->debug_valstart = ptr;
1125
+ #endif
1126
+
1127
+ if (wire_type == kUpb_WireType_EndGroup) {
1128
+ d->end_group = field_number;
1129
+ return ptr;
1130
+ }
1131
+
1132
+ field = decode_findfield(d, layout, field_number, &last_field_index);
1133
+ ptr = decode_wireval(d, ptr, field, wire_type, &val, &op);
1134
+
1135
+ if (op >= 0) {
1136
+ ptr = decode_known(d, ptr, msg, layout, field, op, &val);
1137
+ } else {
1138
+ switch (op) {
1139
+ case OP_UNKNOWN:
1140
+ ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val);
1141
+ break;
1142
+ case OP_MSGSET_ITEM:
1143
+ ptr = upb_Decoder_DecodeMessageSetItem(d, ptr, msg, layout);
1144
+ break;
1145
+ }
1146
+ }
1147
+ }
1148
+
1149
+ return UPB_UNLIKELY(layout && layout->required_count)
1150
+ ? decode_checkrequired(d, ptr, msg, layout)
1151
+ : ptr;
1152
+ }
1153
+
1154
+ const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr,
1155
+ upb_Message* msg, intptr_t table,
1156
+ uint64_t hasbits, uint64_t data) {
1157
+ (void)data;
1158
+ *(uint32_t*)msg |= hasbits;
1159
+ return decode_msg(d, ptr, msg, decode_totablep(table));
1160
+ }
1161
+
1162
+ static upb_DecodeStatus decode_top(struct upb_Decoder* d, const char* buf,
1163
+ void* msg, const upb_MiniTable* l) {
1164
+ if (!decode_tryfastdispatch(d, &buf, msg, l)) {
1165
+ decode_msg(d, buf, msg, l);
1166
+ }
1167
+ if (d->end_group != DECODE_NOGROUP) return kUpb_DecodeStatus_Malformed;
1168
+ if (d->missing_required) return kUpb_DecodeStatus_MissingRequired;
1169
+ return kUpb_DecodeStatus_Ok;
1170
+ }
1171
+
1172
+ upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg,
1173
+ const upb_MiniTable* l,
1174
+ const upb_ExtensionRegistry* extreg, int options,
1175
+ upb_Arena* arena) {
1176
+ upb_Decoder state;
1177
+ unsigned depth = (unsigned)options >> 16;
1178
+
1179
+ if (size <= 16) {
1180
+ memset(&state.patch, 0, 32);
1181
+ if (size) memcpy(&state.patch, buf, size);
1182
+ buf = state.patch;
1183
+ state.end = buf + size;
1184
+ state.limit = 0;
1185
+ options &= ~kUpb_DecodeOption_AliasString; // Can't alias patch buf.
1186
+ } else {
1187
+ state.end = buf + size - 16;
1188
+ state.limit = 16;
1189
+ }
1190
+
1191
+ state.extreg = extreg;
1192
+ state.limit_ptr = state.end;
1193
+ state.unknown_msg = NULL;
1194
+ state.depth = depth ? depth : 64;
1195
+ state.end_group = DECODE_NOGROUP;
1196
+ state.options = (uint16_t)options;
1197
+ state.missing_required = false;
1198
+ state.arena.head = arena->head;
1199
+ state.arena.last_size = arena->last_size;
1200
+ state.arena.cleanup_metadata = arena->cleanup_metadata;
1201
+ state.arena.parent = arena;
1202
+
1203
+ upb_DecodeStatus status = UPB_SETJMP(state.err);
1204
+ if (UPB_LIKELY(status == kUpb_DecodeStatus_Ok)) {
1205
+ status = decode_top(&state, buf, msg, l);
1206
+ }
1207
+
1208
+ arena->head.ptr = state.arena.head.ptr;
1209
+ arena->head.end = state.arena.head.end;
1210
+ arena->cleanup_metadata = state.arena.cleanup_metadata;
1211
+ return status;
1212
+ }
1213
+
1214
+ #undef OP_UNKNOWN
1215
+ #undef OP_SKIP
1216
+ #undef OP_SCALAR_LG2
1217
+ #undef OP_FIXPCK_LG2
1218
+ #undef OP_VARPCK_LG2
1219
+ #undef OP_STRING
1220
+ #undef OP_BYTES
1221
+ #undef OP_SUBMSG