Refactor f64conv's wuffs_base__parse_number_f64

Binary size, before:
27704 gen/lib/c/clang-5.0-dynamic/wuffs-base-f64conv.lo
27896 gen/lib/c/clang-5.0-static/wuffs-base-f64conv.o
29120 gen/lib/c/gcc-dynamic/wuffs-base-f64conv.lo
29120 gen/lib/c/gcc-static/wuffs-base-f64conv.o

After:
27848 gen/lib/c/clang-5.0-dynamic/wuffs-base-f64conv.lo
28040 gen/lib/c/clang-5.0-static/wuffs-base-f64conv.o
30392 gen/lib/c/gcc-dynamic/wuffs-base-f64conv.lo
30392 gen/lib/c/gcc-static/wuffs-base-f64conv.o

$ g++ -O3 script/process-json-numbers.c
$ time ./a.out -parse-number-f64 < citylots.json
Before/After:
real    0m1.306s
real	0m1.231s

citylots.json is from github.com/zemirco/sf-city-lots-json

name                                                old time/op  new time/op  delta
wuffs_strconv_parse_number_f64_1_lsh53_add0/clang5  73.2ns ± 2%  77.0ns ± 0%   +5.19%  (p=0.016 n=5+4)
wuffs_strconv_parse_number_f64_1_lsh53_add1/clang5   688ns ± 0%   690ns ± 0%     ~     (p=0.079 n=5+5)
wuffs_strconv_parse_number_f64_pi_long/clang5        113ns ± 1%    92ns ± 0%  -18.44%  (p=0.000 n=5+4)
wuffs_strconv_parse_number_f64_pi_short/clang5      35.4ns ± 7%  35.0ns ± 3%     ~     (p=1.000 n=5+5)
wuffs_strconv_parse_number_f64_1_lsh53_add0/gcc7    67.0ns ± 0%  67.0ns ± 0%     ~     (all equal)
wuffs_strconv_parse_number_f64_1_lsh53_add1/gcc7     721ns ± 0%   712ns ± 0%   -1.30%  (p=0.008 n=5+5)
wuffs_strconv_parse_number_f64_pi_long/gcc7         90.4ns ± 1%  88.4ns ± 1%   -2.21%  (p=0.008 n=5+5)
wuffs_strconv_parse_number_f64_pi_short/gcc7        32.2ns ± 6%  32.6ns ± 2%     ~     (p=0.730 n=5+5)
diff --git a/internal/cgen/base/f64conv-submodule.c b/internal/cgen/base/f64conv-submodule.c
index 05fff67..c1630b0 100644
--- a/internal/cgen/base/f64conv-submodule.c
+++ b/internal/cgen/base/f64conv-submodule.c
@@ -2007,10 +2007,8 @@
 }
 
 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
-wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
-  wuffs_base__private_implementation__medium_prec_bin m;
-  wuffs_base__private_implementation__high_prec_dec h;
-
+wuffs_base__private_implementation__parse_number_f64__fallback(
+    wuffs_base__private_implementation__high_prec_dec* h) {
   do {
     // powers converts decimal powers of 10 to binary powers of 2. For example,
     // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
@@ -2021,23 +2019,18 @@
         33, 36, 39, 43, 46, 49, 53, 56, 59,      //
     };
 
-    wuffs_base__status status =
-        wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
-    if (status.repr) {
-      return wuffs_base__parse_number_f64_special(s, status.repr);
-    }
-
     // Handle zero and obvious extremes. The largest and smallest positive
     // finite f64 values are approximately 1.8e+308 and 4.9e-324.
-    if ((h.num_digits == 0) || (h.decimal_point < -326)) {
+    if ((h->num_digits == 0) || (h->decimal_point < -326)) {
       goto zero;
-    } else if (h.decimal_point > 310) {
+    } else if (h->decimal_point > 310) {
       goto infinity;
     }
 
+    wuffs_base__private_implementation__medium_prec_bin m;
     wuffs_base__result_f64 mpb_result =
         wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(
-            &m, &h, false);
+            &m, h, false);
     if (mpb_result.status.repr == NULL) {
       return mpb_result;
     }
@@ -2047,39 +2040,37 @@
     // far, ending with a value certainly below 1 and possibly below ½...
     const int32_t f64_bias = -1023;
     int32_t exp2 = 0;
-    while (h.decimal_point > 0) {
-      uint32_t n = (uint32_t)(+h.decimal_point);
+    while (h->decimal_point > 0) {
+      uint32_t n = (uint32_t)(+h->decimal_point);
       uint32_t shift =
           (n < num_powers)
               ? powers[n]
               : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
 
-      wuffs_base__private_implementation__high_prec_dec__small_rshift(&h,
-                                                                      shift);
-      if (h.decimal_point <
+      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
+      if (h->decimal_point <
           -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
         goto zero;
       }
       exp2 += (int32_t)shift;
     }
     // ...then we shift left, putting us in [½ .. 1].
-    while (h.decimal_point <= 0) {
+    while (h->decimal_point <= 0) {
       uint32_t shift;
-      if (h.decimal_point == 0) {
-        if (h.digits[0] >= 5) {
+      if (h->decimal_point == 0) {
+        if (h->digits[0] >= 5) {
           break;
         }
-        shift = (h.digits[0] <= 2) ? 2 : 1;
+        shift = (h->digits[0] <= 2) ? 2 : 1;
       } else {
-        uint32_t n = (uint32_t)(-h.decimal_point);
+        uint32_t n = (uint32_t)(-h->decimal_point);
         shift = (n < num_powers)
                     ? powers[n]
                     : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
       }
 
-      wuffs_base__private_implementation__high_prec_dec__small_lshift(&h,
-                                                                      shift);
-      if (h.decimal_point >
+      wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
+      if (h->decimal_point >
           +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
         goto infinity;
       }
@@ -2095,7 +2086,7 @@
       if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
         n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
       }
-      wuffs_base__private_implementation__high_prec_dec__small_rshift(&h, n);
+      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
       exp2 += (int32_t)n;
     }
 
@@ -2105,9 +2096,9 @@
     }
 
     // Extract 53 bits for the mantissa (in base-2).
-    wuffs_base__private_implementation__high_prec_dec__small_lshift(&h, 53);
+    wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);
     uint64_t man2 =
-        wuffs_base__private_implementation__high_prec_dec__rounded_integer(&h);
+        wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
 
     // Rounding might have added one bit. If so, shift and re-check overflow.
     if ((man2 >> 53) != 0) {
@@ -2125,10 +2116,10 @@
 
     // Pack the bits and return.
     uint64_t exp2_bits =
-        (uint64_t)((exp2 - f64_bias) & 0x07FF);             // (1 << 11) - 1.
-    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |           // (1 << 52) - 1.
-                    (exp2_bits << 52) |                     //
-                    (h.negative ? 0x8000000000000000 : 0);  // (1 << 63).
+        (uint64_t)((exp2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.
+    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.
+                    (exp2_bits << 52) |                      //
+                    (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).
 
     wuffs_base__result_f64 ret;
     ret.status.repr = NULL;
@@ -2138,7 +2129,7 @@
 
 zero:
   do {
-    uint64_t bits = h.negative ? 0x8000000000000000 : 0;
+    uint64_t bits = h->negative ? 0x8000000000000000 : 0;
 
     wuffs_base__result_f64 ret;
     ret.status.repr = NULL;
@@ -2148,7 +2139,7 @@
 
 infinity:
   do {
-    uint64_t bits = h.negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
+    uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
 
     wuffs_base__result_f64 ret;
     ret.status.repr = NULL;
@@ -2157,6 +2148,17 @@
   } while (0);
 }
 
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
+wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
+  wuffs_base__private_implementation__high_prec_dec h;
+  wuffs_base__status status =
+      wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
+  if (status.repr) {
+    return wuffs_base__parse_number_f64_special(s, status.repr);
+  }
+  return wuffs_base__private_implementation__parse_number_f64__fallback(&h);
+}
+
 // --------
 
 static inline size_t  //
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index f29bcd0..dc16614 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -131,12 +131,12 @@
 	"" +
 	"// --------\n\nstatic wuffs_base__result_f64  //\nwuffs_base__parse_number_f64_special(wuffs_base__slice_u8 s,\n                                     const char* fallback_status_repr) {\n  do {\n    uint8_t* p = s.ptr;\n    uint8_t* q = s.ptr + s.len;\n\n    for (; (p < q) && (*p == '_'); p++) {\n    }\n    if (p >= q) {\n      goto fallback;\n    }\n\n    // Parse sign.\n    bool negative = false;\n    do {\n      if (*p == '+') {\n        p++;\n      } else if (*p == '-') {\n        negative = true;\n        p++;\n      } else {\n        break;\n      }\n      for (; (p < q) && (*p == '_'); p++) {\n      }\n    } while (0);\n    if (p >= q) {\n      goto fallback;\n    }\n\n    bool nan = false;\n    switch (p[0]) {\n      case 'I':\n      case 'i':\n        if (((q - p) < 3) ||                     //\n            ((p[1] != 'N') && (p[1] != 'n')) ||  //\n            ((p[2] != 'F') && (p[2] != 'f'))) {\n          goto fallback;\n        }\n        p += 3;\n\n        if ((p >= q) || (*p == '_')) {\n          break;\n        } else if (((q - p) < 5) ||    " +
 	"                 //\n                   ((p[0] != 'I') && (p[0] != 'i')) ||  //\n                   ((p[1] != 'N') && (p[1] != 'n')) ||  //\n                   ((p[2] != 'I') && (p[2] != 'i')) ||  //\n                   ((p[3] != 'T') && (p[3] != 't')) ||  //\n                   ((p[4] != 'Y') && (p[4] != 'y'))) {\n          goto fallback;\n        }\n        p += 5;\n\n        if ((p >= q) || (*p == '_')) {\n          break;\n        }\n        goto fallback;\n\n      case 'N':\n      case 'n':\n        if (((q - p) < 3) ||                     //\n            ((p[1] != 'A') && (p[1] != 'a')) ||  //\n            ((p[2] != 'N') && (p[2] != 'n'))) {\n          goto fallback;\n        }\n        p += 3;\n\n        if ((p >= q) || (*p == '_')) {\n          nan = true;\n          break;\n        }\n        goto fallback;\n\n      default:\n        goto fallback;\n    }\n\n    // Finish.\n    for (; (p < q) && (*p == '_'); p++) {\n    }\n    if (p != q) {\n      goto fallback;\n    }\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.va" +
-	"lue = wuffs_base__ieee_754_bit_representation__to_f64(\n        (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |\n        (negative ? 0x8000000000000000 : 0));\n    return ret;\n  } while (0);\n\nfallback:\n  do {\n    wuffs_base__result_f64 ret;\n    ret.status.repr = fallback_status_repr;\n    ret.value = 0;\n    return ret;\n  } while (0);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {\n  wuffs_base__private_implementation__medium_prec_bin m;\n  wuffs_base__private_implementation__high_prec_dec h;\n\n  do {\n    // powers converts decimal powers of 10 to binary powers of 2. For example,\n    // (10000 >> 13) is 1. It stops before the elements exceed 60, also known\n    // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.\n    static const uint32_t num_powers = 19;\n    static const uint8_t powers[19] = {\n        0,  3,  6,  9,  13, 16, 19, 23, 26, 29,  //\n        33, 36, 39, 43, 46, 49, 53, 56, 59,      //\n    };\n\n    wuffs_base__status status =\n       " +
-	" wuffs_base__private_implementation__high_prec_dec__parse(&h, s);\n    if (status.repr) {\n      return wuffs_base__parse_number_f64_special(s, status.repr);\n    }\n\n    // Handle zero and obvious extremes. The largest and smallest positive\n    // finite f64 values are approximately 1.8e+308 and 4.9e-324.\n    if ((h.num_digits == 0) || (h.decimal_point < -326)) {\n      goto zero;\n    } else if (h.decimal_point > 310) {\n      goto infinity;\n    }\n\n    wuffs_base__result_f64 mpb_result =\n        wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(\n            &m, &h, false);\n    if (mpb_result.status.repr == NULL) {\n      return mpb_result;\n    }\n\n    // Scale by powers of 2 until we're in the range [½ .. 1], which gives us\n    // our exponent (in base-2). First we shift right, possibly a little too\n    // far, ending with a value certainly below 1 and possibly below ½...\n    const int32_t f64_bias = -1023;\n    int32_t exp2 = 0;\n    while (h.decimal_point > 0) {\n      uint32_t n = (uint32_t)(+h" +
-	".decimal_point);\n      uint32_t shift =\n          (n < num_powers)\n              ? powers[n]\n              : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(&h,\n                                                                      shift);\n      if (h.decimal_point <\n          -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n        goto zero;\n      }\n      exp2 += (int32_t)shift;\n    }\n    // ...then we shift left, putting us in [½ .. 1].\n    while (h.decimal_point <= 0) {\n      uint32_t shift;\n      if (h.decimal_point == 0) {\n        if (h.digits[0] >= 5) {\n          break;\n        }\n        shift = (h.digits[0] <= 2) ? 2 : 1;\n      } else {\n        uint32_t n = (uint32_t)(-h.decimal_point);\n        shift = (n < num_powers)\n                    ? powers[n]\n                    : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n\n      wuffs_base__private_implementation__high_prec_dec__small_lshif" +
-	"t(&h,\n                                                                      shift);\n      if (h.decimal_point >\n          +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n        goto infinity;\n      }\n      exp2 -= (int32_t)shift;\n    }\n\n    // We're in the range [½ .. 1] but f64 uses [1 .. 2].\n    exp2--;\n\n    // The minimum normal exponent is (f64_bias + 1).\n    while ((f64_bias + 1) > exp2) {\n      uint32_t n = (uint32_t)((f64_bias + 1) - exp2);\n      if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n        n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(&h, n);\n      exp2 += (int32_t)n;\n    }\n\n    // Check for overflow.\n    if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n      goto infinity;\n    }\n\n    // Extract 53 bits for the mantissa (in base-2).\n    wuffs_base__private_implementation__high_prec_dec__small_lshift(&h, 53);\n    uint64_t man2 =\n        wuffs_base__privat" +
-	"e_implementation__high_prec_dec__rounded_integer(&h);\n\n    // Rounding might have added one bit. If so, shift and re-check overflow.\n    if ((man2 >> 53) != 0) {\n      man2 >>= 1;\n      exp2++;\n      if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n        goto infinity;\n      }\n    }\n\n    // Handle subnormal numbers.\n    if ((man2 >> 52) == 0) {\n      exp2 = f64_bias;\n    }\n\n    // Pack the bits and return.\n    uint64_t exp2_bits =\n        (uint64_t)((exp2 - f64_bias) & 0x07FF);             // (1 << 11) - 1.\n    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |           // (1 << 52) - 1.\n                    (exp2_bits << 52) |                     //\n                    (h.negative ? 0x8000000000000000 : 0);  // (1 << 63).\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n    return ret;\n  } while (0);\n\nzero:\n  do {\n    uint64_t bits = h.negative ? 0x8000000000000000 : 0;\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = " +
-	"NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n    return ret;\n  } while (0);\n\ninfinity:\n  do {\n    uint64_t bits = h.negative ? 0xFFF0000000000000 : 0x7FF0000000000000;\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n    return ret;\n  } while (0);\n}\n\n" +
+	"lue = wuffs_base__ieee_754_bit_representation__to_f64(\n        (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |\n        (negative ? 0x8000000000000000 : 0));\n    return ret;\n  } while (0);\n\nfallback:\n  do {\n    wuffs_base__result_f64 ret;\n    ret.status.repr = fallback_status_repr;\n    ret.value = 0;\n    return ret;\n  } while (0);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //\nwuffs_base__private_implementation__parse_number_f64__fallback(\n    wuffs_base__private_implementation__high_prec_dec* h) {\n  do {\n    // powers converts decimal powers of 10 to binary powers of 2. For example,\n    // (10000 >> 13) is 1. It stops before the elements exceed 60, also known\n    // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.\n    static const uint32_t num_powers = 19;\n    static const uint8_t powers[19] = {\n        0,  3,  6,  9,  13, 16, 19, 23, 26, 29,  //\n        33, 36, 39, 43, 46, 49, 53, 56, 59,      //\n    };\n\n    // Handle zero and obvious extremes. The largest and smallest positive\n    // f" +
+	"inite f64 values are approximately 1.8e+308 and 4.9e-324.\n    if ((h->num_digits == 0) || (h->decimal_point < -326)) {\n      goto zero;\n    } else if (h->decimal_point > 310) {\n      goto infinity;\n    }\n\n    wuffs_base__private_implementation__medium_prec_bin m;\n    wuffs_base__result_f64 mpb_result =\n        wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(\n            &m, h, false);\n    if (mpb_result.status.repr == NULL) {\n      return mpb_result;\n    }\n\n    // Scale by powers of 2 until we're in the range [½ .. 1], which gives us\n    // our exponent (in base-2). First we shift right, possibly a little too\n    // far, ending with a value certainly below 1 and possibly below ½...\n    const int32_t f64_bias = -1023;\n    int32_t exp2 = 0;\n    while (h->decimal_point > 0) {\n      uint32_t n = (uint32_t)(+h->decimal_point);\n      uint32_t shift =\n          (n < num_powers)\n              ? powers[n]\n              : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n\n      wuffs_bas" +
+	"e__private_implementation__high_prec_dec__small_rshift(h, shift);\n      if (h->decimal_point <\n          -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n        goto zero;\n      }\n      exp2 += (int32_t)shift;\n    }\n    // ...then we shift left, putting us in [½ .. 1].\n    while (h->decimal_point <= 0) {\n      uint32_t shift;\n      if (h->decimal_point == 0) {\n        if (h->digits[0] >= 5) {\n          break;\n        }\n        shift = (h->digits[0] <= 2) ? 2 : 1;\n      } else {\n        uint32_t n = (uint32_t)(-h->decimal_point);\n        shift = (n < num_powers)\n                    ? powers[n]\n                    : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n\n      wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);\n      if (h->decimal_point >\n          +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n        goto infinity;\n      }\n      exp2 -= (int32_t)shift;\n    }\n\n    // We're in the range [½ .. 1] but f64 uses [1 .. 2].\n   " +
+	" exp2--;\n\n    // The minimum normal exponent is (f64_bias + 1).\n    while ((f64_bias + 1) > exp2) {\n      uint32_t n = (uint32_t)((f64_bias + 1) - exp2);\n      if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n        n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);\n      exp2 += (int32_t)n;\n    }\n\n    // Check for overflow.\n    if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n      goto infinity;\n    }\n\n    // Extract 53 bits for the mantissa (in base-2).\n    wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);\n    uint64_t man2 =\n        wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);\n\n    // Rounding might have added one bit. If so, shift and re-check overflow.\n    if ((man2 >> 53) != 0) {\n      man2 >>= 1;\n      exp2++;\n      if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n        goto infinity;\n      }\n    }\n\n    // Handle subnormal numbe" +
+	"rs.\n    if ((man2 >> 52) == 0) {\n      exp2 = f64_bias;\n    }\n\n    // Pack the bits and return.\n    uint64_t exp2_bits =\n        (uint64_t)((exp2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.\n    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.\n                    (exp2_bits << 52) |                      //\n                    (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n    return ret;\n  } while (0);\n\nzero:\n  do {\n    uint64_t bits = h->negative ? 0x8000000000000000 : 0;\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n    return ret;\n  } while (0);\n\ninfinity:\n  do {\n    uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representatio" +
+	"n__to_f64(bits);\n    return ret;\n  } while (0);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {\n  wuffs_base__private_implementation__high_prec_dec h;\n  wuffs_base__status status =\n      wuffs_base__private_implementation__high_prec_dec__parse(&h, s);\n  if (status.repr) {\n    return wuffs_base__parse_number_f64_special(s, status.repr);\n  }\n  return wuffs_base__private_implementation__parse_number_f64__fallback(&h);\n}\n\n" +
 	"" +
 	"// --------\n\nstatic inline size_t  //\nwuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,\n                                               bool neg,\n                                               uint32_t options) {\n  if (neg) {\n    if (dst.len < 4) {\n      return 0;\n    }\n    wuffs_base__store_u32le__no_bounds_check(dst.ptr, 0x666E492D);  // '-Inf'le.\n    return 4;\n  }\n\n  if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {\n    if (dst.len < 4) {\n      return 0;\n    }\n    wuffs_base__store_u32le__no_bounds_check(dst.ptr, 0x666E492B);  // '+Inf'le.\n    return 4;\n  }\n\n  if (dst.len < 3) {\n    return 0;\n  }\n  wuffs_base__store_u24le__no_bounds_check(dst.ptr, 0x666E49);  // 'Inf'le.\n  return 3;\n}\n\nstatic inline size_t  //\nwuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) {\n  if (dst.len < 3) {\n    return 0;\n  }\n  wuffs_base__store_u24le__no_bounds_check(dst.ptr, 0x4E614E);  // 'NaN'le.\n  return 3;\n}\n\nstatic size_t  //\nwuffs_base__private_implementation__high" +
 	"_prec_dec__render_exponent_absent(\n    wuffs_base__slice_u8 dst,\n    wuffs_base__private_implementation__high_prec_dec* h,\n    uint32_t precision,\n    uint32_t options) {\n  size_t n = (h->negative ||\n              (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))\n                 ? 1\n                 : 0;\n  if (h->decimal_point <= 0) {\n    n += 1;\n  } else {\n    n += (size_t)(h->decimal_point);\n  }\n  if (precision > 0) {\n    n += precision + 1;  // +1 for the '.'.\n  }\n\n  // Don't modify dst if the formatted number won't fit.\n  if (n > dst.len) {\n    return 0;\n  }\n\n  // Align-left or align-right.\n  uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)\n                     ? &dst.ptr[dst.len - n]\n                     : &dst.ptr[0];\n\n  // Leading \"±\".\n  if (h->negative) {\n    *ptr++ = '-';\n  } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {\n    *ptr++ = '+';\n  }\n\n  // Integral digits.\n  if (h->decimal_point <= 0) {\n    *ptr++ = '0';\n  } else {\n    uint32_t m =\n" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 86f7417..cf96ec5 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -10953,10 +10953,8 @@
 }
 
 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
-wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
-  wuffs_base__private_implementation__medium_prec_bin m;
-  wuffs_base__private_implementation__high_prec_dec h;
-
+wuffs_base__private_implementation__parse_number_f64__fallback(
+    wuffs_base__private_implementation__high_prec_dec* h) {
   do {
     // powers converts decimal powers of 10 to binary powers of 2. For example,
     // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
@@ -10967,23 +10965,18 @@
         33, 36, 39, 43, 46, 49, 53, 56, 59,      //
     };
 
-    wuffs_base__status status =
-        wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
-    if (status.repr) {
-      return wuffs_base__parse_number_f64_special(s, status.repr);
-    }
-
     // Handle zero and obvious extremes. The largest and smallest positive
     // finite f64 values are approximately 1.8e+308 and 4.9e-324.
-    if ((h.num_digits == 0) || (h.decimal_point < -326)) {
+    if ((h->num_digits == 0) || (h->decimal_point < -326)) {
       goto zero;
-    } else if (h.decimal_point > 310) {
+    } else if (h->decimal_point > 310) {
       goto infinity;
     }
 
+    wuffs_base__private_implementation__medium_prec_bin m;
     wuffs_base__result_f64 mpb_result =
         wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(
-            &m, &h, false);
+            &m, h, false);
     if (mpb_result.status.repr == NULL) {
       return mpb_result;
     }
@@ -10993,39 +10986,37 @@
     // far, ending with a value certainly below 1 and possibly below ½...
     const int32_t f64_bias = -1023;
     int32_t exp2 = 0;
-    while (h.decimal_point > 0) {
-      uint32_t n = (uint32_t)(+h.decimal_point);
+    while (h->decimal_point > 0) {
+      uint32_t n = (uint32_t)(+h->decimal_point);
       uint32_t shift =
           (n < num_powers)
               ? powers[n]
               : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
 
-      wuffs_base__private_implementation__high_prec_dec__small_rshift(&h,
-                                                                      shift);
-      if (h.decimal_point <
+      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
+      if (h->decimal_point <
           -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
         goto zero;
       }
       exp2 += (int32_t)shift;
     }
     // ...then we shift left, putting us in [½ .. 1].
-    while (h.decimal_point <= 0) {
+    while (h->decimal_point <= 0) {
       uint32_t shift;
-      if (h.decimal_point == 0) {
-        if (h.digits[0] >= 5) {
+      if (h->decimal_point == 0) {
+        if (h->digits[0] >= 5) {
           break;
         }
-        shift = (h.digits[0] <= 2) ? 2 : 1;
+        shift = (h->digits[0] <= 2) ? 2 : 1;
       } else {
-        uint32_t n = (uint32_t)(-h.decimal_point);
+        uint32_t n = (uint32_t)(-h->decimal_point);
         shift = (n < num_powers)
                     ? powers[n]
                     : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
       }
 
-      wuffs_base__private_implementation__high_prec_dec__small_lshift(&h,
-                                                                      shift);
-      if (h.decimal_point >
+      wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
+      if (h->decimal_point >
           +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
         goto infinity;
       }
@@ -11041,7 +11032,7 @@
       if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
         n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
       }
-      wuffs_base__private_implementation__high_prec_dec__small_rshift(&h, n);
+      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
       exp2 += (int32_t)n;
     }
 
@@ -11051,9 +11042,9 @@
     }
 
     // Extract 53 bits for the mantissa (in base-2).
-    wuffs_base__private_implementation__high_prec_dec__small_lshift(&h, 53);
+    wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);
     uint64_t man2 =
-        wuffs_base__private_implementation__high_prec_dec__rounded_integer(&h);
+        wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
 
     // Rounding might have added one bit. If so, shift and re-check overflow.
     if ((man2 >> 53) != 0) {
@@ -11071,10 +11062,10 @@
 
     // Pack the bits and return.
     uint64_t exp2_bits =
-        (uint64_t)((exp2 - f64_bias) & 0x07FF);             // (1 << 11) - 1.
-    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |           // (1 << 52) - 1.
-                    (exp2_bits << 52) |                     //
-                    (h.negative ? 0x8000000000000000 : 0);  // (1 << 63).
+        (uint64_t)((exp2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.
+    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.
+                    (exp2_bits << 52) |                      //
+                    (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).
 
     wuffs_base__result_f64 ret;
     ret.status.repr = NULL;
@@ -11084,7 +11075,7 @@
 
 zero:
   do {
-    uint64_t bits = h.negative ? 0x8000000000000000 : 0;
+    uint64_t bits = h->negative ? 0x8000000000000000 : 0;
 
     wuffs_base__result_f64 ret;
     ret.status.repr = NULL;
@@ -11094,7 +11085,7 @@
 
 infinity:
   do {
-    uint64_t bits = h.negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
+    uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
 
     wuffs_base__result_f64 ret;
     ret.status.repr = NULL;
@@ -11103,6 +11094,17 @@
   } while (0);
 }
 
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
+wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
+  wuffs_base__private_implementation__high_prec_dec h;
+  wuffs_base__status status =
+      wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
+  if (status.repr) {
+    return wuffs_base__parse_number_f64_special(s, status.repr);
+  }
+  return wuffs_base__private_implementation__parse_number_f64__fallback(&h);
+}
+
 // --------
 
 static inline size_t  //