diff --git a/crates/js-component-bindgen/src/intrinsics/lower.rs b/crates/js-component-bindgen/src/intrinsics/lower.rs index a8cc61b9..83e1cb38 100644 --- a/crates/js-component-bindgen/src/intrinsics/lower.rs +++ b/crates/js-component-bindgen/src/intrinsics/lower.rs @@ -542,14 +542,17 @@ impl LowerIntrinsic { ctx.resultPtr = originalPtr + payloadOffset32; - const payloadBytesWritten = lowerFn({{ - memory, - realloc, - vals: [val], - storagePtr, - storageLen, - componentIdx, - }}); + let payloadBytesWritten = 0; + if (lowerFn) {{ + lowerFn({{ + memory, + realloc, + vals: [val], + storagePtr, + storageLen, + componentIdx, + }}); + }} let bytesWritten = payloadOffset + payloadBytesWritten; const rem = ctx.storagePtr % align32; diff --git a/crates/js-component-bindgen/src/intrinsics/mod.rs b/crates/js-component-bindgen/src/intrinsics/mod.rs index 0b50d4cf..ac82b5d0 100644 --- a/crates/js-component-bindgen/src/intrinsics/mod.rs +++ b/crates/js-component-bindgen/src/intrinsics/mod.rs @@ -1213,6 +1213,9 @@ pub fn render_intrinsics(args: RenderIntrinsicsArgs) -> Source { if args .intrinsics .contains(&Intrinsic::Waitable(WaitableIntrinsic::WaitableSetPoll)) + || args + .intrinsics + .contains(&Intrinsic::Waitable(WaitableIntrinsic::WaitableSetWait)) { args.intrinsics .extend([&Intrinsic::Host(HostIntrinsic::StoreEventInComponentMemory)]); @@ -1268,6 +1271,22 @@ pub fn render_intrinsics(args: RenderIntrinsicsArgs) -> Source { ]); } + if args + .intrinsics + .contains(&Intrinsic::Lower(LowerIntrinsic::LowerFlatResult)) + { + args.intrinsics + .insert(Intrinsic::Lower(LowerIntrinsic::LowerFlatVariant)); + } + + if args + .intrinsics + .contains(&Intrinsic::Lower(LowerIntrinsic::LowerFlatOption)) + { + args.intrinsics + .insert(Intrinsic::Lower(LowerIntrinsic::LowerFlatVariant)); + } + if args .intrinsics .contains(&Intrinsic::Lower(LowerIntrinsic::LowerFlatVariant)) @@ -1364,10 +1383,14 @@ pub fn render_intrinsics(args: RenderIntrinsicsArgs) -> Source { if args .intrinsics .contains(&Intrinsic::AsyncStream(AsyncStreamIntrinsic::StreamWrite)) + || args + .intrinsics + .contains(&Intrinsic::AsyncStream(AsyncStreamIntrinsic::StreamRead)) { args.intrinsics.extend([ &Intrinsic::GlobalBufferManager, &Intrinsic::AsyncTask(AsyncTaskIntrinsic::AsyncBlockedConstant), + &Intrinsic::AsyncEventCodeEnum, ]); } diff --git a/crates/js-component-bindgen/src/intrinsics/p3/async_stream.rs b/crates/js-component-bindgen/src/intrinsics/p3/async_stream.rs index 5e027d19..e9bc4555 100644 --- a/crates/js-component-bindgen/src/intrinsics/p3/async_stream.rs +++ b/crates/js-component-bindgen/src/intrinsics/p3/async_stream.rs @@ -1140,7 +1140,7 @@ impl AsyncStreamIntrinsic { r#" class {host_stream_class_name} {{ #componentIdx; - #streamEndIdx; + #streamEndWaitableIdx; #streamTableIdx; #payloadLiftFn; @@ -1162,14 +1162,16 @@ impl AsyncStreamIntrinsic { if (!args.payloadLowerFn) {{ throw new TypeError("missing payload lower fn"); }} this.#payloadLowerFn = args.payloadLowerFn; - if (args.streamEndIdx === undefined) {{ throw new Error("missing stream idx"); }} + if (args.streamEndWaitableIdx === undefined) {{ throw new Error("missing stream idx"); }} if (args.streamTableIdx === undefined) {{ throw new Error("missing stream table idx"); }} - this.#streamEndIdx = args.streamEndIdx; + this.#streamEndWaitableIdx = args.streamEndWaitableIdx; this.#streamTableIdx = args.streamTableIdx; this.#isUnitStream = args.isUnitStream; }} + setRep(r) {{ this.#rep = r; }} + createUserStream(args) {{ if (this.#userStream) {{ return this.#userStream; }} if (this.#rep === null) {{ throw new Error("unexpectedly missing rep for host stream"); }} @@ -1177,9 +1179,9 @@ impl AsyncStreamIntrinsic { const cstate = {get_or_create_async_state_fn}(this.#componentIdx); if (!cstate) {{ throw new Error(`missing async state for component [${{this.#componentIdx}}]`); }} - const streamEnd = cstate.getStreamEnd({{ tableIdx: this.#streamTableIdx, streamEndIdx: this.#streamEndIdx }}); + const streamEnd = cstate.getStreamEnd({{ tableIdx: this.#streamTableIdx, streamEndWaitableIdx: this.#streamEndWaitableIdx }}); if (!streamEnd) {{ - throw new Error(`missing stream [${{this.#streamEndIdx}}] (table [${{this.#streamTableIdx}}], component [${{this.#componentIdx}}]`); + throw new Error(`missing stream [${{this.#streamEndWaitableIdx}}] (table [${{this.#streamTableIdx}}], component [${{this.#componentIdx}}]`); }} return new {external_stream_class}({{ @@ -1366,7 +1368,7 @@ impl AsyncStreamIntrinsic { {debug_log_fn}('[{stream_new_from_lift_fn}()] args', {{ ctx }}); const {{ componentIdx, - streamEndIdx, + streamEndWaitableIdx, streamTableIdx, payloadLiftFn, payloadTypeSize32, @@ -1376,7 +1378,7 @@ impl AsyncStreamIntrinsic { const stream = new {host_stream_class}({{ componentIdx, - streamEndIdx, + streamEndWaitableIdx, streamTableIdx, payloadLiftFn: payloadLiftFn, payloadLowerFn: payloadLowerFn, diff --git a/crates/js-component-bindgen/src/intrinsics/p3/waitable.rs b/crates/js-component-bindgen/src/intrinsics/p3/waitable.rs index f7beb8a6..ba0ed043 100644 --- a/crates/js-component-bindgen/src/intrinsics/p3/waitable.rs +++ b/crates/js-component-bindgen/src/intrinsics/p3/waitable.rs @@ -392,8 +392,9 @@ impl WaitableIntrinsic { throw Error(`task component [${{task.componentIdx}}] !== executing component [${{componentIdx}}]`); }} - const event = await task.waitForEvent({{ waitableSetRep, isAsync }}); - return {store_event_in_component_memory_fn}(memory, task, event, resultPtr); + const memory = getMemoryFn(); + const event = await task.waitUntil({{ waitableSetRep, readyFn: () => true, cancellable: false }}); + return {store_event_in_component_memory_fn}({{ memory, ptr: resultPtr, event }}); }} "#)); } diff --git a/crates/js-component-bindgen/src/transpile_bindgen.rs b/crates/js-component-bindgen/src/transpile_bindgen.rs index 8822efd0..8f0885b5 100644 --- a/crates/js-component-bindgen/src/transpile_bindgen.rs +++ b/crates/js-component-bindgen/src/transpile_bindgen.rs @@ -1202,12 +1202,12 @@ impl<'a> Instantiator<'a, '_> { uwriteln!( self.src.js, r#" - const trampoline{i} = {waitable_set_wait_fn}.bind(null, {{ + const trampoline{i} = new WebAssembly.Suspending({waitable_set_wait_fn}.bind(null, {{ componentIdx: {instance_idx}, isAsync: {async_}, memoryIdx: {memory_idx}, getMemoryFn: () => memory{memory_idx}, - }}); + }})); "#, ); }