Files
scriptc/tests/corpus/native-array-dynamic-reads/main.ts
T
Chris Tate ea599922a4 Iterate and read native arrays from untyped code without type-name scans
Untyped code that loops over a native array (`for (const ch of checks)` in
zod, over arrays the compiled code built) paid for the loop before its
first element:

- Every check of whether a typed capsule is a generator compared its type
  name against "async-generator<" with strncmp, and native array type
  names also start with 'a'. Iterator creation made several such checks.
  The test now looks at the second byte before comparing.
- scr_dyn_iterator called the builtin values() through the general call
  path for a native array; it now creates the native iterator directly,
  as it already did for untyped arrays.
- Read sites of `length` and `next` call scr_js_get_probe_native, which
  answers a native array's `length` and a native iterator's `next`, where
  the generic read built the array's checked view or looked the method up
  by name. Other read sites keep scr_js_get_probe, so their receivers that
  are not ordinary objects still miss without a further test.
2026-10-25 13:23:22 -05:00

33 lines
1.2 KiB
TypeScript

// Native arrays and iterators from typed code, read by untyped code: for-of
// over them, their length, an iterator's next read as a value and called,
// generators and async generators beside them, and an array whose
// iteration a Symbol.iterator use elsewhere in the program does not change.
import { asyncKinds, describe, lengths, sumAll, stepper } from "./reads.js";
interface Item {
sku: string;
qty: number;
}
const numbers: number[] = [1, 2, 3, 4];
const items: Item[] = [
{ sku: "a", qty: 2 },
{ sku: "b", qty: 5 },
];
const empty: string[] = [];
function* counting(): Generator<number> {
yield 10;
yield 20;
}
console.log(sumAll(numbers), sumAll(items.map((i) => i.qty)), sumAll(empty.map(Number)));
console.log(lengths([numbers, items, empty]).join());
numbers.push(5);
console.log(lengths([numbers]).join(), sumAll(numbers));
console.log(describe(items), describe(counting()));
console.log(stepper(numbers).join(), stepper(counting()).join());
const iterable = { *[Symbol.iterator]() { yield "own"; } };
console.log([...iterable].join(), sumAll(numbers));
async function* later(): AsyncGenerator<number> {
yield 1;
}
asyncKinds(later(), numbers).then((kinds) => console.log(kinds.join()));