Skip to content
Merged
2 changes: 1 addition & 1 deletion quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ generic std gap is planned here even when moq never calls it.
- [Placeholders written to a crate's own fmt::Write](/quest/m3/ts-fmt-calls.md) - `write!` with placeholders into a crate's own writer translates, its `write_str` seeing each call std makes
- [Waiting: drop the lang fixture's mul_add allowance](/quest/m3/ts-fma-allowance.md) - the differential fails on any `mul_add` difference again once wasm32's `fma` rounds exactly
- [Waiting: type-check in process with tsrs](/quest/m3/ts-tsrs.md) - rust2-ts checks bindings through tsrs instead of `tsc` once it is a stable library
- [Drop order in std's folds and iterators](/quest/m3/ts-drop-order.md) - the values that drop still refused in std's consumers, flattens, and collects drop as std's do
- [Drop order in std's folds and iterators](/quest/m3/ts-drop-order.md) - the values that drop still refused in std's consumers and collects drop as std's do
- [A slice of one value behind any &mut](/quest/m3/ts-slice-of-one.md) - `slice::from_mut` and `array::from_mut` of a `&mut u8`, or of an object no place names, translate
- [std's calls of a closure that have no mapping](/quest/m3/ts-closure-calls.md) - `try_fold`, `partition`, `repeat_with`, `sort_by_cached_key`, and `LazyCell::new` translate, dropping what their closures own as std's do
- [A closure that drops given to a string's edit or search](/quest/m3/ts-string-closures.md) - `String::retain` and `str`'s searches by a closure that owns a value that drops translate
Expand Down
19 changes: 4 additions & 15 deletions quest/m3/ts-drop-order.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,12 @@ map's `into_keys` and `into_values`, and the closures `for_each` and `fold` own
The closures `reduce`, `max_by`, `min_by`, their `_by_key` forms, `is_sorted_by_key`, and
a map's entries' `or_insert_with`, `or_insert_with_key`, and `and_modify` own landed in
[#438](https://github.com/moq-dev/rust2/pull/438), with its `released` step.
A `skip` of a zip std reads by index, a zip collected in place, and a `flatten` whose
inner iterators hold items once they end landed in
[#446](https://github.com/moq-dev/rust2/pull/446), with its `indexed` and
`flattened` steps.
Each left is refused with a span where std's order is one JS's can't follow yet:

- A `skip` of a `zip` of two `TrustedRandomAccess` iterators of items that drop, as the
reject fixture's `skipped_zip`: std's `Skip` read by index, as a zip by index or `take`'s
fold reads it, makes and drops each skipped pair whole, where its `next` skips through
the zip's `nth`, a side at a time. `rt.Iter` would need a reader by index beside `folded`.
- A `collect` in place of a zip std reads by index that holds values that drop, as the
reject fixture's `zip_in_place`: std reads it by index, then drops it whole, inner
closures before outer ones, where the runtime's bounded read is its `fold`, which drops
each closure as its fold ends.
- A `flatten` or `flat_map` whose inner iterator holds items once ended, as
`v.into_iter().map(|v| v.into_iter().take(1)).flatten()` of a `Vec<Vec<T>>` whose `T`
drops. std's `try_fold` keeps an ended inner iterator until the next one replaces it, or
drops it after the source once the source ends, where `next` drops it as it ends. Every
adaptor whose `try_fold` is its source's, such as `map`, `filter`'s `next`, and `rev`'s
through `try_rfold`, reads it that way, so `rt.Iter::folded` would follow through each,
a hot path to measure on the [TS benchmark](/ts/README.md#bench).
- A B-tree's `collect` of entries that drop, sorted and deduplicated by the crate's own
impls, as `v.into_iter().collect::<BTreeSet<O>>()` of an `O` whose `Ord`, `PartialOrd`,
or `PartialEq` is its own: one that panics or disagrees with itself leaves equal keys
Expand Down
7 changes: 7 additions & 0 deletions ts/bench/iter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ export function iterate(chain: number, data: Uint8Array): Uint8Array {
for (let i = data.length - 1; i >= 0; i--) if ((i & 0xff) < data[i]) n++;
return u64(n);
}
case 8: {
// Both sides mapped as the front's `for ... of` reads them.
let n = 0;
let i = 0;
for (const a of data.values()) if (a >> 1 < (data[i++] ^ 3)) n++;
return u64(n);
}
default: {
let last = 0;
let i = 0;
Expand Down
2 changes: 1 addition & 1 deletion ts/bench/workloads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function workloads(encode: (input: Uint8Array) => Uint8Array): Workload[]
// Iterator chains over bytes, as `bench.rs`'s op 6 picks them by selector; no byte is
// 0xff, so `any` reads them all.
const bytes = Uint8Array.from({ length: 1024 }, (_, i) => (i * 167 + 13) % 255);
const chains = ["map-filter-count", "any", "filter-collect", "sum", "skip-take-fold", "enumerate-for", "zip-filter-count", "zip-rev-filter-count"];
const chains = ["map-filter-count", "any", "filter-collect", "sum", "skip-take-fold", "enumerate-for", "zip-filter-count", "zip-rev-filter-count", "zip-map-filter-count"];
chains.forEach((chain, selector) => {
out.push({ name: `iter/${chain}`, op: "iterate", items: bytes.length, input: Uint8Array.of(6, selector, ...bytes) });
});
Expand Down
44 changes: 26 additions & 18 deletions ts/fixtures/codec/expected/bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,45 +473,53 @@ export function push(selector: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void
*/
export function iterate(chain: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
if (chain === 0) {
putUsize(out, rt.iterCount(rt.iterFilter(rt.iterMap(rt.iterSlice(rt.byteSliceView(data)), (_214: rt.u8): rt.u8 => {
return _214 >> 1;
}), (_215: rt.u8): boolean => {
return (_215 & 1) === 0;
putUsize(out, rt.iterCount(rt.iterFilter(rt.iterMap(rt.iterSlice(rt.byteSliceView(data)), (_217: rt.u8): rt.u8 => {
return _217 >> 1;
}), (_218: rt.u8): boolean => {
return (_218 & 1) === 0;
})));
} else if (chain === 1) {
rt.byteVecPush(out, rt.iterAny(rt.iterSlice(rt.byteSliceView(data)), (_213: rt.u8): boolean => {
return _213 === 255;
rt.byteVecPush(out, rt.iterAny(rt.iterSlice(rt.byteSliceView(data)), (_216: rt.u8): boolean => {
return _216 === 255;
}) ? 1 : 0);
} else if (chain === 2) {
putUsize(out, rt.iterToByteVec(rt.iterFilter(rt.iterSlice(rt.byteSliceView(data)), (_212: rt.u8): boolean => {
return (_212 & 1) === 1;
putUsize(out, rt.iterToByteVec(rt.iterFilter(rt.iterSlice(rt.byteSliceView(data)), (_215: rt.u8): boolean => {
return (_215 & 1) === 1;
}), "next").length);
} else if (chain === 3) {
harness_putU64(out, rt.iterSum(rt.iterMap(rt.iterSlice(rt.byteSliceView(data)), (_211: rt.u8): rt.u32 => {
return _211 as rt.u32;
harness_putU64(out, rt.iterSum(rt.iterMap(rt.iterSlice(rt.byteSliceView(data)), (_214: rt.u8): rt.u32 => {
return _214 as rt.u32;
}), rt.u32Add, 0) as rt.u64);
} else if (chain === 4) {
harness_putU64(out, rt.iterFold(rt.iterTake(rt.iterSkip(rt.iterSlice(rt.byteSliceView(data)), 16), 512), 0, (acc: rt.u32, _3: rt.u8): rt.u32 => {
return (acc ^ _3 as rt.u32) >>> 0;
}) as rt.u64);
} else if (chain === 6) {
putUsize(out, rt.iterCount(rt.iterFilter(rt.iterZip(rt.iterSlice(rt.byteSliceView(data)), rt.iterRev(rt.iterSlice(rt.byteSliceView(data))), "len"), (_210: [rt.u8, rt.u8]): boolean => {
return _210[0] < _210[1];
putUsize(out, rt.iterCount(rt.iterFilter(rt.iterZip(rt.iterSlice(rt.byteSliceView(data)), rt.iterRev(rt.iterSlice(rt.byteSliceView(data))), "len"), (_213: [rt.u8, rt.u8]): boolean => {
return _213[0] < _213[1];
})));
} else if (chain === 7) {
putUsize(out, rt.iterCount(rt.iterFilter(rt.iterRev(rt.iterZip(new rt.Range(0, rt.usizeMul(data.length, 64)), rt.iterSlice(rt.byteSliceView(data)), [false, false])), (_2: [rt.usize, rt.u8]): boolean => {
return (_2[0] & 0xff) < _2[1];
putUsize(out, rt.iterCount(rt.iterFilter(rt.iterRev(rt.iterZip(new rt.Range(0, rt.usizeMul(data.length, 64)), rt.iterSlice(rt.byteSliceView(data)), [false, false])), (_212: [rt.usize, rt.u8]): boolean => {
return (_212[0] & 0xff) < _212[1];
})));
} else if (chain === 8) {
putUsize(out, rt.iterCount(rt.iterFilter(rt.iterZip(rt.iterMap(rt.iterSlice(rt.byteSliceView(data)), (_2: rt.u8): rt.u8 => {
return _2 >> 1;
}), rt.iterMap(rt.iterSlice(rt.byteSliceView(data)), (_210: rt.u8): rt.u8 => {
return _210 ^ 3;
}), [true, true]), (_211: [rt.u8, rt.u8]): boolean => {
return _211[0] < _211[1];
})));
} else {
let last: rt.usize = 0;
const iter: rt.Iter<[rt.usize, rt.u8]> = rt.iterEnumerate(rt.iterSlice(rt.byteSliceView(data)));
while (true) {
const _47: [rt.usize, rt.u8] | rt.Done = iter.next();
if (_47 === rt.DONE) {
const _54: [rt.usize, rt.u8] | rt.Done = iter.next();
if (_54 === rt.DONE) {
break;
}
const i: rt.usize = _47[0];
if (_47[1] === 128) {
const i: rt.usize = _54[0];
if (_54[1] === 128) {
last = i;
}
}
Expand Down
9 changes: 9 additions & 0 deletions ts/fixtures/codec/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,15 @@ fn iterate(chain: u8, data: &[u8], out: &mut Vec<u8>) {
.filter(|&(i, &b)| (i as u8) < b)
.count(),
),
// By index from the front, each side mapped, which may have side effects.
8 => put_usize(
out,
data.iter()
.map(|&b| b >> 1)
.zip(data.iter().map(|&b| b ^ 3))
.filter(|(a, b)| a < b)
.count(),
),
_ => {
let mut last = 0;
for (i, &b) in data.iter().enumerate() {
Expand Down
42 changes: 21 additions & 21 deletions ts/fixtures/lang/expected/iters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2115,7 +2115,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6227.value, x217 ^ 2);
rt.refMutRelease(_6227);
return x217;
}), [true, true]), n)) & 0xff);
}), [true, true]), n, undefined, true)) & 0xff);
} else if (_79 === 6) {
rt.byteVecPush(out, rt.iterCount(rt.iterSkip(rt.iterZip(rt.iterMap(rt.iterSlice(rt.byteSliceView(a2)), (_2272: rt.u8): rt.u8 => {
const x214: rt.u8 = _2272;
Expand Down Expand Up @@ -2536,7 +2536,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6179.value, x139 ^ 8);
rt.refMutRelease(_6179);
return x139;
}), "len");
}), "index");
const _574: rt.usize = rt.usizeRem(data.length, 8);
if (_574 === 0) {
rt.byteVecPush(out, rt.iterCount(z7) & 0xff);
Expand All @@ -2555,7 +2555,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
} else if (_574 === 4) {
rt.iterExtendBytes(out, rt.byteVecIntoIter(rt.iterToByteVec(rt.iterMap(z7, (_2205: [rt.u8, rt.u8]): rt.u8 => {
return _2205[0] ^ _2205[1];
}), undefined, true, 1)), undefined, true);
}), "index", true, 1)), undefined, true);
} else if (_574 === 5) {
rt.byteVecPush(out, rt.iterFold(z7, 0, (acc4: rt.u8, p14: [rt.u8, rt.u8]): rt.u8 => {
return rt.u8WrappingMul(acc4, 3) ^ _573(p14);
Expand Down Expand Up @@ -2598,7 +2598,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6177.value, x136 ^ 8);
rt.refMutRelease(_6177);
return x136;
}), "len"), (_2198: [rt.u8, rt.u8]): boolean => {
}), "index"), (_2198: [rt.u8, rt.u8]): boolean => {
return rt.u8Rem(_2198[0], 2) === 0;
})) & 0xff);
} else if (_612 === 1) {
Expand All @@ -2612,7 +2612,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6175.value, x133 ^ 8);
rt.refMutRelease(_6175);
return x133;
}), "len"), (_2197: [rt.u8, rt.u8]): rt.u8 | undefined => {
}), "index"), (_2197: [rt.u8, rt.u8]): rt.u8 | undefined => {
return rt.u8CheckedSub(_2197[0], _2197[1]);
})) & 0xff);
} else if (_612 === 2) {
Expand All @@ -2626,7 +2626,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6173.value, x130 ^ 8);
rt.refMutRelease(_6173);
return x130;
}), "len"), (_2196: [rt.u8, rt.u8]): boolean => {
}), "index"), (_2196: [rt.u8, rt.u8]): boolean => {
return _2196[0] < 128;
})) & 0xff);
} else if (_612 === 3) {
Expand All @@ -2640,7 +2640,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6171.value, x128 ^ 8);
rt.refMutRelease(_6171);
return x128;
}), "len")), (_2195: [rt.usize, [rt.u8, rt.u8]]): rt.u8 => {
}), "index")), (_2195: [rt.usize, [rt.u8, rt.u8]]): rt.u8 => {
return _2195[0] & 0xff;
})), 238));
} else if (_612 === 4) {
Expand All @@ -2654,7 +2654,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6169.value, x126 ^ 8);
rt.refMutRelease(_6169);
return x126;
}), "len"), rt.iterSlice([[1, 2] as [rt.u8, rt.u8]]))) & 0xff);
}), "index"), rt.iterSlice([[1, 2] as [rt.u8, rt.u8]]))) & 0xff);
} else if (_612 === 5) {
rt.byteVecPush(out, rt.iterCount(rt.iterTake(rt.iterZip(rt.iterMap(rt.byteVecIntoIter(rt.byteSliceToByteVec(a2)), (x123: rt.u8): rt.u8 => {
const _6166: rt.RefCell<rt.ByteVec> = rt.refCellBorrowMut(log);
Expand All @@ -2666,7 +2666,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6167.value, x124 ^ 8);
rt.refMutRelease(_6167);
return x124;
}), "len"), n)) & 0xff);
}), "index"), n)) & 0xff);
} else if (_612 === 6) {
rt.byteVecPush(out, rt.iterCount(rt.iterSkip(rt.iterZip(rt.iterMap(rt.byteVecIntoIter(rt.byteSliceToByteVec(a2)), (x121: rt.u8): rt.u8 => {
const _6164: rt.RefCell<rt.ByteVec> = rt.refCellBorrowMut(log);
Expand All @@ -2678,7 +2678,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6165.value, x122 ^ 8);
rt.refMutRelease(_6165);
return x122;
}), "len"), n)) & 0xff);
}), "index"), n)) & 0xff);
} else {
const p4: rt.Peekable<[rt.u8, rt.u8]> = rt.iterPeekable(rt.iterZip(rt.iterMap(rt.byteVecIntoIter(rt.byteSliceToByteVec(a2)), (x119: rt.u8): rt.u8 => {
const _6162: rt.RefCell<rt.ByteVec> = rt.refCellBorrowMut(log);
Expand All @@ -2690,7 +2690,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6163.value, x120 ^ 8);
rt.refMutRelease(_6163);
return x120;
}), "len"));
}), "index"));
rt.byteVecPush(out, (rt.peekablePeek(p4) !== undefined ? 1 : 0) ^ (rt.iterCount(p4) & 0xff));
}
}
Expand All @@ -2706,7 +2706,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6159.value, x108 ^ 10);
rt.refMutRelease(_6159);
return x108;
}), "len");
}), "index");
const _751: rt.usize = rt.usizeRem(data.length, 8);
if (_751 === 0) {
rt.byteVecPush(out, rt.iterCount(z9) & 0xff);
Expand All @@ -2725,7 +2725,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
} else if (_751 === 4) {
rt.iterExtendBytes(out, rt.byteVecIntoIter(rt.iterToByteVec(rt.iterMap(z9, (_2192: [rt.u8, rt.u8]): rt.u8 => {
return _2192[0] ^ _2192[1];
}), undefined, true, 1)), undefined, true);
}), "index", true, 1)), undefined, true);
} else if (_751 === 5) {
rt.byteVecPush(out, rt.iterFold(z9, 0, (acc3: rt.u8, p12: [rt.u8, rt.u8]): rt.u8 => {
return rt.u8WrappingMul(acc3, 3) ^ _750(p12);
Expand Down Expand Up @@ -2769,7 +2769,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6157.value, x105 ^ 10);
rt.refMutRelease(_6157);
return x105;
}), "len"), (_2184: [rt.u8, rt.u8]): boolean => {
}), "index"), (_2184: [rt.u8, rt.u8]): boolean => {
return rt.u8Rem(_2184[0], 2) === 0;
})) & 0xff);
} else if (_789 === 1) {
Expand All @@ -2784,7 +2784,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6155.value, x102 ^ 10);
rt.refMutRelease(_6155);
return x102;
}), "len"), (_2182: [rt.u8, rt.u8]): rt.u8 | undefined => {
}), "index"), (_2182: [rt.u8, rt.u8]): rt.u8 | undefined => {
return rt.u8CheckedSub(_2182[0], _2182[1]);
})) & 0xff);
} else if (_789 === 2) {
Expand All @@ -2799,7 +2799,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6153.value, x99 ^ 10);
rt.refMutRelease(_6153);
return x99;
}), "len"), (_2180: [rt.u8, rt.u8]): boolean => {
}), "index"), (_2180: [rt.u8, rt.u8]): boolean => {
return _2180[0] < 128;
})) & 0xff);
} else if (_789 === 3) {
Expand All @@ -2814,7 +2814,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6151.value, x97 ^ 10);
rt.refMutRelease(_6151);
return x97;
}), "len")), (_2178: [rt.usize, [rt.u8, rt.u8]]): rt.u8 => {
}), "index")), (_2178: [rt.usize, [rt.u8, rt.u8]]): rt.u8 => {
return _2178[0] & 0xff;
})), 238));
} else if (_789 === 4) {
Expand All @@ -2829,7 +2829,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6149.value, x95 ^ 10);
rt.refMutRelease(_6149);
return x95;
}), "len"), rt.iterSlice([[1, 2] as [rt.u8, rt.u8]]))) & 0xff);
}), "index"), rt.iterSlice([[1, 2] as [rt.u8, rt.u8]]))) & 0xff);
} else if (_789 === 5) {
rt.byteVecPush(out, rt.iterCount(rt.iterTake(rt.iterZip(rt.iterMap(rt.iterSkip(rt.byteVecIntoIter(rt.byteSliceToByteVec(a2)), 1), (x92: rt.u8): rt.u8 => {
const _6146: rt.RefCell<rt.ByteVec> = rt.refCellBorrowMut(log);
Expand All @@ -2842,7 +2842,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6147.value, x93 ^ 10);
rt.refMutRelease(_6147);
return x93;
}), "len"), n)) & 0xff);
}), "index"), n)) & 0xff);
} else if (_789 === 6) {
rt.byteVecPush(out, rt.iterCount(rt.iterSkip(rt.iterZip(rt.iterMap(rt.iterSkip(rt.byteVecIntoIter(rt.byteSliceToByteVec(a2)), 1), (x90: rt.u8): rt.u8 => {
const _6144: rt.RefCell<rt.ByteVec> = rt.refCellBorrowMut(log);
Expand All @@ -2855,7 +2855,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6145.value, x91 ^ 10);
rt.refMutRelease(_6145);
return x91;
}), "len"), n)) & 0xff);
}), "index"), n)) & 0xff);
} else {
const p5: rt.Peekable<[rt.u8, rt.u8]> = rt.iterPeekable(rt.iterZip(rt.iterMap(rt.iterSkip(rt.byteVecIntoIter(rt.byteSliceToByteVec(a2)), 1), (x88: rt.u8): rt.u8 => {
const _6142: rt.RefCell<rt.ByteVec> = rt.refCellBorrowMut(log);
Expand All @@ -2868,7 +2868,7 @@ export function zips(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecPush(_6143.value, x89 ^ 10);
rt.refMutRelease(_6143);
return x89;
}), "len"));
}), "index"));
rt.byteVecPush(out, (rt.peekablePeek(p5) !== undefined ? 1 : 0) ^ (rt.iterCount(p5) & 0xff));
}
}
Expand Down
Loading