split out the alloc code from the arena code

PiperOrigin-RevId: 456531002
diff --git a/BUILD b/BUILD
index 95701d1..00bd8fd 100644
--- a/BUILD
+++ b/BUILD
@@ -102,6 +102,7 @@
 cc_library(
     name = "upb",
     srcs = [
+        "upb/alloc.c",
         "upb/arena.c",
         "upb/decode.c",
         "upb/encode.c",
@@ -115,6 +116,7 @@
         "upb/upb.c",
     ],
     hdrs = [
+        "upb/alloc.h",
         "upb/arena.h",
         "upb/decode.h",
         "upb/encode.h",
@@ -707,6 +709,7 @@
 cc_library(
     name = "table",
     hdrs = [
+        "upb/alloc.h",
         "upb/arena.h",
         "upb/internal/table.h",
         "upb/status.h",
diff --git a/upb/alloc.c b/upb/alloc.c
new file mode 100644
index 0000000..6e242cd
--- /dev/null
+++ b/upb/alloc.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009-2021, Google LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Google LLC nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "upb/alloc.h"
+
+#include <stdlib.h>
+
+// Must be last.
+#include "upb/port_def.inc"
+
+static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
+                                  size_t size) {
+  UPB_UNUSED(alloc);
+  UPB_UNUSED(oldsize);
+  if (size == 0) {
+    free(ptr);
+    return NULL;
+  } else {
+    return realloc(ptr, size);
+  }
+}
+
+upb_alloc upb_alloc_global = {&upb_global_allocfunc};
diff --git a/upb/alloc.h b/upb/alloc.h
new file mode 100644
index 0000000..add70b8
--- /dev/null
+++ b/upb/alloc.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009-2021, Google LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Google LLC nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UPB_ALLOC_H_
+#define UPB_ALLOC_H_
+
+#include "upb/port_def.inc"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct upb_alloc;
+typedef struct upb_alloc upb_alloc;
+
+/* A combined `malloc()`/`free()` function.
+ * If `size` is 0 then the function acts like `free()`, otherwise it acts like
+ * `realloc()`.  Only `oldsize` bytes from a previous allocation are
+ * preserved. */
+typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize,
+                             size_t size);
+
+/* A upb_alloc is a possibly-stateful allocator object.
+ *
+ * It could either be an arena allocator (which doesn't require individual
+ * `free()` calls) or a regular `malloc()` (which does).  The client must
+ * therefore free memory unless it knows that the allocator is an arena
+ * allocator. */
+struct upb_alloc {
+  upb_alloc_func* func;
+};
+
+UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) {
+  UPB_ASSERT(alloc);
+  return alloc->func(alloc, NULL, 0, size);
+}
+
+UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize,
+                             size_t size) {
+  UPB_ASSERT(alloc);
+  return alloc->func(alloc, ptr, oldsize, size);
+}
+
+UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) {
+  UPB_ASSERT(alloc);
+  alloc->func(alloc, ptr, 0, 0);
+}
+
+/* The global allocator used by upb.  Uses the standard malloc()/free(). */
+
+extern upb_alloc upb_alloc_global;
+
+/* Functions that hard-code the global malloc.
+ *
+ * We still get benefit because we can put custom logic into our global
+ * allocator, like injecting out-of-memory faults in debug/testing builds. */
+
+UPB_INLINE void* upb_gmalloc(size_t size) {
+  return upb_malloc(&upb_alloc_global, size);
+}
+
+UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) {
+  return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
+}
+
+UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); }
+
+#include "upb/port_undef.inc"
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* UPB_ALLOC_H_ */
diff --git a/upb/arena.c b/upb/arena.c
index 3c87269..6cee9cf 100644
--- a/upb/arena.c
+++ b/upb/arena.c
@@ -27,27 +27,12 @@
 
 #include "upb/arena.h"
 
-#include <stdlib.h>
-
+#include "upb/alloc.h"
 #include "upb/internal/upb.h"
 
 // Must be last.
 #include "upb/port_def.inc"
 
