Have io_{reader,writer}.mark use io0_etc
diff --git a/internal/cgen/base/io-private.h b/internal/cgen/base/io-private.h
index e19940c..a9b4ca1 100644
--- a/internal/cgen/base/io-private.h
+++ b/internal/cgen/base/io-private.h
@@ -164,6 +164,8 @@
 wuffs_base__io_reader__set(wuffs_base__io_buffer** o,
                            wuffs_base__io_buffer* b,
                            uint8_t** ptr_iop_r,
+                           uint8_t** ptr_io0_r,
+                           uint8_t** ptr_io1_r,
                            uint8_t** ptr_io2_r,
                            wuffs_base__slice_u8 data) {
   b->data = data;
@@ -174,6 +176,8 @@
 
   *o = b;
   *ptr_iop_r = data.ptr;
+  *ptr_io0_r = data.ptr;
+  *ptr_io1_r = data.ptr;
   *ptr_io2_r = data.ptr + data.len;
 
   wuffs_base__empty_struct ret;
@@ -195,6 +199,8 @@
 wuffs_base__io_writer__set(wuffs_base__io_buffer** o,
                            wuffs_base__io_buffer* b,
                            uint8_t** ptr_iop_w,
+                           uint8_t** ptr_io0_w,
+                           uint8_t** ptr_io1_w,
                            uint8_t** ptr_io2_w,
                            wuffs_base__slice_u8 data) {
   b->data = data;
@@ -205,6 +211,8 @@
 
   *o = b;
   *ptr_iop_w = data.ptr;
+  *ptr_io0_w = data.ptr;
+  *ptr_io1_w = data.ptr;
   *ptr_io2_w = data.ptr + data.len;
 
   wuffs_base__empty_struct ret;
diff --git a/internal/cgen/builtin.go b/internal/cgen/builtin.go
index 17d0e10..5d5d06a 100644
--- a/internal/cgen/builtin.go
+++ b/internal/cgen/builtin.go
@@ -149,8 +149,8 @@
 		return nil
 
 	case t.IDMark:
-		b.printf("(%s%s ? ((uint64_t)(iop_%s%s - %s%s->data.ptr)) : 0)",
-			prefix, name, prefix, name, prefix, name)
+		b.printf("(%s%s ? ((uint64_t)(%s%s%s - %s%s%s)) : 0)",
+			prefix, name, iopPrefix, prefix, name, io0Prefix, prefix, name)
 		return nil
 
 	case t.IDPosition:
@@ -258,7 +258,7 @@
 		return nil
 
 	case t.IDMark:
-		b.printf("(a_dst ? ((uint64_t)(iop_a_dst - a_dst->data.ptr)) : 0)")
+		b.printf("(a_dst ? ((uint64_t)(iop_a_dst - io0_a_dst)) : 0)")
 		return nil
 
 	case t.IDPosition:
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index 13e1aea..a2c6e06 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -167,8 +167,8 @@
 	"    n = (size_t)(length);\n  }\n  // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that\n  // is mostly because 3 is the minimum length for the deflate format. This\n  // function implementation shouldn't overfit to that one format. Perhaps the\n  // copy_n_from_history Wuffs method should also take an unroll hint argument,\n  // and the cgen can look if that argument is the constant expression '3'.\n  //\n  // See also wuffs_base__io_writer__copy_n_from_history_fast below.\n  //\n  // Alternatively, or additionally, have a sloppy_copy_n_from_history method\n  // that copies 8 bytes at a time, possibly writing more than length bytes?\n  for (; n >= 3; n -= 3) {\n    *p++ = *q++;\n    *p++ = *q++;\n    *p++ = *q++;\n  }\n  for (; n; n--) {\n    *p++ = *q++;\n  }\n  *ptr_iop_w = p;\n  return length;\n}\n\n// wuffs_base__io_writer__copy_n_from_history_fast is like the\n// wuffs_base__io_writer__copy_n_from_history function above, but has stronger\n// pre-conditions. The caller needs to prove that:\n//  - distance >  " +
 	"0\n//  - distance <= (*ptr_iop_w - io1_w)\n//  - length   <= (io2_w      - *ptr_iop_w)\nstatic inline uint32_t  //\nwuffs_base__io_writer__copy_n_from_history_fast(uint8_t** ptr_iop_w,\n                                                uint8_t* io1_w,\n                                                uint8_t* io2_w,\n                                                uint32_t length,\n                                                uint32_t distance) {\n  uint8_t* p = *ptr_iop_w;\n  uint8_t* q = p - distance;\n  uint32_t n = length;\n  for (; n >= 3; n -= 3) {\n    *p++ = *q++;\n    *p++ = *q++;\n    *p++ = *q++;\n  }\n  for (; n; n--) {\n    *p++ = *q++;\n  }\n  *ptr_iop_w = p;\n  return length;\n}\n\nstatic inline uint32_t  //\nwuffs_base__io_writer__copy_n_from_reader(uint8_t** ptr_iop_w,\n                                          uint8_t* io2_w,\n                                          uint32_t length,\n                                          uint8_t** ptr_iop_r,\n                                          uint8_t* io2_r) {\n  uint8_t* i" +
 	"op_w = *ptr_iop_w;\n  size_t n = length;\n  if (n > ((size_t)(io2_w - iop_w))) {\n    n = (size_t)(io2_w - iop_w);\n  }\n  uint8_t* iop_r = *ptr_iop_r;\n  if (n > ((size_t)(io2_r - iop_r))) {\n    n = (size_t)(io2_r - iop_r);\n  }\n  if (n > 0) {\n    memmove(iop_w, iop_r, n);\n    *ptr_iop_w += n;\n    *ptr_iop_r += n;\n  }\n  return (uint32_t)(n);\n}\n\nstatic inline uint64_t  //\nwuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,\n                                       uint8_t* io2_w,\n                                       wuffs_base__slice_u8 src) {\n  uint8_t* iop_w = *ptr_iop_w;\n  size_t n = src.len;\n  if (n > ((size_t)(io2_w - iop_w))) {\n    n = (size_t)(io2_w - iop_w);\n  }\n  if (n > 0) {\n    memmove(iop_w, src.ptr, n);\n    *ptr_iop_w += n;\n  }\n  return (uint64_t)(n);\n}\n\nstatic inline uint32_t  //\nwuffs_base__io_writer__copy_n_from_slice(uint8_t** ptr_iop_w,\n                                         uint8_t* io2_w,\n                                         uint32_t length,\n                                         w" +
-	"uffs_base__slice_u8 src) {\n  uint8_t* iop_w = *ptr_iop_w;\n  size_t n = src.len;\n  if (n > length) {\n    n = length;\n  }\n  if (n > ((size_t)(io2_w - iop_w))) {\n    n = (size_t)(io2_w - iop_w);\n  }\n  if (n > 0) {\n    memmove(iop_w, src.ptr, n);\n    *ptr_iop_w += n;\n  }\n  return (uint32_t)(n);\n}\n\nstatic inline wuffs_base__empty_struct  //\nwuffs_base__io_reader__set(wuffs_base__io_buffer** o,\n                           wuffs_base__io_buffer* b,\n                           uint8_t** ptr_iop_r,\n                           uint8_t** ptr_io2_r,\n                           wuffs_base__slice_u8 data) {\n  b->data = data;\n  b->meta.wi = data.len;\n  b->meta.ri = 0;\n  b->meta.pos = 0;\n  b->meta.closed = false;\n\n  *o = b;\n  *ptr_iop_r = data.ptr;\n  *ptr_io2_r = data.ptr + data.len;\n\n  wuffs_base__empty_struct ret;\n  ret.private_impl = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__io_reader__take(uint8_t** ptr_iop_r, uint8_t* io2_r, uint64_t n) {\n  if (n <= ((size_t)(io2_r - *ptr_iop_r))) {\n    uint8_t*" +
-	" p = *ptr_iop_r;\n    *ptr_iop_r += n;\n    return wuffs_base__make_slice_u8(p, n);\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\nstatic inline wuffs_base__empty_struct  //\nwuffs_base__io_writer__set(wuffs_base__io_buffer** o,\n                           wuffs_base__io_buffer* b,\n                           uint8_t** ptr_iop_w,\n                           uint8_t** ptr_io2_w,\n                           wuffs_base__slice_u8 data) {\n  b->data = data;\n  b->meta.wi = 0;\n  b->meta.ri = 0;\n  b->meta.pos = 0;\n  b->meta.closed = false;\n\n  *o = b;\n  *ptr_iop_w = data.ptr;\n  *ptr_io2_w = data.ptr + data.len;\n\n  wuffs_base__empty_struct ret;\n  ret.private_impl = 0;\n  return ret;\n}\n\n" +
+	"uffs_base__slice_u8 src) {\n  uint8_t* iop_w = *ptr_iop_w;\n  size_t n = src.len;\n  if (n > length) {\n    n = length;\n  }\n  if (n > ((size_t)(io2_w - iop_w))) {\n    n = (size_t)(io2_w - iop_w);\n  }\n  if (n > 0) {\n    memmove(iop_w, src.ptr, n);\n    *ptr_iop_w += n;\n  }\n  return (uint32_t)(n);\n}\n\nstatic inline wuffs_base__empty_struct  //\nwuffs_base__io_reader__set(wuffs_base__io_buffer** o,\n                           wuffs_base__io_buffer* b,\n                           uint8_t** ptr_iop_r,\n                           uint8_t** ptr_io0_r,\n                           uint8_t** ptr_io1_r,\n                           uint8_t** ptr_io2_r,\n                           wuffs_base__slice_u8 data) {\n  b->data = data;\n  b->meta.wi = data.len;\n  b->meta.ri = 0;\n  b->meta.pos = 0;\n  b->meta.closed = false;\n\n  *o = b;\n  *ptr_iop_r = data.ptr;\n  *ptr_io0_r = data.ptr;\n  *ptr_io1_r = data.ptr;\n  *ptr_io2_r = data.ptr + data.len;\n\n  wuffs_base__empty_struct ret;\n  ret.private_impl = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__sli" +
+	"ce_u8  //\nwuffs_base__io_reader__take(uint8_t** ptr_iop_r, uint8_t* io2_r, uint64_t n) {\n  if (n <= ((size_t)(io2_r - *ptr_iop_r))) {\n    uint8_t* p = *ptr_iop_r;\n    *ptr_iop_r += n;\n    return wuffs_base__make_slice_u8(p, n);\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\nstatic inline wuffs_base__empty_struct  //\nwuffs_base__io_writer__set(wuffs_base__io_buffer** o,\n                           wuffs_base__io_buffer* b,\n                           uint8_t** ptr_iop_w,\n                           uint8_t** ptr_io0_w,\n                           uint8_t** ptr_io1_w,\n                           uint8_t** ptr_io2_w,\n                           wuffs_base__slice_u8 data) {\n  b->data = data;\n  b->meta.wi = 0;\n  b->meta.ri = 0;\n  b->meta.pos = 0;\n  b->meta.closed = false;\n\n  *o = b;\n  *ptr_iop_w = data.ptr;\n  *ptr_io0_w = data.ptr;\n  *ptr_io1_w = data.ptr;\n  *ptr_io2_w = data.ptr + data.len;\n\n  wuffs_base__empty_struct ret;\n  ret.private_impl = 0;\n  return ret;\n}\n\n" +
 	"" +
 	"// ---------------- I/O (Utility)\n\n#define wuffs_base__utility__null_io_reader wuffs_base__null_io_reader\n#define wuffs_base__utility__null_io_writer wuffs_base__null_io_writer\n" +
 	""
diff --git a/internal/cgen/statement.go b/internal/cgen/statement.go
index 420ac2a..1cd06f0 100644
--- a/internal/cgen/statement.go
+++ b/internal/cgen/statement.go
@@ -277,12 +277,17 @@
 			b.printf("uint8_t *%s%d_%s%s%s = %s%s%s;\n",
 				oPrefix, ioBindNum, iopPrefix, prefix, name, iopPrefix, prefix, name)
 			b.printf("uint8_t *%s%d_%s%s%s = %s%s%s;\n",
+				oPrefix, ioBindNum, io0Prefix, prefix, name, io0Prefix, prefix, name)
+			b.printf("uint8_t *%s%d_%s%s%s = %s%s%s;\n",
+				oPrefix, ioBindNum, io1Prefix, prefix, name, io1Prefix, prefix, name)
+			b.printf("uint8_t *%s%d_%s%s%s = %s%s%s;\n",
 				oPrefix, ioBindNum, io2Prefix, prefix, name, io2Prefix, prefix, name)
 		}
 
 		if n.Keyword() == t.IDIOBind {
-			b.printf("wuffs_base__io_%s__set(&%s%s, &%s%s, &%s%s%s, &%s%s%s,",
-				cTyp, prefix, name, uPrefix, name, iopPrefix, prefix, name, io2Prefix, prefix, name)
+			b.printf("wuffs_base__io_%s__set(&%s%s, &%s%s, &%s%s%s, &%s%s%s, &%s%s%s, &%s%s%s,",
+				cTyp, prefix, name, uPrefix, name, iopPrefix, prefix, name,
+				io0Prefix, prefix, name, io1Prefix, prefix, name, io2Prefix, prefix, name)
 			if err := g.writeExpr(b, n.Arg1(), 0); err != nil {
 				return err
 			}
@@ -318,6 +323,10 @@
 			b.printf("%s%s%s = %s%d_%s%s%s;\n",
 				iopPrefix, prefix, name, oPrefix, ioBindNum, iopPrefix, prefix, name)
 			b.printf("%s%s%s = %s%d_%s%s%s;\n",
+				io0Prefix, prefix, name, oPrefix, ioBindNum, io0Prefix, prefix, name)
+			b.printf("%s%s%s = %s%d_%s%s%s;\n",
+				io1Prefix, prefix, name, oPrefix, ioBindNum, io1Prefix, prefix, name)
+			b.printf("%s%s%s = %s%d_%s%s%s;\n",
 				io2Prefix, prefix, name, oPrefix, ioBindNum, io2Prefix, prefix, name)
 		}
 	}
