Redo Wuffs structs' quirk bool fields
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 5c8b4b9..26b70a3 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -5644,13 +5644,7 @@
     uint32_t f_metadata_fourcc_value;
     uint64_t f_metadata_chunk_length_value;
     uint64_t f_metadata_io_position;
-    bool f_quirk_enabled_delay_num_decoded_frames;
-    bool f_quirk_enabled_first_frame_local_palette_means_black_background;
-    bool f_quirk_enabled_honor_background_color;
-    bool f_quirk_enabled_ignore_too_much_pixel_data;
-    bool f_quirk_enabled_image_bounds_are_strict;
-    bool f_quirk_enabled_reject_empty_frame;
-    bool f_quirk_enabled_reject_empty_palette;
+    bool f_quirks[7];
     bool f_delayed_num_decoded_frames;
     bool f_end_of_data;
     bool f_restarted;
@@ -5895,13 +5889,7 @@
     uint32_t f_metadata_fourcc_value;
     uint64_t f_metadata_chunk_length_value;
     uint64_t f_metadata_io_position;
-    bool f_quirk_enabled_delay_num_decoded_frames;
-    bool f_quirk_enabled_first_frame_local_palette_means_black_background;
-    bool f_quirk_enabled_honor_background_color;
-    bool f_quirk_enabled_ignore_too_much_pixel_data;
-    bool f_quirk_enabled_image_bounds_are_strict;
-    bool f_quirk_enabled_reject_empty_frame;
-    bool f_quirk_enabled_reject_empty_palette;
+    bool f_quirks[7];
     bool f_delayed_num_decoded_frames;
     bool f_end_of_data;
     bool f_restarted;
@@ -6501,18 +6489,7 @@
     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
     wuffs_base__vtable null_vtable;
 
-    bool f_quirk_enabled_allow_backslash_etc[8];
-    bool f_quirk_enabled_allow_ascii_control_codes;
-    bool f_quirk_enabled_allow_backslash_capital_u;
-    bool f_quirk_enabled_allow_backslash_x;
-    bool f_quirk_enabled_allow_comment_block;
-    bool f_quirk_enabled_allow_comment_line;
-    bool f_quirk_enabled_allow_extra_comma;
-    bool f_quirk_enabled_allow_inf_nan_numbers;
-    bool f_quirk_enabled_allow_leading_ascii_record_separator;
-    bool f_quirk_enabled_allow_leading_unicode_byte_order_mark;
-    bool f_quirk_enabled_allow_trailing_new_line;
-    bool f_quirk_enabled_replace_invalid_unicode;
+    bool f_quirks[18];
     bool f_allow_leading_ars;
     bool f_allow_leading_ubom;
     bool f_end_of_data;
@@ -16380,6 +16357,10 @@
         88, 77, 80, 32, 68, 97, 116, 97, 88, 77, 80,
 };
 
+#define WUFFS_GIF__QUIRKS_BASE 1041635328
+
+#define WUFFS_GIF__QUIRKS_COUNT 7
+
 // ---------------- Private Initializer Prototypes
 
 // ---------------- Private Function Prototypes
@@ -16724,23 +16705,10 @@
     return wuffs_base__make_empty_struct();
   }
 
