Skip to content

Commit a7914ee

Browse files
committed
WIP
1 parent aedeb5b commit a7914ee

File tree

8 files changed

+47
-99
lines changed

8 files changed

+47
-99
lines changed

crates/wasm-rquickjs/skeleton/Cargo.toml_

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ futures = { version = "0.3.31", features = [] }
2727
futures-concurrency = "7.6.3"
2828
pin-project = "1.1.10"
2929
url = "2.5.7"
30-
wasi = "0.12.1+wasi-0.2.0"
31-
wasi-async-runtime = "0.1.2"
30+
wasi = "=0.14.1+wasi-0.2.3"
3231
wit-bindgen-rt = { version = "0.42.1", features = ["bitflags"] }
33-
34-
# HTTP
35-
reqwest = { git = "https://github.com/golemcloud/reqwest", branch = "update-july-2025", features = ["async"], optional = true }
32+
wstd = "=0.5.4"
3633

3734
# Logging
3835
wasi-logging = { version = "0.0.1", optional = true }
3936

37+
# HTTP
38+
reqwest = { git = "https://github.com/golemcloud/reqwest", branch = "update-sep-2025-wstd", features = ["async"], optional = true }
39+
4040
[package.metadata.component.bindings]
4141
ownership = "owning"

crates/wasm-rquickjs/skeleton/src/builtin/http.rs

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rquickjs::prelude::List;
1818
use rquickjs::{ArrayBuffer, Ctx, JsLifetime, TypedArray};
1919
use std::cell::RefCell;
2020
use std::collections::HashMap;
21+
use wstd::runtime::AsyncPollable;
2122

2223
#[derive(Trace, JsLifetime)]
2324
#[rquickjs::class(rename_all = "camelCase")]
@@ -119,15 +120,7 @@ impl HttpRequest {
119120
}
120121

