Skip to content

Buffer.allocUnsafe and Buffer.byteLength fail at codegen Phase 2 (compile-fatal) #630

Closed

Description

@proggeramlug

Repro

// repro_a.ts
import { Buffer } from "node:buffer";
const b = Buffer.allocUnsafe(8);
console.log(b.fill(0xab).toString("hex"));
// repro_b.ts
import { Buffer } from "node:buffer";
console.log(Buffer.byteLength("hello", "utf8"));

Actual (Perry)

Both files fail at compile, exit 1:

Error compiling module 'repro_a.ts' (...): lowering entry of module 'repro_a.ts':
  lowering init statements of module 'repro_a.ts':
    perry-codegen Phase 2: expression BufferAllocUnsafe not yet supported
Error compiling module 'repro_b.ts' (...): lowering entry of module 'repro_b.ts':
  lowering init statements of module 'repro_b.ts':
    perry-codegen Phase 2: expression BufferByteLength not yet supported

Expected (Node)

abababababababab
5

Impact

These two are foundational Buffer APIs — used by virtually every Node library that touches binary data. Buffer.byteLength(s, "utf8") is the canonical "how many bytes does this string take?" probe used by Content-Length headers, hash inputs, network framing, etc. Buffer.allocUnsafe is the recommended fast-path allocator (faster than Buffer.alloc because it skips zeroing).

Currently any file importing them fails at compile time — there's no PERRY_ALLOW_UNIMPLEMENTED workaround because the failure happens during HIR lowering, not at runtime dispatch.

Both have HIR variants (Expr::BufferAllocUnsafe, Expr::BufferByteLength) so the lowering recognizes them; codegen Phase 2 just doesn't have arms for them yet. Most adjacent buffer ops (Buffer.alloc, Buffer.from, Buffer.concat) work fine — these two are clear gaps.

Acceptance

Both repros above compile + run with Perry, byte-identical to Node.

Related

Surfaced while building test-files/test_parity_buffer.ts (parity gap report). Both lines are currently // PERRY-SKIP: codegen-fatal in the test file; uncomment when fixed.

Activity

  1. proggeramlug commented on May 9, 2026

    @proggeramlug
    ContributorAuthor

    Closed in v0.5.724. Both HIR variants and runtime helpers were already in place; only the codegen lowering arms were missing. Added two arms in crates/perry-codegen/src/expr.rs: Expr::BufferAllocUnsafe lowers size through fptosi and calls js_buffer_alloc_unsafe; Expr::BufferByteLength extracts the StringHeader via js_get_string_pointer_unified and calls js_buffer_byte_length (sitofp to f64).

    Both repros byte-identical to Node post-fix. Tests: test-files/test_issue_630_a.ts / test-files/test_issue_630_b.ts.

    Note: the encoding arg of Buffer.byteLength is currently UTF-8 only — matches the existing BufferHeader.byte_len semantics. Hex/base64 byte counts are a separate enhancement; the load-bearing UTF-8 case works.

  2. added a commit that references this issue on May 9, 2026
    8a4fcaa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions