Skip to content

push onto an array parameter is lost to the caller (stale length/data under gc; crash under rc) #453

Closed

Description

@ASDAlexander77

A push inside a function onto an array it was given is not seen by the caller. The callee pushes onto its own copy of the array (its pointer and length), so the caller keeps the old length, and reads through the old data pointer after the callee may have reallocated it.

function keepTwo(into: number[]) {
    into.push(1);
    into.push(2);
    print("inside ", into.length);
}

function main() {
    const list: number[] = [7];
    keepTwo(list);
    print("after ", list.length, " ", list[0]);
}

Expected: inside 3, then after 3 7.

Actual, tslang --emit=jit --no-default-lib, main 8b9d631:

model output
gc inside 3, then after 1 0. The length is stale, and list[0] reads 0, not 7
none the same as gc for the one-push version: len 0
rc exits with 127 and prints nothing after the callee (the old data block is freed by the reallocation)

The same happens with let list and with the default library under gc (len 0 for a single keepOne(1, list) push).

Found while writing Shared<T> tests (own phase 8): own_shared_count.ts keeps its handles in a class field instead of an array parameter because of this.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions