vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
struct Utf8ValidateParams {
    input_len: u32,
    reserved0: u32,
    reserved1: u32,
    reserved2: u32,
}

@group(0) @binding(0) var<uniform> params: Utf8ValidateParams;
@group(0) @binding(1) var<storage, read> input_words: array<u32>;
@group(0) @binding(2) var<storage, read_write> result: array<u32>;

fn decode_utf8_cont(index: u32) -> bool {
    if (index >= params.input_len) {
        return false;
    }
    let byte = vyre_packed_byte(&input_words, index);
    return byte >= 128u && byte <= 191u;
}

@compute @workgroup_size(1, 1, 1)
fn decode_utf8_validate(@builtin(global_invocation_id) id: vec3<u32>) {
    if (id.x != 0u) {
        return;
    }
    var index = 0u;
    loop {
        if (index >= params.input_len) {
            break;
        }
        let byte = vyre_packed_byte(&input_words, index);
        if (byte <= 127u) {
            index = index + 1u;
            continue;
        }
        if (byte >= 194u && byte <= 223u) {
            if (!decode_utf8_cont(index + 1u)) { result[0] = 0u; return; }
            index = index + 2u;
            continue;
        }
        if (byte == 224u) {
            let b1 = select(0u, vyre_packed_byte(&input_words, index + 1u), index + 1u < params.input_len);
            if (!(b1 >= 160u && b1 <= 191u) || !decode_utf8_cont(index + 2u)) { result[0] = 0u; return; }
            index = index + 3u;
            continue;
        }
        if ((byte >= 225u && byte <= 236u) || (byte >= 238u && byte <= 239u)) {
            if (!decode_utf8_cont(index + 1u) || !decode_utf8_cont(index + 2u)) { result[0] = 0u; return; }
            index = index + 3u;
            continue;
        }
        if (byte == 237u) {
            let b1 = select(0u, vyre_packed_byte(&input_words, index + 1u), index + 1u < params.input_len);
            if (!(b1 >= 128u && b1 <= 159u) || !decode_utf8_cont(index + 2u)) { result[0] = 0u; return; }
            index = index + 3u;
            continue;
        }
        if (byte == 240u) {
            let b1 = select(0u, vyre_packed_byte(&input_words, index + 1u), index + 1u < params.input_len);
            if (!(b1 >= 144u && b1 <= 191u) || !decode_utf8_cont(index + 2u) || !decode_utf8_cont(index + 3u)) { result[0] = 0u; return; }
            index = index + 4u;
            continue;
        }
        if (byte >= 241u && byte <= 243u) {
            if (!decode_utf8_cont(index + 1u) || !decode_utf8_cont(index + 2u) || !decode_utf8_cont(index + 3u)) { result[0] = 0u; return; }
            index = index + 4u;
            continue;
        }
        if (byte == 244u) {
            let b1 = select(0u, vyre_packed_byte(&input_words, index + 1u), index + 1u < params.input_len);
            if (!(b1 >= 128u && b1 <= 143u) || !decode_utf8_cont(index + 2u) || !decode_utf8_cont(index + 3u)) { result[0] = 0u; return; }
            index = index + 4u;
            continue;
        }
        result[0] = 0u;
        return;
    }
    result[0] = 1u;
}