Skip to content

async_builtins: sync subtask.cancel park omits has_sync_waiter (waitable.join admitted that the reference traps) #87

Description

@lann

Severity: medium — missing trap escalates to an internal assert (jspi mode).

SITE 5 (intrinsics/async_builtins.ts:474-486) parks a sync subtask.cancel
via blockCurrentActivation({readyFunc: () => st.resolved(), ...}) and
never sets hasSyncWaiter. The reference's wait_for_pending_event sets
has_sync_waiter for the duration (definitions.py:786-790, reached from
canon_subtask_cancel :2491), which is what makes a concurrent
waitable.join trap (canon_waitable_join, definitions.py:2463). The
repo's own join-time trap exists (async_builtins.ts:362-365) but can never
fire on this path. The stream twin does this correctly — SITE 4,
stream_builtins.ts:305-323.

Escalation: with the illegal join admitted, another task's
waitable-set.wait can steal the SUBTASK event between resolution and the
cancel's resume; finishSubtaskCancel (:403-419) then calls
getPendingEvent() with no pending event and dies in assert_
(task/waitable.ts:70) — an internal AssertionError where the reference
makes the misuse a trap at the join.

Fix: mirror SITE 4 — set hasSyncWaiter before the park, clear it in
produce, and use hasPendingEvent() (not resolved()) as the ready
condition, matching the reference's wait target.

Found in the 2026-08-10 adversarial conformance review (runtime + translator vs component-model @ 73b7ad5 definitions.py; wasmtime-environ 47.0.3 treated as trusted).

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