121122
pub fn init_send(&mut self) {
122-
let js_state = crate::internal::get_js_state();
123-
let reactor = js_state
124-
.reactor
125-
.borrow()
126-
.as_ref()
127-
.expect("http send is called from outside of an async call")
128-
.clone();
129-
130-
let client = reqwest::ClientBuilder::new(reactor)
123+
let client = reqwest::ClientBuilder::new()
131124
.build()
132125
.expect("Failed to create HTTP client");
133126

@@ -179,15 +172,7 @@ impl HttpRequest {
179172
}
180173

181174
pub async fn simple_send(&mut self) -> HttpResponse {
182-
let js_state = crate::internal::get_js_state();
183-
let reactor = js_state
184-
.reactor
185-
.borrow()
186-
.as_ref()
187-
.expect("http send is called from outside of an async call")
188-
.clone();
189-
190-
let client = reqwest::ClientBuilder::new(reactor)
175+
let client = reqwest::ClientBuilder::new()
191176
.build()
192177
.expect("Failed to create HTTP client");
193178

@@ -381,14 +366,7 @@ impl ResponseBodyStream {
381366
if let Some((stream, _body, _response)) = &mut self.stream {
382367
const CHUNK_SIZE: u64 = 4096;
383368
let pollable = stream.subscribe();
384-
let js_state = crate::internal::get_js_state();
385-
let reactor = js_state
386-
.reactor
387-
.borrow()
388-
.as_ref()
389-
.expect("http pull is called from outside of an async call")
390-
.clone();
391-
reactor.wait_for(pollable).await;
369+
AsyncPollable::new(pollable).wait_for().await;
392370

393371
match stream.read(CHUNK_SIZE) {
394372
Ok(chunk) => {

crates/wasm-rquickjs/skeleton/src/builtin/http_disabled.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.

crates/wasm-rquickjs/skeleton/src/builtin/process.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
pub mod native_module {
44
use crate::internal::{format_caught_error, get_js_state};
55
use rquickjs::function::Args;
6-
use rquickjs::{CatchResultExt, Function, Persistent, Value, async_with};
6+
use rquickjs::{CatchResultExt, Ctx, Function, Persistent, Value, async_with};
77
use std::collections::HashMap;
88

99
#[rquickjs::function]
@@ -18,11 +18,13 @@ pub mod native_module {
1818

1919
#[rquickjs::function]
2020
pub fn next_tick(
21+
ctx: Ctx<'_>,
2122
function: Persistent<Function<'static>>,
2223
args: Persistent<Vec<Value<'static>>>,
2324
) {
2425
let state = get_js_state();
2526

27+
println!("add_next_tick_callback");
2628
state.add_next_tick_callback(Box::new(move || {
2729
Box::pin(next_tick_callback(function, args))
2830
}))

crates/wasm-rquickjs/skeleton/src/builtin/timeout.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use crate::internal::{format_caught_error, sleep};
1+
use crate::internal::format_caught_error;
22
use rquickjs::function::Args;
33
use rquickjs::{CatchResultExt, Ctx, Persistent, Value};
4-
use std::time::Duration;
54

65
// Native functions for the timeout implementation
76
#[rquickjs::module]
@@ -73,24 +72,18 @@ async fn scheduled_task(
7372
run_scheduled_task(ctx.clone(), code_or_fn.clone(), args.clone())
7473
.catch(&ctx)
7574
.unwrap_or_else(|e| {
76-
panic!(
77-
"Failed to run scheduled task:\n{}",
78-
format_caught_error(e)
79-
)
75+
panic!("Failed to run scheduled task:\n{}", format_caught_error(e))
8076
});
8177
} else {
82-
let duration = Duration::from_millis(delay as u64);
78+
let duration = wstd::time::Duration::from_millis(delay as u64);
8379

8480
loop {
85-
sleep(duration).await;
81+
wstd::task::sleep(duration).await;
8682

8783
run_scheduled_task(ctx.clone(), code_or_fn.clone(), args.clone())
8884
.catch(&ctx)
8985
.unwrap_or_else(|e| {
90-
panic!(
91-
"Failed to run scheduled task:\n{}",
92-
format_caught_error(e)
93-
)
86+
panic!("Failed to run scheduled task:\n{}", format_caught_error(e))
9487
});
9588

9689
if !periodic {

crates/wasm-rquickjs/skeleton/src/internal.rs

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@ use std::collections::{HashMap, VecDeque};
1212
use std::future::Future;
1313
use std::pin::Pin;
1414
use std::sync::atomic::AtomicUsize;
15-
use std::time::Duration;
16-
use wasi::clocks::monotonic_clock::subscribe_duration;
17-
use wasi_async_runtime::{Reactor, block_on};
15+
use wstd::runtime::block_on;
1816

1917
pub const RESOURCE_TABLE_NAME: &str = "__wasm_rquickjs_resources";
2018
pub const RESOURCE_ID_KEY: &str = "__wasm_rquickjs_resource_id";
2119
pub const DISPOSE_SYMBOL: &str = "__wasm_rquickjs_symbol_dispose";
2220

2321
pub struct JsState {
24-
pub reactor: RefCell<Option<Reactor>>,
2522
pub rt: AsyncRuntime,
2623
pub ctx: AsyncContext,
2724
pub last_resource_id: AtomicUsize,
@@ -30,7 +27,7 @@ pub struct JsState {
3027
pub abort_handles: RefCell<HashMap<usize, AbortHandle>>,
3128
pub last_abort_id: AtomicUsize,
3229
next_tick_queue:
33-
RefCell<VecDeque<Box<dyn FnOnce() -> Pin<Box<dyn Future<Output = ()> + 'static>>>>>,
30+
RefCell<VecDeque<Box<dyn FnOnce() -> Pin<Box<dyn Future<Output=()> + 'static>>>>>,
3431
}
3532

3633
impl Default for JsState {
@@ -41,7 +38,7 @@ impl Default for JsState {
4138

4239
impl JsState {
4340
pub fn new() -> Self {
44-
block_on(|_reactor| async {
41+
block_on(async {
4542
let rt = AsyncRuntime::new().expect("Failed to create AsyncRuntime");
4643
let ctx = AsyncContext::full(&rt)
4744
.await
@@ -126,7 +123,6 @@ impl JsState {
126123

127124
let last_resource_id = AtomicUsize::new(1);
128125
Self {
129-
reactor: RefCell::new(None),
130126
rt,
131127
ctx,
132128
last_resource_id,
@@ -141,31 +137,35 @@ impl JsState {
141137

142138
pub fn add_next_tick_callback(
143139
&self,
144-
callback: Box<dyn FnOnce() -> Pin<Box<dyn Future<Output = ()> + 'static>>>,
140+
callback: Box<dyn FnOnce() -> Pin<Box<dyn Future<Output=()> + 'static>>>,
145141
) {
146142
self.next_tick_queue.borrow_mut().push_back(callback);
147143
}
148144

149145
fn pop_next_tick_callback(
150146
&self,
151-
) -> Option<Box<dyn FnOnce() -> Pin<Box<dyn Future<Output = ()> + 'static>>>> {
147+
) -> Option<Box<dyn FnOnce() -> Pin<Box<dyn Future<Output=()> + 'static>>>> {
152148
let result = self.next_tick_queue.borrow_mut().pop_front();
153149
result
154150
}
155151

156152
pub async fn idle(&self) {
157-
let mut n = 0;
153+
let mut n;
158154

159155
loop {
160156
n = 0;
161157

162158
while let Some(f) = self.pop_next_tick_callback() {
159+
println!("** CALLING NEXT_TICK CALLBACK");
163160
f().await;
164161
n += 1;
165162
}
166163

164+
println!("** CALLING RT.IDLE");
167165
self.rt.idle().await;
168166

167+
println!("** IDLE DONE {n}");
168+
169169
if n == 0 {
170170
break;
171171
}
@@ -188,10 +188,10 @@ pub fn get_js_state() -> &'static JsState {
188188
pub fn async_exported_function<F: Future>(future: F) -> F::Output {
189189
let js_state = get_js_state();
190190

191-
block_on(|reactor| async move {
191+
block_on(async move {
192192
use futures::StreamExt;
193193

194-
js_state.reactor.replace(Some(reactor));
194+
println!("async_exported_function start");
195195
if let Some(mut resource_drop_queue_rx) = js_state.resource_drop_queue_rx.take() {
196196
let resource_dropper = async move {
197197
while let Some(resource_id) = resource_drop_queue_rx.next().await {
@@ -214,6 +214,8 @@ pub fn async_exported_function<F: Future>(future: F) -> F::Output {
214214
.resource_drop_queue_rx
215215
.replace(Some(resource_drop_queue_rx));
216216

217+
println!("async_exported_function end");
218+
217219
result
218220
} else {
219221
// This case will never happen because block_on does not allow reentry
@@ -251,7 +253,7 @@ where
251253
.map(|e| crate::wrappers::JsResult(Err(e)))
252254
},
253255
)
254-
.await
256+
.await
255257
}
256258

257259
async fn call_js_export_internal<A, R, FR, TME>(
@@ -303,6 +305,8 @@ where
303305
if value.is_promise() {
304306
let promise: Promise = value.into_promise().unwrap();
305307
let promise_future = promise.into_future::<R> ();
308+
println!("promise future await start");
309+
306310
match promise_future.await {
307311
Ok(result) => {
308312
map_result(result)
@@ -332,7 +336,9 @@ where
332336
}
333337
}
334338
}).await;
339+
println!("async_with finished, before idle");
335340
js_state.idle().await;
341+
println!("after idle");
336342
result
337343
}
338344

@@ -416,7 +422,7 @@ where
416422
|a| a,
417423
|_, _| None,
418424
)
419-
.await
425+
.await
420426
}
421427

422428
pub async fn call_js_resource_method_returning_result<A, R, E>(
@@ -444,7 +450,7 @@ where
444450
.map(|e| crate::wrappers::JsResult(Err(e)))
445451
},
446452
)
447-
.await
453+
.await
448454
}
449455

450456
async fn call_js_resource_method_internal<A, R, FR, TME>(
@@ -552,14 +558,6 @@ pub fn enqueue_drop_js_resource(resource_id: usize) {
552558
.expect("Failed to enqueue resource drop");
553559
}
554560

555-
pub async fn sleep(duration: Duration) {
556-
let js_state = get_js_state();
557-
let reactor = js_state.reactor.borrow().clone().unwrap();
558-
559-
let pollable = subscribe_duration(duration.as_nanos() as u64);
560-
reactor.wait_for(pollable).await;
561-
}
562-
563561
async fn drop_js_resource(resource_id: usize) {
564562
let js_state = get_js_state();
565563

@@ -570,7 +568,7 @@ async fn drop_js_resource(resource_id: usize) {
570568
panic!("Failed to delete resource {resource_id}: {e:?}");
571569
}
572570
})
573-
.await;
571+
.await;
574572
js_state.idle().await;
575573
}
576574

@@ -700,9 +698,9 @@ pub fn format_js_exception(exc: &Value) -> String {
700698
.unwrap_or_else(|| {
701699
let formatted_exc = pretty_stringify_or_debug_print(&exc);
702700
if formatted_exc.contains("\n") {
703-
format!("JavaScript exception:\n{formatted_exc}",)
701+
format!("JavaScript exception:\n{formatted_exc}", )
704702
} else {
705-
format!("JavaScript exception: {formatted_exc}",)
703+
format!("JavaScript exception: {formatted_exc}", )
706704
}
707705
})
708706
}

crates/wasm-rquickjs/src/imports.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,12 +446,9 @@ fn generate_import_module(
446446
{
447447
special_methods.push(quote! {
448448
pub async fn promise(&mut self) -> () {
449-
let js_state = crate::internal::get_js_state();
450-
let reactor = js_state.reactor.borrow().clone().unwrap();
451-
452449
let pollable = self.inner.take().expect("Resource has already been disposed");
453450
let pollable: wasi::io::poll::Pollable = unsafe { wasi::io::poll::Pollable::from_handle(pollable.take_handle()) };
454-
reactor.wait_for(pollable).await;
451+
wstd::runtime::AsyncPollable::new(pollable).wait_for().await;
455452
}
456453
});
457454
}

tests/runtime.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -939,23 +939,11 @@ async fn timeout_3(#[tagged_as("timeout")] compiled: &CompiledTest) -> anyhow::R
939939
output,
940940
indoc!(
941941
r#"
942-
timeout test starts
943-
Message from setImmediate #1
944-
Message from setImmediate #2
945-
This is a repeated message every 250ms
946-
This is a repeated message every 250ms
947-
This is a repeated message every 250ms
948-
This is a delayed message after 1s, with params x, 100
949-
This is a repeated message every 250ms
950-
This is a repeated message every 250ms
951-
This is a repeated message every 250ms
952-
This is a repeated message every 250ms
953-
This is a delayed message after 2s
954-
This is a repeated message every 250ms
955-
This is a repeated message every 250ms
956-
This is a repeated message every 250ms
957-
This is a repeated message every 250ms
958-
This is a followup delayed message after 1s
942+
start
943+
end
944+
nextTick callback 1
945+
nextTick callback 2
946+
setImmediate callback 1
959947
"#
960948
)
961949
);

0 commit comments

Comments
 (0)