Skip to content

Commit

Permalink
feat(plugin_runner): shared runtime engine
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj committed Jun 27, 2023
1 parent ed9a4ae commit 0f251e6
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 36 deletions.
9 changes: 5 additions & 4 deletions crates/swc_plugin_runner/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ use wasmer::{Module, Store};
#[cfg(all(not(target_arch = "wasm32"), feature = "filesystem_cache"))]
use wasmer_cache::{Cache as WasmerCache, FileSystemCache, Hash};

use crate::plugin_module_bytes::{
CompiledPluginModuleBytes, PluginModuleBytes, RawPluginModuleBytes,
use crate::{
plugin_module_bytes::{CompiledPluginModuleBytes, PluginModuleBytes, RawPluginModuleBytes},
wasix_runtime::new_store,
};

/// Version for bytecode cache stored in local filesystem.
Expand Down Expand Up @@ -114,7 +115,7 @@ impl PluginModuleCacheInner {
// If FilesystemCache is available, store serialized bytes into fs.
if let Some(fs_cache_store) = &mut self.fs_cache_store {
let module_bytes_hash = Hash::generate(&raw_module_bytes);
let store = crate::plugin_module_bytes::new_store();
let store = new_store();
let module = Module::new(&store, raw_module_bytes.clone())
.context("Cannot compile plugin binary")?;
fs_cache_store.store(module_bytes_hash, &module)?;
Expand Down Expand Up @@ -154,7 +155,7 @@ impl PluginModuleCacheInner {
#[cfg(all(not(target_arch = "wasm32"), feature = "filesystem_cache"))]
if let Some(fs_cache_store) = &self.fs_cache_store {
let hash = self.fs_cache_hash_store.get(key)?;
let store = crate::plugin_module_bytes::new_store();
let store = new_store();
let module = unsafe { fs_cache_store.load(&store, *hash) };
if let Ok(module) = module {
return Some(Box::new(CompiledPluginModuleBytes::new(
Expand Down
31 changes: 1 addition & 30 deletions crates/swc_plugin_runner/src/plugin_module_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,7 @@ use anyhow::Error;
use serde::{Deserialize, Serialize};
use wasmer::{Module, Store};

/// Creates an instnace of [Store].
///
/// This function exists because we need to disable simd.
#[cfg(not(target_arch = "wasm32"))]
#[allow(unused_mut)]
pub(crate) fn new_store() -> Store {
// Use empty enumset to disable simd.
use enumset::EnumSet;
use wasmer::{BaseTunables, CompilerConfig, EngineBuilder, Target, Triple};
let mut set = EnumSet::new();

// [TODO]: Should we use is_x86_feature_detected! macro instead?
#[cfg(target_arch = "x86_64")]
set.insert(wasmer::CpuFeature::SSE2);
let target = Target::new(Triple::host(), set);

let config = wasmer_compiler_cranelift::Cranelift::default();
let mut engine = EngineBuilder::new(Box::new(config) as Box<dyn CompilerConfig>)
.set_target(Some(target))
.engine();
let tunables = BaseTunables::for_target(engine.target());
engine.set_tunables(tunables);

Store::new(engine)
}

#[cfg(target_arch = "wasm32")]
fn new_store() -> Store {
Store::default()
}
use crate::wasix_runtime::new_store;

// A trait abstracts plugin's wasm compilation and instantiation.
// Depends on the caller, this could be a simple clone from existing module, or
Expand Down
56 changes: 54 additions & 2 deletions crates/swc_plugin_runner/src/wasix_runtime.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,36 @@
use std::{path::PathBuf, sync::Arc};

use parking_lot::Mutex;
use swc_common::sync::{Lazy, OnceCell};
use wasmer::Store;
use wasmer_wasix::Runtime;

/// A shared instance to plugin runtime engine.
/// ref: https://github.com/wasmerio/wasmer/issues/3793#issuecomment-1607117480
static ENGINE: Lazy<OnceCell<Mutex<wasmer::Engine>>> = Lazy::new(|| {
// Use empty enumset to disable simd.
use enumset::EnumSet;
use wasmer::{BaseTunables, CompilerConfig, EngineBuilder, Target, Triple};
let mut set = EnumSet::new();

// [TODO]: Should we use is_x86_feature_detected! macro instead?
#[cfg(target_arch = "x86_64")]
set.insert(wasmer::CpuFeature::SSE2);
let target = Target::new(Triple::host(), set);

let config = wasmer_compiler_cranelift::Cranelift::default();
let mut engine = EngineBuilder::new(Box::new(config) as Box<dyn CompilerConfig>)
.set_target(Some(target))
.engine();
let tunables = BaseTunables::for_target(engine.target());
engine.set_tunables(tunables);
OnceCell::with_value(parking_lot::Mutex::new(wasmer::Engine::from(engine)))
});

/// Dummy http client for wasix runtime to avoid instantiation failure for the
/// default pluggable runtime. We don't support network in the host runtime
/// anyway (we init vnet instead), and for the default runtime mostly it's for
/// the wapm registry which is redundant for the plugin.
#[derive(Debug)]
struct StubHttpClient;

Expand Down Expand Up @@ -38,11 +67,16 @@ pub fn build_wasi_runtime(
SharedCache::default().with_fallback(wasmer_wasix::runtime::module_cache::in_memory());

let dummy_loader = BuiltinPackageLoader::new_with_client(".", Arc::new(StubHttpClient));

let rt = PluggableRuntime {
rt: Arc::new(TokioTaskManager::shared()),
networking: Arc::new(virtual_net::UnsupportedVirtualNetworking::default()),
engine: Some(wasmer::Engine::default()),
engine: Some(
ENGINE
.get()
.expect("Engine should be initialized all time")
.lock()
.clone(),
),
tty: None,
source: Arc::new(MultiSource::new()),
module_cache: Arc::new(cache),
Expand All @@ -52,3 +86,21 @@ pub fn build_wasi_runtime(

Some(Arc::new(rt))
}

/// Creates an instnace of [Store] with custom engine instead of default one to
/// disable simd for certain platform targets
#[cfg(not(target_arch = "wasm32"))]
#[allow(unused_mut)]
pub(crate) fn new_store() -> Store {
let engine = ENGINE
.get()
.expect("Engine should be initialized all time")
.lock()
.clone();
Store::new(engine)
}

#[cfg(target_arch = "wasm32")]
pub(crate) fn new_store() -> Store {
Store::default()
}

0 comments on commit 0f251e6

Please sign in to comment.