-  if (self->private_impl.f_call_sequence == 0) {
-    if (a_quirk == 1041635328) {
-      self->private_impl.f_quirk_enabled_delay_num_decoded_frames = a_enabled;
-    } else if (a_quirk == 1041635329) {
-      self->private_impl
-          .f_quirk_enabled_first_frame_local_palette_means_black_background =
-          a_enabled;
-    } else if (a_quirk == 1041635330) {
-      self->private_impl.f_quirk_enabled_honor_background_color = a_enabled;
-    } else if (a_quirk == 1041635331) {
-      self->private_impl.f_quirk_enabled_ignore_too_much_pixel_data = a_enabled;
-    } else if (a_quirk == 1041635332) {
-      self->private_impl.f_quirk_enabled_image_bounds_are_strict = a_enabled;
-    } else if (a_quirk == 1041635333) {
-      self->private_impl.f_quirk_enabled_reject_empty_frame = a_enabled;
-    } else if (a_quirk == 1041635334) {
-      self->private_impl.f_quirk_enabled_reject_empty_palette = a_enabled;
+  if ((self->private_impl.f_call_sequence == 0) && (a_quirk >= 1041635328)) {
+    a_quirk -= 1041635328;
+    if (a_quirk < 7) {
+      self->private_impl.f_quirks[a_quirk] = a_enabled;
     }
   }
   return wuffs_base__make_empty_struct();
@@ -16801,7 +16769,7 @@
       goto suspend;
     }
     v_ffio = !self->private_impl.f_gc_has_transparent_index;
-    if (!self->private_impl.f_quirk_enabled_honor_background_color) {
+    if (!self->private_impl.f_quirks[(1041635330 - 1041635328)]) {
       v_ffio =
           (v_ffio && (self->private_impl.f_frame_rect_x0 == 0) &&
            (self->private_impl.f_frame_rect_y0 == 0) &&
@@ -17211,8 +17179,7 @@
     if (!self->private_impl.f_gc_has_transparent_index) {
       v_background_color =
           self->private_impl.f_background_color_u32_argb_premul;
-      if (self->private_impl
-              .f_quirk_enabled_first_frame_local_palette_means_black_background &&
+      if (self->private_impl.f_quirks[(1041635329 - 1041635328)] &&
           (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
@@ -17346,7 +17313,7 @@
     if (status.repr) {
       goto suspend;
     }
-    if (self->private_impl.f_quirk_enabled_delay_num_decoded_frames) {
+    if (self->private_impl.f_quirks[(1041635328 - 1041635328)]) {
       self->private_impl.f_delayed_num_decoded_frames = true;
     } else {
       wuffs_base__u64__sat_add_indirect(
@@ -17781,7 +17748,7 @@
             ((uint8_t)(((v_argb >> 24) & 255)));
         v_i += 1;
       }
-      if (self->private_impl.f_quirk_enabled_honor_background_color) {
+      if (self->private_impl.f_quirks[(1041635330 - 1041635328)]) {
         if ((v_background_color_index != 0) &&
             (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
           v_j = (4 * ((uint32_t)(v_background_color_index)));
@@ -18537,7 +18504,7 @@
     }
     self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
     if ((self->private_impl.f_call_sequence == 0) &&
-        !self->private_impl.f_quirk_enabled_image_bounds_are_strict) {
+        !self->private_impl.f_quirks[(1041635332 - 1041635328)]) {
       self->private_impl.f_width = wuffs_base__u32__max(
           self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
       self->private_impl.f_height = wuffs_base__u32__max(
@@ -18577,23 +18544,10 @@
     return wuffs_base__make_empty_struct();
   }
 
-  if (self->private_impl.f_call_sequence == 0) {
-    if (a_quirk == 1041635328) {
-      self->private_impl.f_quirk_enabled_delay_num_decoded_frames = a_enabled;
-    } else if (a_quirk == 1041635329) {
-      self->private_impl
-          .f_quirk_enabled_first_frame_local_palette_means_black_background =
-          a_enabled;
-    } else if (a_quirk == 1041635330) {
-      self->private_impl.f_quirk_enabled_honor_background_color = a_enabled;
-    } else if (a_quirk == 1041635331) {
-      self->private_impl.f_quirk_enabled_ignore_too_much_pixel_data = a_enabled;
-    } else if (a_quirk == 1041635332) {
-      self->private_impl.f_quirk_enabled_image_bounds_are_strict = a_enabled;
-    } else if (a_quirk == 1041635333) {
-      self->private_impl.f_quirk_enabled_reject_empty_frame = a_enabled;
-    } else if (a_quirk == 1041635334) {
-      self->private_impl.f_quirk_enabled_reject_empty_palette = a_enabled;
+  if ((self->private_impl.f_call_sequence == 0) && (a_quirk >= 1041635328)) {
+    a_quirk -= 1041635328;
+    if (a_quirk < 7) {
+      self->private_impl.f_quirks[a_quirk] = a_enabled;
     }
   }
   return wuffs_base__make_empty_struct();
@@ -18654,7 +18608,7 @@
       goto suspend;
     }
     v_ffio = !self->private_impl.f_gc_has_transparent_index;
-    if (!self->private_impl.f_quirk_enabled_honor_background_color) {
+    if (!self->private_impl.f_quirks[(1041635330 - 1041635328)]) {
       v_ffio =
           (v_ffio && (self->private_impl.f_frame_rect_x0 == 0) &&
            (self->private_impl.f_frame_rect_y0 == 0) &&
@@ -19066,8 +19020,7 @@
     if (!self->private_impl.f_gc_has_transparent_index) {
       v_background_color =
           self->private_impl.f_background_color_u32_argb_premul;
-      if (self->private_impl
-              .f_quirk_enabled_first_frame_local_palette_means_black_background &&
+      if (self->private_impl.f_quirks[(1041635329 - 1041635328)] &&
           (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
@@ -19201,7 +19154,7 @@
     if (status.repr) {
       goto suspend;
     }
-    if (self->private_impl.f_quirk_enabled_delay_num_decoded_frames) {
+    if (self->private_impl.f_quirks[(1041635328 - 1041635328)]) {
       self->private_impl.f_delayed_num_decoded_frames = true;
     } else {
       wuffs_base__u64__sat_add_indirect(
@@ -19272,7 +19225,7 @@
         goto suspend;
       }
     }
-    if (self->private_impl.f_quirk_enabled_reject_empty_frame &&
+    if (self->private_impl.f_quirks[(1041635333 - 1041635328)] &&
         ((self->private_impl.f_frame_rect_x0 ==
           self->private_impl.f_frame_rect_x1) ||
          (self->private_impl.f_frame_rect_y0 ==
@@ -19677,7 +19630,7 @@
             ((uint8_t)(((v_argb >> 24) & 255)));
         v_i += 1;
       }
-      if (self->private_impl.f_quirk_enabled_honor_background_color) {
+      if (self->private_impl.f_quirks[(1041635330 - 1041635328)]) {
         if ((v_background_color_index != 0) &&
             (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
           v_j = (4 * ((uint32_t)(v_background_color_index)));
@@ -20435,7 +20388,7 @@
     self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
     self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
     if ((self->private_impl.f_call_sequence == 0) &&
-        !self->private_impl.f_quirk_enabled_image_bounds_are_strict) {
+        !self->private_impl.f_quirks[(1041635332 - 1041635328)]) {
       self->private_impl.f_width = wuffs_base__u32__max(
           self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
       self->private_impl.f_height = wuffs_base__u32__max(
@@ -20570,7 +20523,7 @@
         self->private_data.f_palettes[1][((4 * v_i) + 3)] = 255;
         v_i += 1;
       }
-    } else if (self->private_impl.f_quirk_enabled_reject_empty_palette &&
+    } else if (self->private_impl.f_quirks[(1041635334 - 1041635328)] &&
                !self->private_impl.f_has_global_palette) {
       status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
       goto exit;
@@ -20937,7 +20890,7 @@
   while (v_src_ri < ((uint64_t)(a_src.len))) {
     v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
     if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
-      if (self->private_impl.f_quirk_enabled_ignore_too_much_pixel_data) {
+      if (self->private_impl.f_quirks[(1041635331 - 1041635328)]) {
         return wuffs_base__make_status(NULL);
       }
       return wuffs_base__make_status(wuffs_base__error__too_much_data);
@@ -21641,8 +21594,14 @@
         0,   0, 0,   0,   0, 0, 0, 0,   0,
 };
 
-static const uint8_t                       //
-    WUFFS_JSON__LUT_QUIRKY_BACKSLASHES[8]  //
+static const uint8_t                              //
+    WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8]  //
+    WUFFS_BASE__POTENTIALLY_UNUSED = {
+        0, 1, 3, 4, 5, 6, 7, 9,
+};
+
+static const uint8_t                             //
+    WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8]  //
     WUFFS_BASE__POTENTIALLY_UNUSED = {
         0, 7, 27, 10, 63, 39, 11, 0,
 };
@@ -21759,6 +21718,10 @@
         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,
 };
 
+#define WUFFS_JSON__QUIRKS_BASE 1225364480
+
+#define WUFFS_JSON__QUIRKS_COUNT 18
+
 // ---------------- Private Initializer Prototypes
 
 // ---------------- Private Function Prototypes
@@ -21894,44 +21857,11 @@
     return wuffs_base__make_empty_struct();
   }
 
-  if (a_quirk == 1225364480) {
-    self->private_impl.f_quirk_enabled_allow_ascii_control_codes = a_enabled;
-  } else if (a_quirk == 1225364481) {
-    self->private_impl.f_quirk_enabled_allow_backslash_etc[1] = a_enabled;
-  } else if (a_quirk == 1225364482) {
-    self->private_impl.f_quirk_enabled_allow_backslash_capital_u = a_enabled;
-  } else if (a_quirk == 1225364483) {
-    self->private_impl.f_quirk_enabled_allow_backslash_etc[2] = a_enabled;
-  } else if (a_quirk == 1225364484) {
-    self->private_impl.f_quirk_enabled_allow_backslash_etc[3] = a_enabled;
-  } else if (a_quirk == 1225364485) {
-    self->private_impl.f_quirk_enabled_allow_backslash_etc[4] = a_enabled;
-  } else if (a_quirk == 1225364486) {
-    self->private_impl.f_quirk_enabled_allow_backslash_etc[5] = a_enabled;
-  } else if (a_quirk == 1225364487) {
-    self->private_impl.f_quirk_enabled_allow_backslash_etc[6] = a_enabled;
-  } else if (a_quirk == 1225364488) {
-    self->private_impl.f_quirk_enabled_allow_backslash_x = a_enabled;
-  } else if (a_quirk == 1225364489) {
-    self->private_impl.f_quirk_enabled_allow_backslash_etc[7] = a_enabled;
-  } else if (a_quirk == 1225364490) {
-    self->private_impl.f_quirk_enabled_allow_comment_block = a_enabled;
-  } else if (a_quirk == 1225364491) {
-    self->private_impl.f_quirk_enabled_allow_comment_line = a_enabled;
-  } else if (a_quirk == 1225364492) {
-    self->private_impl.f_quirk_enabled_allow_extra_comma = a_enabled;
-  } else if (a_quirk == 1225364493) {
-    self->private_impl.f_quirk_enabled_allow_inf_nan_numbers = a_enabled;
-  } else if (a_quirk == 1225364494) {
-    self->private_impl.f_quirk_enabled_allow_leading_ascii_record_separator =
-        a_enabled;
-  } else if (a_quirk == 1225364495) {
-    self->private_impl.f_quirk_enabled_allow_leading_unicode_byte_order_mark =
-        a_enabled;
-  } else if (a_quirk == 1225364496) {
-    self->private_impl.f_quirk_enabled_allow_trailing_new_line = a_enabled;
-  } else if (a_quirk == 1225364497) {
-    self->private_impl.f_quirk_enabled_replace_invalid_unicode = a_enabled;
+  if (a_quirk >= 1225364480) {
+    a_quirk -= 1225364480;
+    if (a_quirk < 18) {
+      self->private_impl.f_quirks[a_quirk] = a_enabled;
+    }
   }
   return wuffs_base__make_empty_struct();
 }
@@ -22046,10 +21976,8 @@
       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
       goto ok;
     }
-    if (self->private_impl
-            .f_quirk_enabled_allow_leading_ascii_record_separator ||
-        self->private_impl
-            .f_quirk_enabled_allow_leading_unicode_byte_order_mark) {
+    if (self->private_impl.f_quirks[(1225364494 - 1225364480)] ||
+        self->private_impl.f_quirks[(1225364495 - 1225364480)]) {
       if (a_dst) {
         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
       }
@@ -22255,14 +22183,16 @@
                       (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
                   goto label__string_loop_outer__continue;
                 } else if (v_backslash != 0) {
-                  if (self->private_impl.f_quirk_enabled_allow_backslash_etc[(
-                          v_backslash & 7)]) {
+                  if (self->private_impl
+                          .f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(
+                              v_backslash & 7)]]) {
                     (iop_a_src += 2, wuffs_base__make_empty_struct());
                     *iop_a_dst++ = wuffs_base__make_token(
                         (((uint64_t)(
                              (6291456 |
-                              ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES[(
-                                  v_backslash & 7)])))))
+                              ((uint32_t)(
+                                  WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(
+                                      v_backslash & 7)])))))
                          << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
                         (((uint64_t)(1))
                          << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
@@ -22320,7 +22250,7 @@
                     if (((uint64_t)(io2_a_src - iop_a_src)) < 12) {
                       if (a_src && a_src->meta.closed) {
                         if (self->private_impl
-                                .f_quirk_enabled_replace_invalid_unicode) {
+                                .f_quirks[(1225364497 - 1225364480)]) {
                           (iop_a_src += 6, wuffs_base__make_empty_struct());
                           *iop_a_dst++ = wuffs_base__make_token(
                               (((uint64_t)(6356989))
@@ -22389,8 +22319,7 @@
                       goto label__string_loop_outer__continue;
                     }
                   }
-                  if (self->private_impl
-                          .f_quirk_enabled_replace_invalid_unicode) {
+                  if (self->private_impl.f_quirks[(1225364497 - 1225364480)]) {
                     if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
                       status = wuffs_base__make_status(
                           wuffs_json__error__internal_error_inconsistent_i_o);
@@ -22407,7 +22336,7 @@
                   }
                 } else if ((v_c == 85) &&
                            self->private_impl
-                               .f_quirk_enabled_allow_backslash_capital_u) {
+                               .f_quirks[(1225364482 - 1225364480)]) {
                   if (((uint64_t)(io2_a_src - iop_a_src)) < 10) {
                     if (a_src && a_src->meta.closed) {
                       status = wuffs_base__make_status(
@@ -22470,7 +22399,7 @@
                         (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
                     goto label__string_loop_outer__continue;
                   } else if (self->private_impl
-                                 .f_quirk_enabled_replace_invalid_unicode) {
+                                 .f_quirks[(1225364497 - 1225364480)]) {
                     (iop_a_src += 10, wuffs_base__make_empty_struct());
                     *iop_a_dst++ = wuffs_base__make_token(
                         (((uint64_t)(6356989))
@@ -22482,7 +22411,7 @@
                   }
                 } else if ((v_c == 120) &&
                            self->private_impl
-                               .f_quirk_enabled_allow_backslash_x) {
+                               .f_quirks[(1225364488 - 1225364480)]) {
                   if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
                     if (a_src && a_src->meta.closed) {
                       status = wuffs_base__make_status(
@@ -22549,7 +22478,7 @@
                   }
                   if (a_src && a_src->meta.closed) {
                     if (self->private_impl
-                            .f_quirk_enabled_replace_invalid_unicode) {
+                            .f_quirks[(1225364497 - 1225364480)]) {
                       *iop_a_dst++ = wuffs_base__make_token(
                           (((uint64_t)(6356989))
                            << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
@@ -22608,7 +22537,7 @@
                   }
                   if (a_src && a_src->meta.closed) {
                     if (self->private_impl
-                            .f_quirk_enabled_replace_invalid_unicode) {
+                            .f_quirks[(1225364497 - 1225364480)]) {
                       *iop_a_dst++ = wuffs_base__make_token(
                           (((uint64_t)(6356989))
                            << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
@@ -22672,7 +22601,7 @@
                   }
                   if (a_src && a_src->meta.closed) {
                     if (self->private_impl
-                            .f_quirk_enabled_replace_invalid_unicode) {
+                            .f_quirks[(1225364497 - 1225364480)]) {
                       *iop_a_dst++ = wuffs_base__make_token(
                           (((uint64_t)(6356989))
                            << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
@@ -22733,8 +22662,7 @@
                 }
               }
               if ((v_char & 128) != 0) {
-                if (self->private_impl
-                        .f_quirk_enabled_allow_ascii_control_codes) {
+                if (self->private_impl.f_quirks[(1225364480 - 1225364480)]) {
                   *iop_a_dst++ = wuffs_base__make_token(
                       (((uint64_t)((6291456 | ((uint32_t)((v_char & 127))))))
                        << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
@@ -22747,7 +22675,7 @@
                     wuffs_json__error__bad_c0_control_code);
                 goto exit;
               }
-              if (self->private_impl.f_quirk_enabled_replace_invalid_unicode) {
+              if (self->private_impl.f_quirks[(1225364497 - 1225364480)]) {
                 *iop_a_dst++ = wuffs_base__make_token(
                     (((uint64_t)(6356989))
                      << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
@@ -22798,13 +22726,13 @@
               (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
           if (0 == (v_expect & (((uint32_t)(1)) << 8))) {
-            if (self->private_impl.f_quirk_enabled_allow_extra_comma) {
+            if (self->private_impl.f_quirks[(1225364492 - 1225364480)]) {
               v_expect = 4162;
             } else {
               v_expect = 4098;
             }
           } else {
-            if (self->private_impl.f_quirk_enabled_allow_extra_comma) {
+            if (self->private_impl.f_quirks[(1225364492 - 1225364480)]) {
               v_expect = 8114;
             } else {
               v_expect = 7858;
@@ -22852,7 +22780,7 @@
               }
             }
             if (v_number_status == 1) {
-              if (self->private_impl.f_quirk_enabled_allow_inf_nan_numbers) {
+              if (self->private_impl.f_quirks[(1225364493 - 1225364480)]) {
                 if (a_dst) {
                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
                 }
@@ -23065,7 +22993,7 @@
             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
             goto label__outer__continue;
           }
-          if (self->private_impl.f_quirk_enabled_allow_inf_nan_numbers) {
+          if (self->private_impl.f_quirks[(1225364493 - 1225364480)]) {
             if (a_dst) {
               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
             }
@@ -23086,8 +23014,8 @@
             goto label__goto_parsed_a_leaf_value__break;
           }
         } else if (v_class == 12) {
-          if (self->private_impl.f_quirk_enabled_allow_comment_block ||
-              self->private_impl.f_quirk_enabled_allow_comment_line) {
+          if (self->private_impl.f_quirks[(1225364490 - 1225364480)] ||
+              self->private_impl.f_quirks[(1225364491 - 1225364480)]) {
             if (a_dst) {
               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
             }
@@ -23118,7 +23046,7 @@
       v_expect = v_expect_after_value;
     }
   label__outer__break:;
-    if (self->private_impl.f_quirk_enabled_allow_trailing_new_line) {
+    if (self->private_impl.f_quirks[(1225364496 - 1225364480)]) {
       if (a_dst) {
         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
       }
@@ -23395,10 +23323,9 @@
     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
 
     self->private_impl.f_allow_leading_ars =
-        self->private_impl.f_quirk_enabled_allow_leading_ascii_record_separator;
+        self->private_impl.f_quirks[(1225364494 - 1225364480)];
     self->private_impl.f_allow_leading_ubom =
-        self->private_impl
-            .f_quirk_enabled_allow_leading_unicode_byte_order_mark;
+        self->private_impl.f_quirks[(1225364495 - 1225364480)];
   label__0__continue:;
     while (self->private_impl.f_allow_leading_ars ||
            self->private_impl.f_allow_leading_ubom) {
@@ -23526,7 +23453,7 @@
     }
     v_c2 = wuffs_base__load_u16le__no_bounds_check(iop_a_src);
     if ((v_c2 == 10799) &&
-        self->private_impl.f_quirk_enabled_allow_comment_block) {
+        self->private_impl.f_quirks[(1225364490 - 1225364480)]) {
       (iop_a_src += 2, wuffs_base__make_empty_struct());
       v_length = 2;
     label__comment_block__continue:;
@@ -23579,7 +23506,7 @@
         }
       }
     } else if ((v_c2 == 12079) &&
-               self->private_impl.f_quirk_enabled_allow_comment_line) {
+               self->private_impl.f_quirks[(1225364491 - 1225364480)]) {
       (iop_a_src += 2, wuffs_base__make_empty_struct());
       v_length = 2;
     label__comment_line__continue:;
diff --git a/std/gif/decode_config.wuffs b/std/gif/decode_config.wuffs
index cc56b79..8b8dc70 100644
--- a/std/gif/decode_config.wuffs
+++ b/std/gif/decode_config.wuffs
@@ -68,13 +68,7 @@
 	metadata_chunk_length_value : base.u64,
 	metadata_io_position        : base.u64,
 
-	quirk_enabled_delay_num_decoded_frames                         : base.bool,
-	quirk_enabled_first_frame_local_palette_means_black_background : base.bool,
-	quirk_enabled_honor_background_color                           : base.bool,
-	quirk_enabled_ignore_too_much_pixel_data                       : base.bool,
-	quirk_enabled_image_bounds_are_strict                          : base.bool,
-	quirk_enabled_reject_empty_frame                               : base.bool,
-	quirk_enabled_reject_empty_palette                             : base.bool,
+	quirks : array[QUIRKS_COUNT] base.bool,
 
 	delayed_num_decoded_frames         : base.bool,
 	end_of_data                        : base.bool,
@@ -115,21 +109,10 @@
 )
 
 pub func config_decoder.set_quirk_enabled!(quirk: base.u32, enabled: base.bool) {
-	if this.call_sequence == 0 {
-		if args.quirk == QUIRK_DELAY_NUM_DECODED_FRAMES {
-			this.quirk_enabled_delay_num_decoded_frames = args.enabled
-		} else if args.quirk == QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND {
-			this.quirk_enabled_first_frame_local_palette_means_black_background = args.enabled
-		} else if args.quirk == QUIRK_HONOR_BACKGROUND_COLOR {
-			this.quirk_enabled_honor_background_color = args.enabled
-		} else if args.quirk == QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA {
-			this.quirk_enabled_ignore_too_much_pixel_data = args.enabled
-		} else if args.quirk == QUIRK_IMAGE_BOUNDS_ARE_STRICT {
-			this.quirk_enabled_image_bounds_are_strict = args.enabled
-		} else if args.quirk == QUIRK_REJECT_EMPTY_FRAME {
-			this.quirk_enabled_reject_empty_frame = args.enabled
-		} else if args.quirk == QUIRK_REJECT_EMPTY_PALETTE {
-			this.quirk_enabled_reject_empty_palette = args.enabled
+	if (this.call_sequence == 0) and (args.quirk >= QUIRKS_BASE) {
+		args.quirk -= QUIRKS_BASE
+		if args.quirk < QUIRKS_COUNT {
+			this.quirks[args.quirk] = args.enabled
 		}
 	}
 }
@@ -149,7 +132,7 @@
 	// TODO: if this.end_of_data, return an error and/or set dst to zero?
 
 	ffio = not this.gc_has_transparent_index
-	if not this.quirk_enabled_honor_background_color {
+	if not this.quirks[QUIRK_HONOR_BACKGROUND_COLOR - QUIRKS_BASE] {
 		ffio = ffio and
 			(this.frame_rect_x0 == 0) and
 			(this.frame_rect_y0 == 0) and
@@ -301,7 +284,7 @@
 
 		// If the quirk is enabled and the first frame has a local color
 		// palette, its background color is black.
-		if this.quirk_enabled_first_frame_local_palette_means_black_background and
+		if this.quirks[QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND - QUIRKS_BASE] and
 			(this.num_decoded_frame_configs_value == 0) {
 
 			while args.src.available() <= 0,
@@ -356,7 +339,7 @@
 	// Skip the blocks of LZW-compressed data.
 	this.skip_blocks?(src: args.src)
 
-	if this.quirk_enabled_delay_num_decoded_frames {
+	if this.quirks[QUIRK_DELAY_NUM_DECODED_FRAMES - QUIRKS_BASE] {
 		this.delayed_num_decoded_frames = true
 	} else {
 		this.num_decoded_frames_value ~sat+= 1
@@ -469,7 +452,7 @@
 			i += 1
 		} endwhile
 
-		if this.quirk_enabled_honor_background_color {
+		if this.quirks[QUIRK_HONOR_BACKGROUND_COLOR - QUIRKS_BASE] {
 			if (background_color_index <> 0) and
 				((background_color_index as base.u32) < num_palette_entries) {
 
@@ -715,7 +698,7 @@
 	// and the bottom right extent of the first frame. See
 	// test/data/artificial/gif-frame-out-of-bounds.gif.make-artificial.txt for
 	// more discussion.
-	if (this.call_sequence == 0) and (not this.quirk_enabled_image_bounds_are_strict) {
+	if (this.call_sequence == 0) and (not this.quirks[QUIRK_IMAGE_BOUNDS_ARE_STRICT - QUIRKS_BASE]) {
 		this.width = this.width.max(a: this.frame_rect_x1)
 		this.height = this.height.max(a: this.frame_rect_y1)
 	}
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index d00a196..6d38d48 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -83,13 +83,7 @@
 	metadata_chunk_length_value : base.u64,
 	metadata_io_position        : base.u64,
 
-	quirk_enabled_delay_num_decoded_frames                         : base.bool,
-	quirk_enabled_first_frame_local_palette_means_black_background : base.bool,
-	quirk_enabled_honor_background_color                           : base.bool,
-	quirk_enabled_ignore_too_much_pixel_data                       : base.bool,
-	quirk_enabled_image_bounds_are_strict                          : base.bool,
-	quirk_enabled_reject_empty_frame                               : base.bool,
-	quirk_enabled_reject_empty_palette                             : base.bool,
+	quirks : array[QUIRKS_COUNT] base.bool,
 
 	delayed_num_decoded_frames         : base.bool,
 	end_of_data                        : base.bool,
@@ -154,21 +148,10 @@
 )
 
 pub func decoder.set_quirk_enabled!(quirk: base.u32, enabled: base.bool) {
-	if this.call_sequence == 0 {
-		if args.quirk == QUIRK_DELAY_NUM_DECODED_FRAMES {
-			this.quirk_enabled_delay_num_decoded_frames = args.enabled
-		} else if args.quirk == QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND {
-			this.quirk_enabled_first_frame_local_palette_means_black_background = args.enabled
-		} else if args.quirk == QUIRK_HONOR_BACKGROUND_COLOR {
-			this.quirk_enabled_honor_background_color = args.enabled
-		} else if args.quirk == QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA {
-			this.quirk_enabled_ignore_too_much_pixel_data = args.enabled
-		} else if args.quirk == QUIRK_IMAGE_BOUNDS_ARE_STRICT {
-			this.quirk_enabled_image_bounds_are_strict = args.enabled
-		} else if args.quirk == QUIRK_REJECT_EMPTY_FRAME {
-			this.quirk_enabled_reject_empty_frame = args.enabled
-		} else if args.quirk == QUIRK_REJECT_EMPTY_PALETTE {
-			this.quirk_enabled_reject_empty_palette = args.enabled
+	if (this.call_sequence == 0) and (args.quirk >= QUIRKS_BASE) {
+		args.quirk -= QUIRKS_BASE
+		if args.quirk < QUIRKS_COUNT {
+			this.quirks[args.quirk] = args.enabled
 		}
 	}
 }
@@ -188,7 +171,7 @@
 	// TODO: if this.end_of_data, return an error and/or set dst to zero?
 
 	ffio = not this.gc_has_transparent_index
-	if not this.quirk_enabled_honor_background_color {
+	if not this.quirks[QUIRK_HONOR_BACKGROUND_COLOR - QUIRKS_BASE] {
 		ffio = ffio and
 			(this.frame_rect_x0 == 0) and
 			(this.frame_rect_y0 == 0) and
@@ -360,7 +343,7 @@
 
 		// If the quirk is enabled and the first frame has a local color
 		// palette, its background color is black.
-		if this.quirk_enabled_first_frame_local_palette_means_black_background and
+		if this.quirks[QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND - QUIRKS_BASE] and
 			(this.num_decoded_frame_configs_value == 0) {
 
 			while args.src.available() <= 0,
@@ -415,7 +398,7 @@
 	// Skip the blocks of LZW-compressed data.
 	this.skip_blocks?(src: args.src)
 
-	if this.quirk_enabled_delay_num_decoded_frames {
+	if this.quirks[QUIRK_DELAY_NUM_DECODED_FRAMES - QUIRKS_BASE] {
 		this.delayed_num_decoded_frames = true
 	} else {
 		this.num_decoded_frames_value ~sat+= 1
@@ -430,7 +413,7 @@
 	if this.call_sequence <> 4 {
 		this.decode_frame_config?(dst: nullptr, src: args.src)
 	}
-	if this.quirk_enabled_reject_empty_frame and
+	if this.quirks[QUIRK_REJECT_EMPTY_FRAME - QUIRKS_BASE] and
 		((this.frame_rect_x0 == this.frame_rect_x1) or (this.frame_rect_y0 == this.frame_rect_y1)) {
 		return "#bad frame size"
 	}
@@ -544,7 +527,7 @@
 			i += 1
 		} endwhile
 
-		if this.quirk_enabled_honor_background_color {
+		if this.quirks[QUIRK_HONOR_BACKGROUND_COLOR - QUIRKS_BASE] {
 			if (background_color_index <> 0) and
 				((background_color_index as base.u32) < num_palette_entries) {
 
@@ -795,7 +778,7 @@
 	// and the bottom right extent of the first frame. See
 	// test/data/artificial/gif-frame-out-of-bounds.gif.make-artificial.txt for
 	// more discussion.
-	if (this.call_sequence == 0) and (not this.quirk_enabled_image_bounds_are_strict) {
+	if (this.call_sequence == 0) and (not this.quirks[QUIRK_IMAGE_BOUNDS_ARE_STRICT - QUIRKS_BASE]) {
 		this.width = this.width.max(a: this.frame_rect_x1)
 		this.height = this.height.max(a: this.frame_rect_y1)
 	}
@@ -844,7 +827,7 @@
 			this.palettes[1][(4 * i) + 3] = 0xFF
 			i += 1
 		} endwhile
-	} else if this.quirk_enabled_reject_empty_palette and (not this.has_global_palette) {
+	} else if this.quirks[QUIRK_REJECT_EMPTY_PALETTE - QUIRKS_BASE] and (not this.has_global_palette) {
 		return "#bad palette"
 	} else if this.gc_has_transparent_index {
 		this.palettes[1][..].copy_from_slice!(s: this.palettes[0][..])
@@ -1037,7 +1020,7 @@
 		src = args.src[src_ri ..]
 
 		if this.dst_y >= this.frame_rect_y1 {
-			if this.quirk_enabled_ignore_too_much_pixel_data {
+			if this.quirks[QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA - QUIRKS_BASE] {
 				return ok
 			}
 			return base."#too much data"
diff --git a/std/gif/decode_quirks.wuffs b/std/gif/decode_quirks.wuffs
index edb4fb2..b53b696 100644
--- a/std/gif/decode_quirks.wuffs
+++ b/std/gif/decode_quirks.wuffs
@@ -18,6 +18,7 @@
 //
 // The base38 encoding of "gif " is 0x0F_8586. Left shifting by 10 gives
 // 0x3E16_1800.
+pri const QUIRKS_BASE : base.u32 = 0x3E16_1800
 
 // --------
 
@@ -86,3 +87,5 @@
 // When this quirk is enabled, a frame with no explicit palette is rejected,
 // instead of implicitly having a palette with every entry being opaque black.
 pub const QUIRK_REJECT_EMPTY_PALETTE : base.u32 = 0x3E16_1800 | 0x06
+
+pri const QUIRKS_COUNT : base.u32 = 0x07
diff --git a/std/json/common_consts.wuffs b/std/json/common_consts.wuffs
index ddcee1f..7642167 100644
--- a/std/json/common_consts.wuffs
+++ b/std/json/common_consts.wuffs
@@ -66,14 +66,15 @@
 //
 // If the element is non-zero (but the 0x80 bit is not set) then "\i"'s
 // validity depends on the relevant quirk. The element's value is an enum:
-//  - 1: "\a", U+0007, quirk_allow_backslash_a.
-//  - 2: "\e", U+001B, quirk_allow_backslash_e.
-//  - 3: "backslash new_line(not_n)", U+000A, quirk_allow_backslash_new_line.
-//  - 4: "\?", U+003F, quirk_allow_backslash_question_mark.
-//  - 5: "\'", U+0027, quirk_allow_backslash_single_quote.
-//  - 6: "\v", U+000B, quirk_allow_backslash_v.
-//  - 7: "\0", U+0000, quirk_allow_backslash_zero.
-// The U+1234 values are held in LUT_QUIRKY_BACKSLASHES, below.
+//  - 1: "\a", U+0007, QUIRK_ALLOW_BACKSLASH_A.
+//  - 2: "\e", U+001B, QUIRK_ALLOW_BACKSLASH_E.
+//  - 3: "backslash new_line(not_n)", U+000A, QUIRK_ALLOW_BACKSLASH_NEW_LINE.
+//  - 4: "\?", U+003F, QUIRK_ALLOW_BACKSLASH_QUESTION_MARK.
+//  - 5: "\'", U+0027, QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE.
+//  - 6: "\v", U+000B, QUIRK_ALLOW_BACKSLASH_V.
+//  - 7: "\0", U+0000, QUIRK_ALLOW_BACKSLASH_ZERO.
+// The quirk and U+1234 values are held in LUT_QUIRKY_BACKSLASHES_QUIRKS and
+// LUT_QUIRKY_BACKSLASHES_CHARS, below.
 //
 // If the element is zero then "\i" is invalid, or it is a special case, the
 // start of "\x12", "\u1234" or "\U12345678".
@@ -119,10 +120,24 @@
 	// 8     9     A     B     C     D     E     F
 ]
 
-// LUT_QUIRKY_BACKSLASHES is discussed in the LUT_BACKSLASHES comment. The
-// first element (index 0) is not used, but 8 is a round power of 2, so
+// LUT_QUIRKY_BACKSLASHES_QUIRKS is discussed in the LUT_BACKSLASHES comment.
+// The first element (index 0) is not used, but 8 is a round power of 2, so
 // enforcing index-in-bounds is a simple "&7" operation.
-pri const LUT_QUIRKY_BACKSLASHES : array[8] base.u8 = [
+pri const LUT_QUIRKY_BACKSLASHES_QUIRKS : array[8] base.u8[..= 0x09] = [
+	0,
+	0x01,  // (QUIRK_ALLOW_BACKSLASH_A - QUIRKS_BASE) as base.u8,
+	0x03,  // (QUIRK_ALLOW_BACKSLASH_E - QUIRKS_BASE) as base.u8,
+	0x04,  // (QUIRK_ALLOW_BACKSLASH_NEW_LINE - QUIRKS_BASE) as base.u8,
+	0x05,  // (QUIRK_ALLOW_BACKSLASH_QUESTION_MARK - QUIRKS_BASE) as base.u8,
+	0x06,  // (QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE - QUIRKS_BASE) as base.u8,
+	0x07,  // (QUIRK_ALLOW_BACKSLASH_V - QUIRKS_BASE) as base.u8,
+	0x09,  // (QUIRK_ALLOW_BACKSLASH_ZERO - QUIRKS_BASE) as base.u8,
+]
+
+// LUT_QUIRKY_BACKSLASHES_CHARS is discussed in the LUT_BACKSLASHES comment.
+// The first element (index 0) is not used, but 8 is a round power of 2, so
+// enforcing index-in-bounds is a simple "&7" operation.
+pri const LUT_QUIRKY_BACKSLASHES_CHARS : array[8] base.u8 = [
 	0x00, 0x07, 0x1B, 0x0A, 0x3F, 0x27, 0x0B, 0x00,
 ]
 
diff --git a/std/json/decode_json.wuffs b/std/json/decode_json.wuffs
index ef7dc6c..f3b9d7e 100644
--- a/std/json/decode_json.wuffs
+++ b/std/json/decode_json.wuffs
@@ -13,21 +13,7 @@
 // limitations under the License.
 
 pub struct decoder? implements base.token_decoder(
-	// quirk_enabled_allow_backslash_etc, an 8-element array, is indexed by the
-	// same enum as LUT_QUIRKY_BACKSLASHES.
-	quirk_enabled_allow_backslash_etc : array[8] base.bool,
-
-	quirk_enabled_allow_ascii_control_codes             : base.bool,
-	quirk_enabled_allow_backslash_capital_u             : base.bool,
-	quirk_enabled_allow_backslash_x                     : base.bool,
-	quirk_enabled_allow_comment_block                   : base.bool,
-	quirk_enabled_allow_comment_line                    : base.bool,
-	quirk_enabled_allow_extra_comma                     : base.bool,
-	quirk_enabled_allow_inf_nan_numbers                 : base.bool,
-	quirk_enabled_allow_leading_ascii_record_separator  : base.bool,
-	quirk_enabled_allow_leading_unicode_byte_order_mark : base.bool,
-	quirk_enabled_allow_trailing_new_line               : base.bool,
-	quirk_enabled_replace_invalid_unicode               : base.bool,
+	quirks : array[QUIRKS_COUNT] base.bool,
 
 	allow_leading_ars  : base.bool,
 	allow_leading_ubom : base.bool,
@@ -68,42 +54,11 @@
 )
 
 pub func decoder.set_quirk_enabled!(quirk: base.u32, enabled: base.bool) {
-	if args.quirk == QUIRK_ALLOW_ASCII_CONTROL_CODES {
-		this.quirk_enabled_allow_ascii_control_codes = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_A {
-		this.quirk_enabled_allow_backslash_etc[1] = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_CAPITAL_U {
-		this.quirk_enabled_allow_backslash_capital_u = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_E {
-		this.quirk_enabled_allow_backslash_etc[2] = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_NEW_LINE {
-		this.quirk_enabled_allow_backslash_etc[3] = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_QUESTION_MARK {
-		this.quirk_enabled_allow_backslash_etc[4] = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE {
-		this.quirk_enabled_allow_backslash_etc[5] = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_V {
-		this.quirk_enabled_allow_backslash_etc[6] = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_X {
-		this.quirk_enabled_allow_backslash_x = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_BACKSLASH_ZERO {
-		this.quirk_enabled_allow_backslash_etc[7] = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_COMMENT_BLOCK {
-		this.quirk_enabled_allow_comment_block = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_COMMENT_LINE {
-		this.quirk_enabled_allow_comment_line = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_EXTRA_COMMA {
-		this.quirk_enabled_allow_extra_comma = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_INF_NAN_NUMBERS {
-		this.quirk_enabled_allow_inf_nan_numbers = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR {
-		this.quirk_enabled_allow_leading_ascii_record_separator = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK {
-		this.quirk_enabled_allow_leading_unicode_byte_order_mark = args.enabled
-	} else if args.quirk == QUIRK_ALLOW_TRAILING_NEW_LINE {
-		this.quirk_enabled_allow_trailing_new_line = args.enabled
-	} else if args.quirk == QUIRK_REPLACE_INVALID_UNICODE {
-		this.quirk_enabled_replace_invalid_unicode = args.enabled
+	if args.quirk >= QUIRKS_BASE {
+		args.quirk -= QUIRKS_BASE
+		if args.quirk < QUIRKS_COUNT {
+			this.quirks[args.quirk] = args.enabled
+		}
 	}
 }
 
@@ -161,8 +116,8 @@
 		return base."@end of data"
 	}
 
-	if this.quirk_enabled_allow_leading_ascii_record_separator or
-		this.quirk_enabled_allow_leading_unicode_byte_order_mark {
+	if this.quirks[QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR - QUIRKS_BASE] or
+		this.quirks[QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK - QUIRKS_BASE] {
 		this.decode_leading?(dst: args.dst, src: args.src)
 	}
 
@@ -370,11 +325,11 @@
 							continue.string_loop_outer
 
 						} else if backslash <> 0 {
-							if this.quirk_enabled_allow_backslash_etc[backslash & 7] {
+							if this.quirks[LUT_QUIRKY_BACKSLASHES_QUIRKS[backslash & 7]] {
 								args.src.skip32_fast!(actual: 2, worst_case: 2)
 								args.dst.write_simple_token_fast!(
 									value_major: 0,
-									value_minor: 0x60_0000 | (LUT_QUIRKY_BACKSLASHES[backslash & 7] as base.u32),
+									value_minor: 0x60_0000 | (LUT_QUIRKY_BACKSLASHES_CHARS[backslash & 7] as base.u32),
 									continued: 1,
 									length: 2)
 								continue.string_loop_outer
@@ -435,7 +390,7 @@
 								// offset of 4.
 								if args.src.available() < 12 {
 									if args.src.is_closed() {
-										if this.quirk_enabled_replace_invalid_unicode {
+										if this.quirks[QUIRK_REPLACE_INVALID_UNICODE - QUIRKS_BASE] {
 											args.src.skip32_fast!(actual: 6, worst_case: 6)
 											args.dst.write_simple_token_fast!(
 												value_major: 0,
@@ -497,7 +452,7 @@
 								}
 							}
 
-							if this.quirk_enabled_replace_invalid_unicode {
+							if this.quirks[QUIRK_REPLACE_INVALID_UNICODE - QUIRKS_BASE] {
 								if args.src.available() < 6 {
 									return "#internal error: inconsistent I/O"
 								}
@@ -512,7 +467,7 @@
 							// -------- END   backslash-u.
 
 						} else if (c == 'U') and
-							this.quirk_enabled_allow_backslash_capital_u {
+							this.quirks[QUIRK_ALLOW_BACKSLASH_CAPITAL_U - QUIRKS_BASE] {
 							// -------- BEGIN backslash-capital-u.
 							if args.src.available() < 10 {
 								if args.src.is_closed() {
@@ -566,7 +521,7 @@
 									continued: 1,
 									length: 10)
 								continue.string_loop_outer
-							} else if this.quirk_enabled_replace_invalid_unicode {
+							} else if this.quirks[QUIRK_REPLACE_INVALID_UNICODE - QUIRKS_BASE] {
 								args.src.skip32_fast!(actual: 10, worst_case: 10)
 								args.dst.write_simple_token_fast!(
 									value_major: 0,
@@ -578,7 +533,7 @@
 							// -------- END   backslash-capital-u.
 
 						} else if (c == 'x') and
-							this.quirk_enabled_allow_backslash_x {
+							this.quirks[QUIRK_ALLOW_BACKSLASH_X - QUIRKS_BASE] {
 							// -------- BEGIN backslash-x
 							if args.src.available() < 4 {
 								if args.src.is_closed() {
@@ -640,7 +595,7 @@
 								}
 							}
 							if args.src.is_closed() {
-								if this.quirk_enabled_replace_invalid_unicode {
+								if this.quirks[QUIRK_REPLACE_INVALID_UNICODE - QUIRKS_BASE] {
 									args.dst.write_simple_token_fast!(
 										value_major: 0,
 										value_minor: 0x60_FFFD,
@@ -688,7 +643,7 @@
 								}
 							}
 							if args.src.is_closed() {
-								if this.quirk_enabled_replace_invalid_unicode {
+								if this.quirks[QUIRK_REPLACE_INVALID_UNICODE - QUIRKS_BASE] {
 									args.dst.write_simple_token_fast!(
 										value_major: 0,
 										value_minor: 0x60_FFFD,
@@ -741,7 +696,7 @@
 								}
 							}
 							if args.src.is_closed() {
-								if this.quirk_enabled_replace_invalid_unicode {
+								if this.quirks[QUIRK_REPLACE_INVALID_UNICODE - QUIRKS_BASE] {
 									args.dst.write_simple_token_fast!(
 										value_major: 0,
 										value_minor: 0x60_FFFD,
@@ -792,7 +747,7 @@
 						}
 					}
 					if (char & 0x80) <> 0 {
-						if this.quirk_enabled_allow_ascii_control_codes {
+						if this.quirks[QUIRK_ALLOW_ASCII_CONTROL_CODES - QUIRKS_BASE] {
 							args.dst.write_simple_token_fast!(
 								value_major: 0,
 								value_minor: 0x60_0000 | ((char & 0x7F) as base.u32),
@@ -803,7 +758,7 @@
 						}
 						return "#bad C0 control code"
 					}
-					if this.quirk_enabled_replace_invalid_unicode {
+					if this.quirks[QUIRK_REPLACE_INVALID_UNICODE - QUIRKS_BASE] {
 						args.dst.write_simple_token_fast!(
 							value_major: 0,
 							value_minor: 0x60_FFFD,
@@ -859,13 +814,13 @@
 			// What's valid after a comma depends on whether or not we're in an
 			// array or an object.
 			if 0 == (expect & ((1 as base.u32) << CLASS_CLOSE_SQUARE_BRACKET)) {
-				if this.quirk_enabled_allow_extra_comma {
+				if this.quirks[QUIRK_ALLOW_EXTRA_COMMA - QUIRKS_BASE] {
 					expect = 0x1042  // 0x1042 is EXPECT_STRING | EXPECT_CLOSE_CURLY_BRACE.
 				} else {
 					expect = 0x1002  // 0x1002 is EXPECT_STRING.
 				}
 			} else {
-				if this.quirk_enabled_allow_extra_comma {
+				if this.quirks[QUIRK_ALLOW_EXTRA_COMMA - QUIRKS_BASE] {
 					expect = 0x1FB2  // 0x0FB2 is EXPECT_VALUE | EXPECT_CLOSE_SQUARE_BRACKET.
 				} else {
 					expect = 0x1EB2  // 0x0EB2 is EXPECT_VALUE.
@@ -915,7 +870,7 @@
 				} endwhile
 
 				if number_status == 1 {
-					if this.quirk_enabled_allow_inf_nan_numbers {
+					if this.quirks[QUIRK_ALLOW_INF_NAN_NUMBERS - QUIRKS_BASE] {
 						this.decode_inf_nan?(dst: args.dst, src: args.src)
 						break
 					}
@@ -1110,13 +1065,14 @@
 				continue.outer
 			}
 
-			if this.quirk_enabled_allow_inf_nan_numbers {
+			if this.quirks[QUIRK_ALLOW_INF_NAN_NUMBERS - QUIRKS_BASE] {
 				this.decode_inf_nan?(dst: args.dst, src: args.src)
 				break.goto_parsed_a_leaf_value
 			}
 
 		} else if class == CLASS_COMMENT {
-			if this.quirk_enabled_allow_comment_block or this.quirk_enabled_allow_comment_line {
+			if this.quirks[QUIRK_ALLOW_COMMENT_BLOCK - QUIRKS_BASE] or
+				this.quirks[QUIRK_ALLOW_COMMENT_LINE - QUIRKS_BASE] {
 				this.decode_comment?(dst: args.dst, src: args.src)
 				continue.outer
 			}
@@ -1133,7 +1089,7 @@
 		expect = expect_after_value
 	} endwhile.outer
 
-	if this.quirk_enabled_allow_trailing_new_line {
+	if this.quirks[QUIRK_ALLOW_TRAILING_NEW_LINE - QUIRKS_BASE] {
 		this.decode_trailing_new_line?(dst: args.dst, src: args.src)
 	}
 
@@ -1319,8 +1275,10 @@
 	var c : base.u8
 	var u : base.u32
 
-	this.allow_leading_ars = this.quirk_enabled_allow_leading_ascii_record_separator
-	this.allow_leading_ubom = this.quirk_enabled_allow_leading_unicode_byte_order_mark
+	this.allow_leading_ars =
+		this.quirks[QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR - QUIRKS_BASE]
+	this.allow_leading_ubom =
+		this.quirks[QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK - QUIRKS_BASE]
 
 	while this.allow_leading_ars or this.allow_leading_ubom {
 		if args.dst.available() <= 0 {
@@ -1382,7 +1340,7 @@
 	} endwhile
 	c2 = args.src.peek_u16le()
 
-	if (c2 == '/*'le) and this.quirk_enabled_allow_comment_block {
+	if (c2 == '/*'le) and this.quirks[QUIRK_ALLOW_COMMENT_BLOCK - QUIRKS_BASE] {
 		args.src.skip32_fast!(actual: 2, worst_case: 2)
 		length = 2
 
@@ -1437,7 +1395,7 @@
 			} endwhile
 		} endwhile.comment_block
 
-	} else if (c2 == '//'le) and this.quirk_enabled_allow_comment_line {
+	} else if (c2 == '//'le) and this.quirks[QUIRK_ALLOW_COMMENT_LINE - QUIRKS_BASE] {
 		args.src.skip32_fast!(actual: 2, worst_case: 2)
 		length = 2
 
diff --git a/std/json/decode_quirks.wuffs b/std/json/decode_quirks.wuffs
index 3d6b01d..cc03ed6 100644
--- a/std/json/decode_quirks.wuffs
+++ b/std/json/decode_quirks.wuffs
@@ -18,6 +18,7 @@
 //
 // The base38 encoding of "json" is 0x12_4265. Left shifting by 10 gives
 // 0x4909_9400.
+pri const QUIRKS_BASE : base.u32 = 0x4909_9400
 
 // --------
 
@@ -204,3 +205,5 @@
 // unit that is an invalid Unicode code point (i.e. in the range U+D800 ..=
 // U+DFFF or above U+10FFFF) is similarly replaced with U+FFFD.
 pub const QUIRK_REPLACE_INVALID_UNICODE : base.u32 = 0x4909_9400 | 0x11
+
+pri const QUIRKS_COUNT : base.u32 = 0x12