Switch from epoch to fuel

Isaac Clayton created

Change summary

crates/plugin_runtime/build.rs              |  2 
crates/plugin_runtime/src/lib.rs            |  4 -
crates/plugin_runtime/src/plugin.rs         | 44 ++++------------------
crates/zed/src/languages/language_plugin.rs |  3 -
4 files changed, 12 insertions(+), 41 deletions(-)

Detailed changes

crates/plugin_runtime/build.rs 🔗

@@ -60,7 +60,7 @@ fn main() {
 fn create_default_engine() -> Engine {
     let mut config = Config::default();
     config.async_support(true);
-    config.epoch_interruption(true);
+    config.consume_fuel(true);
     Engine::new(&config).expect("Could not create engine")
 }
 

crates/plugin_runtime/src/lib.rs 🔗

@@ -23,7 +23,7 @@ mod tests {
         }
 
         async {
-            let (mut runtime, incrementer) = PluginBuilder::new_with_default_ctx()
+            let mut runtime = PluginBuilder::new_with_default_ctx()
                 .unwrap()
                 .host_function("mystery_number", |input: u32| input + 7)
                 .unwrap()
@@ -53,8 +53,6 @@ mod tests {
                 .await
                 .unwrap();
 
-            std::thread::spawn(move || incrementer.block_on());
-
             let plugin = TestPlugin {
                 noop: runtime.function("noop").unwrap(),
                 constant: runtime.function("constant").unwrap(),

crates/plugin_runtime/src/plugin.rs 🔗

@@ -62,8 +62,7 @@ pub struct PluginBuilder {
     wasi_ctx: WasiCtx,
     engine: Engine,
     linker: Linker<WasiCtxAlloc>,
-    delta: u64,
-    epoch: std::time::Duration,
+    fuel_refill: u64,
 }
 
 /// Creates a default engine for compiling Wasm.
@@ -73,7 +72,7 @@ pub struct PluginBuilder {
 pub fn create_default_engine() -> Result<Engine, Error> {
     let mut config = Config::default();
     config.async_support(true);
-    config.epoch_interruption(true);
+    config.consume_fuel(true);
     Engine::new(&config)
 }
 
@@ -88,8 +87,7 @@ impl PluginBuilder {
             wasi_ctx,
             engine,
             linker,
-            delta: 1,
-            epoch: std::time::Duration::from_millis(100),
+            fuel_refill: 1000,
         })
     }
 
@@ -245,17 +243,7 @@ impl PluginBuilder {
 
     /// Initializes a [`Plugin`] from a given compiled Wasm module.
     /// Both binary (`.wasm`) and text (`.wat`) module formats are supported.
-    pub async fn init<T: AsRef<[u8]>>(
-        self,
-        precompiled: bool,
-        module: T,
-    ) -> Result<
-        (
-            Plugin,
-            std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
-        ),
-        Error,
-    > {
+    pub async fn init<T: AsRef<[u8]>>(self, precompiled: bool, module: T) -> Result<Plugin, Error> {
         Plugin::init(precompiled, module.as_ref().to_vec(), self).await
     }
 }
@@ -320,13 +308,7 @@ impl Plugin {
         precompiled: bool,
         module: Vec<u8>,
         plugin: PluginBuilder,
-    ) -> Result<
-        (
-            Self,
-            std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
-        ),
-        Error,
-    > {
+    ) -> Result<Self, Error> {
         // initialize the WebAssembly System Interface context
         let engine = plugin.engine;
         let mut linker = plugin.linker;
@@ -348,15 +330,9 @@ impl Plugin {
             Module::new(&engine, module)?
         };
 
-        // set up automatic yielding after given duration
-        store.epoch_deadline_async_yield_and_update(plugin.delta);
-        let epoch = plugin.epoch;
-        let incrementer = Box::pin(async move {
-            loop {
-                smol::Timer::after(epoch).await;
-                engine.increment_epoch();
-            }
-        });
+        // set up automatic yielding after fuel expires
+        store.out_of_fuel_async_yield(u64::MAX, plugin.fuel_refill);
+        store.add_fuel(plugin.fuel_refill).unwrap();
 
         // load the provided module into the asynchronous runtime
         linker.module_async(&mut store, "", &module).await?;
@@ -371,9 +347,7 @@ impl Plugin {
             free_buffer,
         });
 
-        let plugin = Plugin { store, instance };
-
-        Ok((plugin, incrementer))
+        Ok(Plugin { store, instance })
     }
 
     /// Attaches a file or directory the the given system path to the runtime.

crates/zed/src/languages/language_plugin.rs 🔗

@@ -9,7 +9,7 @@ use std::{any::Any, path::PathBuf, sync::Arc};
 use util::ResultExt;
 
 pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
-    let (plugin, incrementer) = PluginBuilder::new_with_default_ctx()?
+    let plugin = PluginBuilder::new_with_default_ctx()?
         .host_function_async("command", |command: String| async move {
             let mut args = command.split(' ');
             let command = args.next().unwrap();
@@ -26,7 +26,6 @@ pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
         )
         .await?;
 
-    executor.spawn(incrementer).detach();
     PluginLspAdapter::new(plugin, executor).await
 }