From 9e9924501d04a5f4d7cbc1abba3dc80133f4444b Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Mon, 24 Jun 2024 16:21:50 -0600 Subject: [PATCH] use explicit targets and target cache --- arbitrator/jit/src/stylus_backend.rs | 12 ++++++-- arbitrator/stylus/src/cache.rs | 13 ++++++++- arbitrator/stylus/src/lib.rs | 42 +++++++++++++++++++++++++++- arbitrator/stylus/src/native.rs | 10 ++++--- arbitrator/stylus/src/test/mod.rs | 11 ++++++-- arbos/programs/native.go | 1 + 6 files changed, 79 insertions(+), 10 deletions(-) diff --git a/arbitrator/jit/src/stylus_backend.rs b/arbitrator/jit/src/stylus_backend.rs index 61dbf258d4..cb0440a257 100644 --- a/arbitrator/jit/src/stylus_backend.rs +++ b/arbitrator/jit/src/stylus_backend.rs @@ -24,6 +24,7 @@ use std::{ thread::JoinHandle, }; use stylus::{native::NativeInstance, run::RunProgram}; +use wasmer::Target; struct MessageToCothread { result: Vec, @@ -143,8 +144,15 @@ pub fn exec_wasm( let evm_api = EvmApiRequestor::new(cothread); - let mut instance = - unsafe { NativeInstance::deserialize(&module, compile.clone(), evm_api, evm_data) }?; + let mut instance = unsafe { + NativeInstance::deserialize( + &module, + compile.clone(), + evm_api, + evm_data, + Target::default(), + ) + }?; let thread = thread::spawn(move || { let outcome = instance.run_main(&calldata, config, ink); diff --git a/arbitrator/stylus/src/cache.rs b/arbitrator/stylus/src/cache.rs index 180b61e9ee..62db786ac0 100644 --- a/arbitrator/stylus/src/cache.rs +++ b/arbitrator/stylus/src/cache.rs @@ -23,6 +23,7 @@ macro_rules! cache { pub struct InitCache { long_term: HashMap, lru: LruCache, + target: Target, } #[derive(Clone, Copy, Hash, PartialEq, Eq)] @@ -68,6 +69,7 @@ impl InitCache { Self { long_term: HashMap::new(), lru: LruCache::new(NonZeroUsize::new(size).unwrap()), + target: Target::default(), } } @@ -77,6 +79,14 @@ impl InitCache { .resize(NonZeroUsize::new(size.try_into().unwrap()).unwrap()) } + pub fn set_target(target: Target) { + cache!().target = target; + } + + pub fn target() -> Target { + cache!().target.clone() + } + /// Retrieves a cached value, updating items as necessary. pub fn get(module_hash: Bytes32, version: u16, debug: bool) -> Option<(Module, Store)> { let mut cache = cache!(); @@ -118,9 +128,10 @@ impl InitCache { } return Ok(item.data()); } + let target = cache.target.clone(); drop(cache); - let engine = CompileConfig::version(version, debug).engine(Target::default()); + let engine = CompileConfig::version(version, debug).engine(target); let module = unsafe { Module::deserialize_unchecked(&engine, module)? }; let item = CacheItem::new(module, engine); diff --git a/arbitrator/stylus/src/lib.rs b/arbitrator/stylus/src/lib.rs index 7e2c45f63f..2929821433 100644 --- a/arbitrator/stylus/src/lib.rs +++ b/arbitrator/stylus/src/lib.rs @@ -18,6 +18,7 @@ use native::NativeInstance; use prover::programs::{prelude::*, StylusData}; use run::RunProgram; use std::{marker::PhantomData, mem, ptr}; +use target_cache::{target_cache_get, target_cache_set}; pub use brotli; pub use prover; @@ -29,6 +30,7 @@ pub mod run; mod cache; mod evm_api; +mod target_cache; mod util; #[cfg(test)] @@ -176,12 +178,18 @@ pub unsafe extern "C" fn stylus_compile( wasm: GoSliceData, version: u16, debug: bool, + name: GoSliceData, output: *mut RustBytes, ) -> UserOutcomeKind { let wasm = wasm.slice(); let output = &mut *output; + let name = String::from_utf8_unchecked(name.slice().to_vec()); + let target = match target_cache_get(&name) { + Ok(val) => val, + Err(err) => return output.write_err(err), + }; - let asm = match native::compile(wasm, version, debug) { + let asm = match native::compile(wasm, version, debug, target) { Ok(val) => val, Err(err) => return output.write_err(err), }; @@ -190,6 +198,38 @@ pub unsafe extern "C" fn stylus_compile( UserOutcomeKind::Success } +/// sets target index to a string +/// +/// String format is: Triple+CpuFeature+CpuFeature.. +/// +/// # Safety +/// +/// `output` must not be null. +#[no_mangle] +pub unsafe extern "C" fn stylus_target_set( + name: GoSliceData, + description: GoSliceData, + output: *mut RustBytes, + native: bool, +) -> UserOutcomeKind { + let output = &mut *output; + let name = match String::from_utf8(name.slice().to_vec()) { + Ok(val) => val, + Err(err) => return output.write_err(err.into()), + }; + + let desc_str = match String::from_utf8(description.slice().to_vec()) { + Ok(val) => val, + Err(err) => return output.write_err(err.into()), + }; + + if let Err(err) = target_cache_set(name, desc_str, native) { + return output.write_err(err); + }; + + UserOutcomeKind::Success +} + /// Calls an activated user program. /// /// # Safety diff --git a/arbitrator/stylus/src/native.rs b/arbitrator/stylus/src/native.rs index f8d2a481a4..21646a0e71 100644 --- a/arbitrator/stylus/src/native.rs +++ b/arbitrator/stylus/src/native.rs @@ -96,9 +96,10 @@ impl> NativeInstance { compile: CompileConfig, evm: E, evm_data: EvmData, + target: Target, ) -> Result { let env = WasmEnv::new(compile, None, evm, evm_data); - let store = env.compile.store(Target::default()); + let store = env.compile.store(target); let module = unsafe { Module::deserialize_unchecked(&store, module)? }; Self::from_module(module, store, env) } @@ -137,9 +138,10 @@ impl> NativeInstance { evm_data: EvmData, compile: &CompileConfig, config: StylusConfig, + target: Target, ) -> Result { let env = WasmEnv::new(compile.clone(), Some(config), evm_api, evm_data); - let store = env.compile.store(Target::default()); + let store = env.compile.store(target); let wat_or_wasm = std::fs::read(path)?; let module = Module::new(&store, wat_or_wasm)?; Self::from_module(module, store, env) @@ -448,9 +450,9 @@ pub fn activate( Ok((module, stylus_data)) } -pub fn compile(wasm: &[u8], version: u16, debug: bool) -> Result> { +pub fn compile(wasm: &[u8], version: u16, debug: bool, target: Target) -> Result> { let compile = CompileConfig::version(version, debug); - let asm = match self::module(wasm, compile, Target::default()) { + let asm = match self::module(wasm, compile, target) { Ok(asm) => asm, Err(err) => util::panic_with_wasm(wasm, err), }; diff --git a/arbitrator/stylus/src/test/mod.rs b/arbitrator/stylus/src/test/mod.rs index d7f3248d31..cfc0ab23b7 100644 --- a/arbitrator/stylus/src/test/mod.rs +++ b/arbitrator/stylus/src/test/mod.rs @@ -16,7 +16,7 @@ use rand::prelude::*; use std::{collections::HashMap, path::Path, sync::Arc}; use wasmer::{ imports, wasmparser::Operator, CompilerConfig, Function, FunctionEnv, Imports, Instance, - Module, Store, + Module, Store, Target, }; use wasmer_compiler_singlepass::Singlepass; @@ -86,7 +86,14 @@ impl TestInstance { config: StylusConfig, ) -> Result<(Self, TestEvmApi)> { let (mut evm, evm_data) = TestEvmApi::new(compile.clone()); - let native = Self::from_path(path, evm.clone(), evm_data, compile, config)?; + let native = Self::from_path( + path, + evm.clone(), + evm_data, + compile, + config, + Target::default(), + )?; let footprint = native.memory().ty(&native.store).minimum.0 as u16; evm.set_pages(footprint); Ok((native, evm)) diff --git a/arbos/programs/native.go b/arbos/programs/native.go index 53d8f64022..0de63009ac 100644 --- a/arbos/programs/native.go +++ b/arbos/programs/native.go @@ -104,6 +104,7 @@ func activateProgramInternal( goSlice(wasm), u16(version), cbool(debug), + goSlice([]byte{}), output, ))