diff options
Diffstat (limited to 'core/runtime.rs')
-rw-r--r-- | core/runtime.rs | 113 |
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); } |