Skip to content

Zero-length stream copies within one component instance trap for non-numeric payloads #753

Open

Description

@alexcrichton

This test:

;; With a write pending on a `stream<string>`, a zero-length read from the
;; same component instance copies nothing and returns COMPLETED(0).
(component
  (core module $libc
    (memory (export "memory") 1)
    (func (export "realloc") (param i32 i32 i32 i32) (result i32) unreachable))
  (core instance $libc (instantiate $libc))
  (type $stream (stream string))
  (core func $stream.new (canon stream.new $stream))
  (core func $stream.read (canon stream.read $stream async
    (memory (core memory $libc "memory")) (realloc (core func $libc "realloc"))))
  (core func $stream.write (canon stream.write $stream async
    (memory (core memory $libc "memory"))))
  (core module $m
    (import "" "stream.new" (func $stream.new (result i64)))
    (import "" "stream.read" (func $stream.read (param i32 i32 i32) (result i32)))
    (import "" "stream.write" (func $stream.write (param i32 i32 i32) (result i32)))
    (func (export "run") (result i32)
      (local $pair i64)
      (local.set $pair (call $stream.new))
      (if (i32.ne (i32.const -1) ;; BLOCKED
            (call $stream.write
              (i32.wrap_i64 (i64.shr_u (local.get $pair) (i64.const 32)))
              (i32.const 0) (i32.const 1)))
        (then unreachable))
      (call $stream.read (i32.wrap_i64 (local.get $pair)) (i32.const 0) (i32.const 0)))
  )
  (core instance $i (instantiate $m (with "" (instance
    (export "stream.new" (func $stream.new))
    (export "stream.read" (func $stream.read))
    (export "stream.write" (func $stream.write))))))
  (func (export "run") async (result u32) (canon lift (core func $i "run")))
)


(assert_return (invoke "run") (u32.const 0)) ;; COMPLETED(0)

fails in Wasmtime with:

$ wasmtime wast foo.wast
Error: failed to run script file 'foo.wast'

Caused by:
    0: failed directive on foo.wast:39
    1: error while executing at wasm backtrace:
    0:    0x282 - wasm-function[3]
                    at foo.wast:29:8
    2: cannot read from and write to intra-component future/stream with non-numeric payload

but the spec indicates that this test should pass right now as the trap is gated on non-zero-length buffers.

I wanted to flag this as a possible update to the specification (similar to #750 perhaps) where subjectively I'd expect this to unconditionally fail regardless of the lengths in play, but I may also be showing my biases from #750 too.

Activity

  1. lukewagner commented on Oct 23, 2026

    @lukewagner
    Member

    Makes sense, I think the irregularity here was just an oversight; included in #755.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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