Repro
function make(n: number) {
const u = new Uint8Array(n);
console.log('n=' + n + ' length=' + u.length);
}
make(100);
make(1024);
Expected
n=100 length=100
n=1024 length=1024
Actual (Perry 0.5.30)
n=100 length=0
n=1024 length=0
Likely cause
In crates/perry-codegen/src/expr.rs, Expr::Uint8ArrayNew has fast paths for the literal cases Expr::Integer(n) and Expr::Number(n) (routed to js_buffer_alloc), but the catch-all Some(e) => … arm falls through to js_uint8array_from_array, which treats the number as an ArrayHeader* pointer and silently yields a zero-length buffer.
Workaround
Buffer.alloc(n) works with computed/variable sizes. new Uint8Array(<literal>) works too.
Related
The pair for writes (u8[i] = v being a silent no-op) was a similar codegen stub in Expr::Uint8ArraySet; fixed separately.
Repro
Expected
Actual (Perry 0.5.30)
Likely cause
In
crates/perry-codegen/src/expr.rs,Expr::Uint8ArrayNewhas fast paths for the literal casesExpr::Integer(n)andExpr::Number(n)(routed tojs_buffer_alloc), but the catch-allSome(e) => …arm falls through tojs_uint8array_from_array, which treats the number as anArrayHeader*pointer and silently yields a zero-length buffer.Workaround
Buffer.alloc(n)works with computed/variable sizes.new Uint8Array(<literal>)works too.Related
The pair for writes (
u8[i] = vbeing a silent no-op) was a similar codegen stub inExpr::Uint8ArraySet; fixed separately.