mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
a1764f7690
This is a follow-on to the earlier work in reducing string copies, mainly focused on ensuring that ASCII strings are easy to provide to the JS runtime. While we are replacing a 16-byte reference in a number of places with a 24-byte structure (measured via `std::mem::size_of`), the reduction in copies wins out over the additional size of the arguments passed into functions. Benchmarking shows approximately the same if not slightly less wallclock time/instructions retired, but I believe this continues to open up further refactoring opportunities.
69 lines
1.9 KiB
Rust
69 lines
1.9 KiB
Rust
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
|
|
use deno_core::anyhow::Error;
|
|
use deno_core::op;
|
|
use deno_core::Extension;
|
|
use deno_core::JsRuntime;
|
|
use deno_core::OpState;
|
|
use deno_core::RuntimeOptions;
|
|
use futures::channel::mpsc;
|
|
use futures::stream::StreamExt;
|
|
use std::task::Poll;
|
|
|
|
// This is a hack to make the `#[op]` macro work with
|
|
// deno_core examples.
|
|
// You can remove this:
|
|
use deno_core::*;
|
|
|
|
type Task = Box<dyn FnOnce()>;
|
|
|
|
fn main() {
|
|
let my_ext = Extension::builder("my_ext")
|
|
.ops(vec![op_schedule_task::decl()])
|
|
.event_loop_middleware(|state_rc, cx| {
|
|
let mut state = state_rc.borrow_mut();
|
|
let recv = state.borrow_mut::<mpsc::UnboundedReceiver<Task>>();
|
|
let mut ref_loop = false;
|
|
while let Poll::Ready(Some(call)) = recv.poll_next_unpin(cx) {
|
|
call();
|
|
ref_loop = true; // `call` can callback into runtime and schedule new callbacks :-)
|
|
}
|
|
ref_loop
|
|
})
|
|
.state(move |state| {
|
|
let (tx, rx) = mpsc::unbounded::<Task>();
|
|
state.put(tx);
|
|
state.put(rx);
|
|
})
|
|
.build();
|
|
|
|
// Initialize a runtime instance
|
|
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
|
extensions: vec![my_ext],
|
|
..Default::default()
|
|
});
|
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
|
.enable_all()
|
|
.build()
|
|
.unwrap();
|
|
|
|
let future = async move {
|
|
// Schedule 10 tasks.
|
|
js_runtime
|
|
.execute_script_static(
|
|
"<usage>",
|
|
r#"for (let i = 1; i <= 10; i++) Deno.core.ops.op_schedule_task(i);"#,
|
|
)
|
|
.unwrap();
|
|
js_runtime.run_event_loop(false).await
|
|
};
|
|
runtime.block_on(future).unwrap();
|
|
}
|
|
|
|
#[op]
|
|
fn op_schedule_task(state: &mut OpState, i: u8) -> Result<(), Error> {
|
|
let tx = state.borrow_mut::<mpsc::UnboundedSender<Task>>();
|
|
tx.unbounded_send(Box::new(move || println!("Hello, world! x{i}")))
|
|
.expect("unbounded_send failed");
|
|
Ok(())
|
|
}
|