summaryrefslogtreecommitdiff
path: root/core/runtime.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/runtime.rs')
-rw-r--r--core/runtime.rs113
1 files changed, 59 insertions, 54 deletions
diff --git a/core/runtime.rs b/core/runtime.rs
index ac0e812b7..f04788d4e 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -453,55 +453,51 @@ impl JsRuntime {
.remove_near_heap_limit_callback(cb, heap_limit);
}
}
-}
-extern "C" fn near_heap_limit_callback<F>(
- data: *mut c_void,
- current_heap_limit: usize,
- initial_heap_limit: usize,
-) -> usize
-where
- F: FnMut(usize, usize) -> usize,
-{
- let callback = unsafe { &mut *(data as *mut F) };
- callback(current_heap_limit, initial_heap_limit)
-}
-
-impl Future for JsRuntime {
- type Output = Result<(), AnyError>;
+ /// Runs event loop to completion
+ ///
+ /// This future resolves when:
+ /// - there are no more pending dynamic imports
+ /// - there are no more pending ops
+ pub async fn run_event_loop(&mut self) -> Result<(), AnyError> {
+ poll_fn(|cx| self.poll_event_loop(cx)).await
+ }
- fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
- let runtime = self.get_mut();
- runtime.shared_init();
+ /// Runs a single tick of event loop
+ pub fn poll_event_loop(
+ &mut self,
+ cx: &mut Context,
+ ) -> Poll<Result<(), AnyError>> {
+ self.shared_init();
- let state_rc = Self::state(runtime.v8_isolate());
+ let state_rc = Self::state(self.v8_isolate());
{
let state = state_rc.borrow();
state.waker.register(cx.waker());
}
// Top level modules
- runtime.poll_mod_evaluate(cx)?;
+ self.evaluate_pending_modules()?;
// Dynamic module loading - ie. modules loaded using "import()"
{
- let poll_imports = runtime.prepare_dyn_imports(cx)?;
+ let poll_imports = self.prepare_dyn_imports(cx)?;
assert!(poll_imports.is_ready());
- let poll_imports = runtime.poll_dyn_imports(cx)?;
+ let poll_imports = self.poll_dyn_imports(cx)?;
assert!(poll_imports.is_ready());
- runtime.poll_dyn_imports_evaluate(cx)?;
+ self.evaluate_dyn_imports()?;
- runtime.check_promise_exceptions()?;
+ self.check_promise_exceptions()?;
}
// Ops
{
- let overflow_response = runtime.poll_pending_ops(cx);
- runtime.async_op_response(overflow_response)?;
- runtime.drain_macrotasks()?;
- runtime.check_promise_exceptions()?;
+ let overflow_response = self.poll_pending_ops(cx);
+ self.async_op_response(overflow_response)?;
+ self.drain_macrotasks()?;
+ self.check_promise_exceptions()?;
}
let state = state_rc.borrow();
@@ -527,6 +523,18 @@ impl Future for JsRuntime {
}
}
+extern "C" fn near_heap_limit_callback<F>(
+ data: *mut c_void,
+ current_heap_limit: usize,
+ initial_heap_limit: usize,
+) -> usize
+where
+ F: FnMut(usize, usize) -> usize,
+{
+ let callback = unsafe { &mut *(data as *mut F) };
+ callback(current_heap_limit, initial_heap_limit)
+}
+
impl JsRuntimeState {
// Called by V8 during `Isolate::mod_instantiate`.
pub fn module_resolve_cb(
@@ -859,7 +867,7 @@ impl JsRuntime {
debug!("received module evaluate");
return Poll::Ready(result.unwrap());
}
- let _r = self.poll_unpin(cx)?;
+ let _r = self.poll_event_loop(cx)?;
Poll::Pending
})
.await
@@ -1030,7 +1038,7 @@ impl JsRuntime {
}
}
- fn poll_mod_evaluate(&mut self, _cx: &mut Context) -> Result<(), AnyError> {
+ fn evaluate_pending_modules(&mut self) -> Result<(), AnyError> {
let state_rc = Self::state(self.v8_isolate());
let context = self.global_context();
@@ -1074,10 +1082,7 @@ impl JsRuntime {
Ok(())
}
- fn poll_dyn_imports_evaluate(
- &mut self,
- _cx: &mut Context,
- ) -> Result<(), AnyError> {
+ fn evaluate_dyn_imports(&mut self) -> Result<(), AnyError> {
let state_rc = Self::state(self.v8_isolate());
loop {
@@ -1440,13 +1445,13 @@ pub mod tests {
futures::executor::block_on(lazy(move |cx| f(cx)));
}
- fn poll_until_ready<F>(future: &mut F, max_poll_count: usize) -> F::Output
- where
- F: Future + Unpin,
- {
+ fn poll_until_ready(
+ runtime: &mut JsRuntime,
+ max_poll_count: usize,
+ ) -> Result<(), AnyError> {
let mut cx = Context::from_waker(futures::task::noop_waker_ref());
for _ in 0..max_poll_count {
- match future.poll_unpin(&mut cx) {
+ match runtime.poll_event_loop(&mut cx) {
Poll::Pending => continue,
Poll::Ready(val) => return val,
}
@@ -1662,7 +1667,7 @@ pub mod tests {
)
.unwrap();
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
- assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Ready(Ok(_))));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
runtime
.execute(
@@ -1675,11 +1680,11 @@ pub mod tests {
)
.unwrap();
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
- assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Ready(Ok(_))));
runtime.execute("check3.js", "assert(nrecv == 2)").unwrap();
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
// We are idle, so the next poll should be the last.
- assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Ready(Ok(_))));
});
}
@@ -1703,7 +1708,7 @@ pub mod tests {
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
// The above op never finish, but runtime can finish
// because the op is an unreffed async op.
- assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Ready(Ok(_))));
})
}
@@ -1833,7 +1838,7 @@ pub mod tests {
)
.unwrap();
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
- assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Ready(Ok(_))));
runtime
.execute("check.js", "assert(asyncRecv == 1);")
.unwrap();
@@ -1925,7 +1930,7 @@ pub mod tests {
"#,
)
.unwrap();
- if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
+ if let Poll::Ready(Err(_)) = runtime.poll_event_loop(&mut cx) {
unreachable!();
}
});
@@ -1938,7 +1943,7 @@ pub mod tests {
runtime
.execute("core_test.js", include_str!("core_test.js"))
.unwrap();
- if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
+ if let Poll::Ready(Err(_)) = runtime.poll_event_loop(&mut cx) {
unreachable!();
}
});
@@ -1964,7 +1969,7 @@ pub mod tests {
include_str!("encode_decode_test.js"),
)
.unwrap();
- if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
+ if let Poll::Ready(Err(_)) = runtime.poll_event_loop(&mut cx) {
unreachable!();
}
});
@@ -2272,7 +2277,7 @@ pub mod tests {
assert_eq!(count.load(Ordering::Relaxed), 0);
// We should get an error here.
- let result = runtime.poll_unpin(cx);
+ let result = runtime.poll_event_loop(cx);
if let Poll::Ready(Ok(_)) = result {
unreachable!();
}
@@ -2365,14 +2370,14 @@ pub mod tests {
.unwrap();
// First poll runs `prepare_load` hook.
- assert!(matches!(runtime.poll_unpin(cx), Poll::Pending));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Pending));
assert_eq!(prepare_load_count.load(Ordering::Relaxed), 1);
// Second poll actually loads modules into the isolate.
- assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Ready(Ok(_))));
assert_eq!(resolve_count.load(Ordering::Relaxed), 4);
assert_eq!(load_count.load(Ordering::Relaxed), 2);
- assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
+ assert!(matches!(runtime.poll_event_loop(cx), Poll::Ready(Ok(_))));
assert_eq!(resolve_count.load(Ordering::Relaxed), 4);
assert_eq!(load_count.load(Ordering::Relaxed), 2);
})
@@ -2404,10 +2409,10 @@ pub mod tests {
)
.unwrap();
// First poll runs `prepare_load` hook.
- let _ = runtime.poll_unpin(cx);
+ let _ = runtime.poll_event_loop(cx);
assert_eq!(prepare_load_count.load(Ordering::Relaxed), 1);
// Second poll triggers error
- let _ = runtime.poll_unpin(cx);
+ let _ = runtime.poll_event_loop(cx);
})
}
@@ -2538,7 +2543,7 @@ main();
at async error_async_stack.js:10:5
"#;
- match runtime.poll_unpin(cx) {
+ match runtime.poll_event_loop(cx) {
Poll::Ready(Err(e)) => {
assert_eq!(e.to_string(), expected_error);
}