Skip to content
io
view

view

Mojo module 🡭

view

A pointer that knows, in a checked build, how far it may reach.

The decoders’ hot loops read and write through raw pointers, since a bounds check per byte is what makes list[i] slow, and every index is argued in bounds by the length checks around the loop. That argument is what a fuzzer cannot see: a read past a buffer through a raw pointer does not fault, it returns whatever byte is at that address, until the address is unmapped. So the loops go through these two views instead. In the production build a view is the pointer and nothing else, and every method is the pointer operation it wraps. In a build with -D CANVAS_CHECKED_READS (pixi run fuzz passes it), a view also carries how many elements lie past it, and an access outside that aborts the process naming the index, which is what turns a silent read into a finding (#430).

_ReadView is over a borrowed List; _WriteView over a mutable one, and reads too, since a filter reads the bytes it just wrote. offset(k) is a view over the tail from k, which is how a row or a block gets its own pointer. load and store are the vector forms, W elements from i, for element types that are scalars.

A view is only ever built from a List that outlives it; the origin parameter makes the compiler check that. In the production build the length field is dead, and the loops compile as they did with the raw pointer – benchmarks/micro_canvas.mojo has the decoder rows that pin it.

Aliases

  • CHECKED_READS = is_defined[StringSpan("CANVAS_CHECKED_READS")](): True in a build made with -D CANVAS_CHECKED_READS: every view access is bounds-checked and aborts on a miss. False, the default, compiles the checks away.