-/* upb_alloc ******************************************************************/
-
-static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
-                                  size_t size) {
-  UPB_UNUSED(alloc);
-  UPB_UNUSED(oldsize);
-  if (size == 0) {
-    free(ptr);
-    return NULL;
-  } else {
-    return realloc(ptr, size);
-  }
-}
-
 static uint32_t* upb_cleanup_pointer(uintptr_t cleanup_metadata) {
   return (uint32_t*)(cleanup_metadata & ~0x1);
 }
@@ -61,10 +46,6 @@
   return (uintptr_t)cleanup | has_initial_block;
 }
 
-upb_alloc upb_alloc_global = {&upb_global_allocfunc};
-
-/* upb_Arena ******************************************************************/
-
 struct mem_block {
   struct mem_block* next;
   uint32_t size;
@@ -135,7 +116,7 @@
 
 /* Public Arena API ***********************************************************/
 
-upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) {
+static upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) {
   const size_t first_block_overhead = sizeof(upb_Arena) + memblock_reserve;
   upb_Arena* a;
 
diff --git a/upb/arena.h b/upb/arena.h
index 0c4fd1b..81a673b 100644
--- a/upb/arena.h
+++ b/upb/arena.h
@@ -28,75 +28,18 @@
 #ifndef UPB_ARENA_H_
 #define UPB_ARENA_H_
 
-#include <assert.h>
 #include <stdbool.h>
-#include <stdint.h>
 #include <string.h>
 
+#include "upb/alloc.h"
+
+// Must be last.
 #include "upb/port_def.inc"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** upb_alloc *****************************************************************/
-
-/* A upb_alloc is a possibly-stateful allocator object.
- *
- * It could either be an arena allocator (which doesn't require individual
- * free() calls) or a regular malloc() (which does).  The client must therefore
- * free memory unless it knows that the allocator is an arena allocator. */
-
-struct upb_alloc;
-typedef struct upb_alloc upb_alloc;
-
-/* A malloc()/free() function.
- * If "size" is 0 then the function acts like free(), otherwise it acts like
- * realloc().  Only "oldsize" bytes from a previous allocation are preserved. */
-typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize,
-                             size_t size);
-
-struct upb_alloc {
-  upb_alloc_func* func;
-};
-
-UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) {
-  UPB_ASSERT(alloc);
-  return alloc->func(alloc, NULL, 0, size);
-}
-
-UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize,
-                             size_t size) {
-  UPB_ASSERT(alloc);
-  return alloc->func(alloc, ptr, oldsize, size);
-}
-
-UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) {
-  assert(alloc);
-  alloc->func(alloc, ptr, 0, 0);
-}
-
-/* The global allocator used by upb.  Uses the standard malloc()/free(). */
-
-extern upb_alloc upb_alloc_global;
-
-/* Functions that hard-code the global malloc.
- *
- * We still get benefit because we can put custom logic into our global
- * allocator, like injecting out-of-memory faults in debug/testing builds. */
-
-UPB_INLINE void* upb_gmalloc(size_t size) {
-  return upb_malloc(&upb_alloc_global, size);
-}
-
-UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) {
-  return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
-}
-
-UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); }
-
-/* upb_Arena ******************************************************************/
-
 /* upb_Arena is a specific allocator implementation that uses arena allocation.
  * The user provides an allocator that will be used to allocate the underlying
  * arena blocks.  Arenas by nature do not require the individual allocations
diff --git a/upb/port_def.inc b/upb/port_def.inc
index 92e4bf2..849a765 100644
--- a/upb/port_def.inc
+++ b/upb/port_def.inc
@@ -54,8 +54,11 @@
 #error upb requires C99 or C++11 or MSVC >= 2015.
 #endif
 
-#include <stdint.h>
+#include <assert.h>
+#include <setjmp.h>
+#include <stdbool.h>
 #include <stddef.h>
+#include <stdint.h>
 
 #if UINTPTR_MAX == 0xffffffff
 #define UPB_SIZE(size32, size64) size32