lang: add io_reader.peek_u8_at
diff --git a/internal/cgen/builtin.go b/internal/cgen/builtin.go
index cf33171..18e2e99 100644
--- a/internal/cgen/builtin.go
+++ b/internal/cgen/builtin.go
@@ -253,6 +253,14 @@
b.writeb(')')
return nil
+ case t.IDPeekU8At:
+ b.printf("%s%s[", iopPrefix, recvName)
+ if err := g.writeExpr(b, args[0].AsArg().Value(), false, depth); err != nil {
+ return err
+ }
+ b.writeb(']')
+ return nil
+
case t.IDPeekU64LEAt:
b.printf("wuffs_base__peek_u64le__no_bounds_check(%s%s + ", iopPrefix, recvName)
if err := g.writeExpr(b, args[0].AsArg().Value(), false, depth); err != nil {
diff --git a/lang/builtin/builtin.go b/lang/builtin/builtin.go
index da6a596..6dcb58a 100644
--- a/lang/builtin/builtin.go
+++ b/lang/builtin/builtin.go
@@ -510,8 +510,9 @@
"io_reader.peek_u64le() u64",
// As an implementation restriction, we require that offset has a constant
- // value. The (0x1_0000 - sizeof(u64)) limit is arbitrary, but high enough
+ // value. The (0x1_0000 - sizeof(uxx)) limit is arbitrary, but high enough
// in practice.
+ "io_reader.peek_u8_at(offset: u32[..= 0xFFFF]) u8",
"io_reader.peek_u64le_at(offset: u32[..= 0xFFF8]) u64",
"io_reader.count_since(mark: u64) u64",
diff --git a/lang/check/bounds.go b/lang/check/bounds.go
index 25ca22c..4811cde 100644
--- a/lang/check/bounds.go
+++ b/lang/check/bounds.go
@@ -1259,16 +1259,20 @@
advanceExpr, update = actual, true
}
- } else if method == t.IDPeekU64LEAt {
+ } else if (method == t.IDPeekU8At) || (method == t.IDPeekU64LEAt) {
args := n.Args()
if len(args) != 1 {
- return bounds{}, fmt.Errorf("check: internal error: bad peek_u64le_at arguments")
+ return bounds{}, fmt.Errorf("check: internal error: bad peek_uxx_at arguments")
}
offset := args[0].AsArg().Value()
if offset.ConstValue() == nil {
- return bounds{}, fmt.Errorf("check: peek_u64le_at offset is not a constant value")
+ return bounds{}, fmt.Errorf("check: peek_uxx_at offset is not a constant value")
}
- advance, update = big.NewInt(8), false
+ adv := int64(1)
+ if method == t.IDPeekU64LEAt {
+ adv = 8
+ }
+ advance, update = big.NewInt(adv), false
advance.Add(advance, offset.ConstValue())
} else if method >= t.IDPeekU8 {
diff --git a/lang/token/list.go b/lang/token/list.go
index 98cf435..8daf2e6 100644
--- a/lang/token/list.go
+++ b/lang/token/list.go
@@ -570,6 +570,7 @@
IDPeekUndoByte = ID(0x1A0)
IDPeekU8 = ID(0x1A1)
+ IDPeekU8At = ID(0x1A2)
IDPeekU8AsU16 = ID(0x1A5)
IDPeekU16BE = ID(0x1A6)
@@ -1020,6 +1021,7 @@
IDPeekUndoByte: "peek_undo_byte",
IDPeekU8: "peek_u8",
+ IDPeekU8At: "peek_u8_at",
IDPeekU8AsU16: "peek_u8_as_u16",
IDPeekU16BE: "peek_u16be",
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index d5836d3..320e924 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -51400,7 +51400,7 @@
} else if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) {
break;
}
- v_c8 = ((uint8_t)(((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u))));
+ v_c8 = iop_a_src[1u];
if (v_c8 == 0u) {
self->private_data.f_bitstream_buffer[v_wi] = 255u;
v_wi += 1u;
diff --git a/std/jpeg/decode_jpeg.wuffs b/std/jpeg/decode_jpeg.wuffs
index ba9e136..40ee683 100644
--- a/std/jpeg/decode_jpeg.wuffs
+++ b/std/jpeg/decode_jpeg.wuffs
@@ -1749,7 +1749,7 @@
break
}
- c8 = (args.src.peek_u16le() >> 8) as base.u8
+ c8 = args.src.peek_u8_at(offset: 1)
if c8 == 0x00 {
this.bitstream_buffer[wi] = 0xFF
wi += 1