diff --git a/internal/cgen/var.go b/internal/cgen/var.go
index 14416b4..04c2257 100644
--- a/internal/cgen/var.go
+++ b/internal/cgen/var.go
@@ -299,6 +299,8 @@
 			preName := vPrefix + name
 			// TODO: io1_etc variables?
 			b.printf("uint8_t* %s%s WUFFS_BASE__POTENTIALLY_UNUSED = NULL;\n", iopPrefix, preName)
+			b.printf("uint8_t* %s%s WUFFS_BASE__POTENTIALLY_UNUSED = NULL;\n", io0Prefix, preName)
+			b.printf("uint8_t* %s%s WUFFS_BASE__POTENTIALLY_UNUSED = NULL;\n", io1Prefix, preName)
 			b.printf("uint8_t* %s%s WUFFS_BASE__POTENTIALLY_UNUSED = NULL;\n", io2Prefix, preName)
 		}
 	}
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 6c1136a..6a146a1 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -4614,6 +4614,8 @@
 wuffs_base__io_reader__set(wuffs_base__io_buffer** o,
                            wuffs_base__io_buffer* b,
                            uint8_t** ptr_iop_r,
+                           uint8_t** ptr_io0_r,
+                           uint8_t** ptr_io1_r,
                            uint8_t** ptr_io2_r,
                            wuffs_base__slice_u8 data) {
   b->data = data;
@@ -4624,6 +4626,8 @@
 
   *o = b;
   *ptr_iop_r = data.ptr;
+  *ptr_io0_r = data.ptr;
+  *ptr_io1_r = data.ptr;
   *ptr_io2_r = data.ptr + data.len;
 
   wuffs_base__empty_struct ret;
@@ -4645,6 +4649,8 @@
 wuffs_base__io_writer__set(wuffs_base__io_buffer** o,
                            wuffs_base__io_buffer* b,
                            uint8_t** ptr_iop_w,
+                           uint8_t** ptr_io0_w,
+                           uint8_t** ptr_io1_w,
                            uint8_t** ptr_io2_w,
                            wuffs_base__slice_u8 data) {
   b->data = data;
@@ -4655,6 +4661,8 @@
 
   *o = b;
   *ptr_iop_w = data.ptr;
+  *ptr_io0_w = data.ptr;
+  *ptr_io1_w = data.ptr;
   *ptr_io2_w = data.ptr + data.len;
 
   wuffs_base__empty_struct ret;
@@ -6416,7 +6424,7 @@
     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
 
     while (true) {
-      v_mark = (a_dst ? ((uint64_t)(iop_a_dst - a_dst->data.ptr)) : 0);
+      v_mark = (a_dst ? ((uint64_t)(iop_a_dst - io0_a_dst)) : 0);
       {
         if (a_dst) {
           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
@@ -10788,6 +10796,8 @@
   wuffs_base__io_buffer u_r WUFFS_BASE__POTENTIALLY_UNUSED =
       wuffs_base__null_io_buffer();
   uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+  uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+  uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
   uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
   uint64_t v_mark = 0;
   wuffs_base__status v_lzw_status = NULL;
@@ -10885,15 +10895,17 @@
         {
           wuffs_base__io_buffer* o_0_v_r = v_r;
           uint8_t* o_0_iop_v_r = iop_v_r;
+          uint8_t* o_0_io0_v_r = io0_v_r;
+          uint8_t* o_0_io1_v_r = io1_v_r;
           uint8_t* o_0_io2_v_r = io2_v_r;
           wuffs_base__io_reader__set(
-              &v_r, &u_r, &iop_v_r, &io2_v_r,
+              &v_r, &u_r, &iop_v_r, &io0_v_r, &io1_v_r, &io2_v_r,
               wuffs_base__slice_u8__subslice_ij(
                   wuffs_base__make_slice_u8(self->private_data.f_compressed,
                                             4096),
                   self->private_impl.f_compressed_ri,
                   self->private_impl.f_compressed_wi));
-          v_mark = (v_r ? ((uint64_t)(iop_v_r - v_r->data.ptr)) : 0);
+          v_mark = (v_r ? ((uint64_t)(iop_v_r - io0_v_r)) : 0);
           {
             u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
             wuffs_base__status t_1 = wuffs_lzw__decoder__decode_io_writer(
@@ -10910,6 +10922,8 @@
                    : 0));
           v_r = o_0_v_r;
           iop_v_r = o_0_iop_v_r;
+          io0_v_r = o_0_io0_v_r;
+          io1_v_r = o_0_io1_v_r;
           io2_v_r = o_0_io2_v_r;
         }
         v_uncompressed = wuffs_lzw__decoder__flush(&self->private_data.f_lzw);
@@ -11465,7 +11479,7 @@
       goto exit;
     }
     while (true) {
-      v_mark = (a_dst ? ((uint64_t)(iop_a_dst - a_dst->data.ptr)) : 0);
+      v_mark = (a_dst ? ((uint64_t)(iop_a_dst - io0_a_dst)) : 0);
       {
         if (a_dst) {
           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
@@ -11828,7 +11842,7 @@
       goto exit;
     }
     while (true) {
-      v_mark = (a_dst ? ((uint64_t)(iop_a_dst - a_dst->data.ptr)) : 0);
+      v_mark = (a_dst ? ((uint64_t)(iop_a_dst - io0_a_dst)) : 0);
       {
         if (a_dst) {
           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));