Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Lent `own` handle can be dropped before the subtask's result is delivered

Đang mở
#14,949 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
49/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
rust, wasm
Lĩnh vực
backend

Hướng nghiên cứu

The report gives a reproducing WAST test but names no Wasmtime source file or existing test path. Start by locating the component model async implementation of Subtask.deliver_resolve and the handling of task.return or task.cancel, then run the supplied WAST case with cargo run -- wast lend-released-early.wast. Done means the case traps with “cannot remove owned resource while borrowed” before the terminal event is delivered.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

wasm-proposal:component-model-async

This test:

;;! component_model_async = true

;; A lends `own` handle `h` to an async subtask in B. B drops its borrow,
;; calls `task.return` and then completes a future write that A is waiting
;; on. When A wakes up for the future, the subtask's RETURNED event hasn't
;; been delivered yet, so `h` is still lent and `resource.drop` must trap.

(component definition $C
  (import "host" (instance $host
    (export "resource1" (type $r (sub resource)))
    (export "[constructor]resource1" (func (param "r" u32) (result (own $r))))
  ))
  (alias export $host "resource1" (type $r))
  (alias export $host "[constructor]resource1" (func $resource1.ctor))

  (component $B
    (import "resource1" (type $r (sub resource)))
    (type $FT (future))
    (core func $resource.drop (canon resource.drop $r))
    (core func $task.return (canon task.return))
    (core func $future.read (canon future.read $FT async))
    (core func $future.drop-readable (canon future.drop-readable $FT))
    (core module $m
      (import "" "resource.drop" (func $resource.drop (param i32)))
      (import "" "task.return" (func $task.return))
      (import "" "future.read" (func $future.read (param i32 i32) (result i32)))
      (import "" "future.drop-readable" (func $future.drop-readable (param i32)))
      (global $b (mut i32) (i32.const 0))
      (global $rx (mut i32) (i32.const 0))
      (func (export "f") (param $x i32) (param $rx i32) (result i32)
        (global.set $b (local.get $x))
        (global.set $rx (local.get $rx))
        (i32.const 1 (; YIELD ;)))
      (func (export "cb") (param i32 i32 i32) (result i32)
        (call $resource.drop (global.get $b))
        (call $task.return)
        ;; Now complete A's pending future.write
        (if (i32.ne (call $future.read (global.get $rx) (i32.const 0)) (i32.const 0 (; COMPLETED ;)))
          (then unreachable))
        (call $future.drop-readable (global.get $rx))
        (i32.const 0 (; EXIT ;)))
    )
    (core instance $i (instantiate $m (with "" (instance
      (export "resource.drop" (func $resource.drop))
      (export "task.return" (func $task.return))
      (export "future.read" (func $future.read))
      (export "future.drop-readable" (func $future.drop-readable))
    ))))
    (func (export "f") async (param "x" (borrow $r)) (param "rx" $FT)
      (canon lift (core func $i "f") async (callback (core func $i "cb"))))
  )
  (instance $b (instantiate $B (with "resource1" (type $r))))

  (component $A
    (import "resource1" (type $r (sub resource)))
    (type $FT (future))
    (import "[constructor]resource1" (func $resource1.ctor (param "r" u32) (result (own $r))))
    (import "f" (func $f async (param "x" (borrow $r)) (param "rx" $FT)))
    (core func $resource1.ctor (canon lower (func $resource1.ctor)))
    (core func $f (canon lower (func $f) async))
    (core func $resource.drop (canon resource.drop $r))
    (core func $waitable-set.new (canon waitable-set.new))
    (core func $waitable.join (canon waitable.join))
    (core func $task.return (canon task.return))
    (core func $future.new (canon future.new $FT))
    (core func $future.write (canon future.write $FT async))
    (core module $m
      (import "" "task.return" (func $task.return))
      (import "" "[constructor]resource1" (func $resource1.ctor (param i32) (result i32)))
      (import "" "f" (func $f (param i32 i32) (result i32)))
      (import "" "resource.drop" (func $resource.drop (param i32)))
      (import "" "waitable-set.new" (func $waitable-set.new (result i32)))
      (import "" "waitable.join" (func $waitable.join (param i32 i32)))
      (import "" "future.new" (func $future.new (result i64)))
      (import "" "future.write" (func $future.write (param i32 i32) (result i32)))
      (global $h (mut i32) (i32.const 0))
      (func (export "run") (result i32)
        (local $s i32) (local $ws i32) (local $p i64) (local $tx i32)
        (global.set $h (call $resource1.ctor (i32.const 7)))
        (local.set $p (call $future.new))
        (local.set $tx (i32.wrap_i64 (i64.shr_u (local.get $p) (i64.const 32))))
        (local.set $s (call $f (global.get $h) (i32.wrap_i64 (local.get $p))))
        ;; B yielded, so the subtask must be STARTED.
        (if (i32.ne (i32.and (local.get $s) (i32.const 0xf)) (i32.const 1)) (then unreachable))
        ;; B isn't reading yet, so this blocks.
        (if (i32.ne (call $future.write (local.get $tx) (i32.const 0)) (i32.const -1))
          (then unreachable))
        (local.set $ws (call $waitable-set.new))
        (call $waitable.join (local.get $tx) (local.get $ws))
        (i32.or (i32.const 2 (; WAIT ;)) (i32.shl (local.get $ws) (i32.const 4))))
      (func (export "cb") (param $ev i32) (param $idx i32) (param $code i32) (result i32)
        (if (i32.ne (local.get $ev) (i32.const 5 (; FUTURE_WRITE ;))) (then unreachable))
        ;; The subtask's RETURNED event hasn't been delivered, so `h` is
        ;; still lent.
        (call $resource.drop (global.get $h))
        (call $task.return)
        (i32.const 0 (; EXIT ;)))
    )
    (core instance $i (instantiate $m (with "" (instance
      (export "[constructor]resource1" (func $resource1.ctor))
      (export "f" (func $f))
      (export "resource.drop" (func $resource.drop))
      (export "waitable-set.new" (func $waitable-set.new))
      (export "waitable.join" (func $waitable.join))
      (export "task.return" (func $task.return))
      (export "future.new" (func $future.new))
      (export "future.write" (func $future.write))
    ))))
    (func (export "run") async
      (canon lift (core func $i "run") async (callback (core func $i "cb"))))
  )
  (instance $a (instantiate $A (with "resource1" (type $r)) (with "[constructor]resource1" (func $resource1.ctor))
    (with "f" (func $b "f"))))
  (func (export "run") (alias export $a "run"))
)

(component instance $c $C)
(assert_trap (invoke "run") "cannot remove owned resource while borrowed")

fails with:

$ cargo run -- wast lend-released-early.wast
Error: failed to run script file 'lend-released-early.wast'

Caused by:
    0: failed directive on lend-released-early.wast:118
    1: expected trap, got Component([])
Details

In the canonical ABI, a caller's lends to a subtask are released in
Subtask.deliver_resolve, i.e. when the caller receives the RETURNED (or
RETURN_CANCELLED) event. Wasmtime releases them as soon as the callee calls
task.return/task.cancel (or an async host import's future completes or
is aborted), so the caller can resource.drop the lent own while the
terminal event is still undelivered. Wasmtime still checks the callee's
borrows are gone when it returns, so no borrow is left outstanding; it's a
missing trap.

Ngôn ngữ chính
Rust
Star
18.7k
Fork
1.9k
Merge trung bình
22 giờ 27 phút
Pull request đã merge (30 ngày)
383

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của bytecodealliance/wasmtime

Tất cả issue của bytecodealliance/wasmtime

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.