feat(plugin/runner): Share runtime Engine (#7590)

This commit is contained in:
OJ Kwon 2023-06-28 18:56:55 -07:00 committed by GitHub
parent ed9a4ae5bc
commit 9512ea31ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 36 deletions

View File

@ -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.
@ -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)?;
@ -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(

View File

@ -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

View File

@ -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<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);
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;
@ -38,11 +67,10 @@ 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.lock().clone()),
tty: None,
source: Arc::new(MultiSource::new()),
module_cache: Arc::new(cache),
@ -52,3 +80,17 @@ 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.lock().clone();
Store::new(engine)
}
#[cfg(target_arch = "wasm32")]
pub(crate) fn new_store() -> Store {
Store::default()
}