mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-27 03:12:13 +00:00
Update lifetime of function builder references
This commit is contained in:
parent
9f2e068ff4
commit
d440776bc0
@ -13,14 +13,18 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use cranelift_codegen::entity::EntityRef;
|
use cranelift_codegen::entity::EntityRef;
|
||||||
|
use cranelift_codegen::flowgraph::BasicBlock;
|
||||||
use cranelift_codegen::ir::{self, Ebb, Function, InstBuilder, ValueLabel};
|
use cranelift_codegen::ir::{self, Ebb, Function, InstBuilder, ValueLabel};
|
||||||
|
use cranelift_codegen::packed_option::ReservedValue;
|
||||||
use cranelift_codegen::timing;
|
use cranelift_codegen::timing;
|
||||||
use cranelift_codegen::{cursor::FuncCursor, isa};
|
use cranelift_codegen::{cursor::FuncCursor, isa};
|
||||||
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
|
use cranelift_entity::packed_option::PackedOption;
|
||||||
|
use cranelift_frontend::{Block, FunctionBuilder, FunctionBuilderContext, Position, Variable};
|
||||||
use cranelift_wasm::{self, translate_module, FuncTranslator, ModuleEnvironment};
|
use cranelift_wasm::{self, translate_module, FuncTranslator, ModuleEnvironment};
|
||||||
use cranelift_wasm::{get_vmctx_value_label, translate_operator, TranslationState};
|
use cranelift_wasm::{get_vmctx_value_label, translate_operator, TranslationState};
|
||||||
use cranelift_wasm::{FuncEnvironment, ReturnMode, WasmError, WasmResult};
|
use cranelift_wasm::{FuncEnvironment, ReturnMode, WasmError, WasmResult};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasmer_runtime_core::error::CompileError;
|
use wasmer_runtime_core::error::CompileError;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
@ -82,12 +86,7 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
|
|||||||
|
|
||||||
let mut func_translator = FuncTranslator::new();
|
let mut func_translator = FuncTranslator::new();
|
||||||
|
|
||||||
// let func_body = {
|
let func_index = LocalFuncIndex::new(self.functions.len());
|
||||||
|
|
||||||
// let mut func_env = FuncEnv::new(self);
|
|
||||||
|
|
||||||
// TODO should func_index come from self.functions?
|
|
||||||
let func_index = self.func_bodies.next_index();
|
|
||||||
let name = ir::ExternalName::user(0, func_index.index() as u32);
|
let name = ir::ExternalName::user(0, func_index.index() as u32);
|
||||||
|
|
||||||
let sig = generate_signature(
|
let sig = generate_signature(
|
||||||
@ -101,30 +100,25 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
|
|||||||
let mut func = ir::Function::with_name_signature(name, sig);
|
let mut func = ir::Function::with_name_signature(name, sig);
|
||||||
|
|
||||||
//func_translator.translate(body_bytes, body_offset, &mut func, &mut func_env)?;
|
//func_translator.translate(body_bytes, body_offset, &mut func, &mut func_env)?;
|
||||||
// This clears the `FunctionBuilderContext`.
|
|
||||||
|
|
||||||
let mut func_env = CraneliftFunctionCodeGenerator {
|
let mut func_env = CraneliftFunctionCodeGenerator {
|
||||||
builder: None,
|
func,
|
||||||
func_translator,
|
func_translator,
|
||||||
next_local: 0,
|
next_local: 0,
|
||||||
clif_signatures: self.clif_signatures.clone(),
|
clif_signatures: self.clif_signatures.clone(),
|
||||||
module_info: Arc::clone(&module_info),
|
module_info: Arc::clone(&module_info),
|
||||||
target_config: self.isa.frontend_config().clone(),
|
target_config: self.isa.frontend_config().clone(),
|
||||||
|
position: Position::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Coercing lifetime to accommodate FunctionBuilder new
|
debug_assert_eq!(func_env.func.dfg.num_ebbs(), 0, "Function must be empty");
|
||||||
let func_ref =
|
debug_assert_eq!(func_env.func.dfg.num_insts(), 0, "Function must be empty");
|
||||||
unsafe { ::std::mem::transmute::<&mut Function, &'static mut Function>(&mut func) };
|
|
||||||
let func_ctx = unsafe {
|
|
||||||
::std::mem::transmute::<&mut FunctionBuilderContext, &'static mut FunctionBuilderContext>(
|
|
||||||
&mut func_env.func_translator.func_ctx,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let builder = FunctionBuilder::new(func_ref, func_ctx);
|
let mut builder = FunctionBuilder::new(
|
||||||
func_env.builder = Some(builder);
|
&mut func_env.func,
|
||||||
|
&mut func_env.func_translator.func_ctx,
|
||||||
let mut builder = func_env.builder.as_mut().unwrap();
|
&mut func_env.position,
|
||||||
|
);
|
||||||
|
|
||||||
// TODO srcloc
|
// TODO srcloc
|
||||||
//builder.set_srcloc(cur_srcloc(&reader));
|
//builder.set_srcloc(cur_srcloc(&reader));
|
||||||
@ -308,12 +302,6 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
|
|||||||
pos.ins().jump(entry_ebb, new_ebb_params.as_slice());
|
pos.ins().jump(entry_ebb, new_ebb_params.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
// func
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Add function body to list of function bodies.
|
|
||||||
self.func_bodies.push(func);
|
|
||||||
|
|
||||||
self.functions.push(func_env);
|
self.functions.push(func_env);
|
||||||
Ok(self.functions.last_mut().unwrap())
|
Ok(self.functions.last_mut().unwrap())
|
||||||
}
|
}
|
||||||
@ -322,8 +310,13 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
|
|||||||
self,
|
self,
|
||||||
module_info: &ModuleInfo,
|
module_info: &ModuleInfo,
|
||||||
) -> Result<(Caller, Box<dyn CacheGen>), CodegenError> {
|
) -> Result<(Caller, Box<dyn CacheGen>), CodegenError> {
|
||||||
|
let mut func_bodies: Map<LocalFuncIndex, ir::Function> = Map::new();
|
||||||
|
for f in self.functions.into_iter() {
|
||||||
|
func_bodies.push(f.func);
|
||||||
|
}
|
||||||
|
|
||||||
let (func_resolver_builder, handler_data) =
|
let (func_resolver_builder, handler_data) =
|
||||||
FuncResolverBuilder::new(&*self.isa, self.func_bodies, module_info)?;
|
FuncResolverBuilder::new(&*self.isa, func_bodies, module_info)?;
|
||||||
|
|
||||||
let trampolines = Arc::new(Trampolines::new(&*self.isa, module_info));
|
let trampolines = Arc::new(Trampolines::new(&*self.isa, module_info));
|
||||||
|
|
||||||
@ -378,12 +371,13 @@ impl From<CompileError> for CodegenError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct CraneliftFunctionCodeGenerator {
|
pub struct CraneliftFunctionCodeGenerator {
|
||||||
builder: Option<FunctionBuilder<'static>>,
|
func: Function,
|
||||||
func_translator: FuncTranslator,
|
func_translator: FuncTranslator,
|
||||||
next_local: usize,
|
next_local: usize,
|
||||||
pub clif_signatures: Map<SigIndex, ir::Signature>,
|
pub clif_signatures: Map<SigIndex, ir::Signature>,
|
||||||
module_info: Arc<ModuleInfo>,
|
module_info: Arc<ModuleInfo>,
|
||||||
target_config: isa::TargetFrontendConfig,
|
target_config: isa::TargetFrontendConfig,
|
||||||
|
position: Position,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FunctionEnvironment {
|
pub struct FunctionEnvironment {
|
||||||
@ -1088,12 +1082,9 @@ impl FunctionCodeGenerator<CodegenError> for CraneliftFunctionCodeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn feed_local(&mut self, ty: WpType, n: usize) -> Result<(), CodegenError> {
|
fn feed_local(&mut self, ty: WpType, n: usize) -> Result<(), CodegenError> {
|
||||||
cranelift_wasm::declare_locals(
|
let mut next_local = self.next_local;
|
||||||
self.builder.as_mut().unwrap(),
|
cranelift_wasm::declare_locals(&mut self.builder(), n as u32, ty, &mut next_local);
|
||||||
n as u32,
|
self.next_local = next_local;
|
||||||
ty,
|
|
||||||
&mut self.next_local,
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1108,7 +1099,8 @@ impl FunctionCodeGenerator<CodegenError> for CraneliftFunctionCodeGenerator {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let builder = self.builder.as_mut().unwrap();
|
|
||||||
|
//let builder = self.builder.as_mut().unwrap();
|
||||||
//let func_environment = FuncEnv::new();
|
//let func_environment = FuncEnv::new();
|
||||||
//let state = TranslationState::new();
|
//let state = TranslationState::new();
|
||||||
let mut function_environment = FunctionEnvironment {
|
let mut function_environment = FunctionEnvironment {
|
||||||
@ -1116,19 +1108,30 @@ impl FunctionCodeGenerator<CodegenError> for CraneliftFunctionCodeGenerator {
|
|||||||
target_config: self.target_config.clone(),
|
target_config: self.target_config.clone(),
|
||||||
clif_signatures: self.clif_signatures.clone(),
|
clif_signatures: self.clif_signatures.clone(),
|
||||||
};
|
};
|
||||||
translate_operator(
|
|
||||||
op,
|
if (self.func_translator.state.control_stack.is_empty()) {
|
||||||
builder,
|
return Ok(());
|
||||||
&mut self.func_translator.state,
|
}
|
||||||
&mut function_environment,
|
|
||||||
|
let mut builder = FunctionBuilder::new(
|
||||||
|
&mut self.func,
|
||||||
|
&mut self.func_translator.func_ctx,
|
||||||
|
&mut self.position,
|
||||||
);
|
);
|
||||||
|
let state = &mut self.func_translator.state;
|
||||||
|
translate_operator(op, &mut builder, state, &mut function_environment);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize(&mut self) -> Result<(), CodegenError> {
|
fn finalize(&mut self) -> Result<(), CodegenError> {
|
||||||
let return_mode = self.return_mode();
|
let return_mode = self.return_mode();
|
||||||
|
|
||||||
|
let mut builder = FunctionBuilder::new(
|
||||||
|
&mut self.func,
|
||||||
|
&mut self.func_translator.func_ctx,
|
||||||
|
&mut self.position,
|
||||||
|
);
|
||||||
let state = &mut self.func_translator.state;
|
let state = &mut self.func_translator.state;
|
||||||
let builder = self.builder.as_mut().unwrap();
|
|
||||||
|
|
||||||
// The final `End` operator left us in the exit block where we need to manually add a return
|
// The final `End` operator left us in the exit block where we need to manually add a return
|
||||||
// instruction.
|
// instruction.
|
||||||
@ -1149,7 +1152,7 @@ impl FunctionCodeGenerator<CodegenError> for CraneliftFunctionCodeGenerator {
|
|||||||
// or the end of the function is unreachable.
|
// or the end of the function is unreachable.
|
||||||
state.stack.clear();
|
state.stack.clear();
|
||||||
|
|
||||||
self.builder.as_mut().unwrap().finalize();
|
self.builder().finalize();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1172,6 +1175,14 @@ impl CraneliftModuleCodeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CraneliftFunctionCodeGenerator {
|
impl CraneliftFunctionCodeGenerator {
|
||||||
|
pub fn builder(&mut self) -> FunctionBuilder {
|
||||||
|
FunctionBuilder::new(
|
||||||
|
&mut self.func,
|
||||||
|
&mut self.func_translator.func_ctx,
|
||||||
|
&mut self.position,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn return_mode(&self) -> ReturnMode {
|
pub fn return_mode(&self) -> ReturnMode {
|
||||||
ReturnMode::NormalReturns
|
ReturnMode::NormalReturns
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ use std::fmt;
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use wasmparser::{self, WasmDecoder};
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -118,6 +119,20 @@ impl<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate(bytes: &[u8]) -> CompileResult<()> {
|
||||||
|
let mut parser = wasmparser::ValidatingParser::new(bytes, None);
|
||||||
|
loop {
|
||||||
|
let state = parser.read();
|
||||||
|
match *state {
|
||||||
|
wasmparser::ParserState::EndWasm => break Ok(()),
|
||||||
|
wasmparser::ParserState::Error(err) => Err(CompileError::ValidationError {
|
||||||
|
msg: err.message.to_string(),
|
||||||
|
})?,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
MCG: ModuleCodeGenerator<FCG, RM, E>,
|
MCG: ModuleCodeGenerator<FCG, RM, E>,
|
||||||
FCG: FunctionCodeGenerator<E>,
|
FCG: FunctionCodeGenerator<E>,
|
||||||
@ -132,6 +147,11 @@ impl<
|
|||||||
compiler_config: CompilerConfig,
|
compiler_config: CompilerConfig,
|
||||||
_: Token,
|
_: Token,
|
||||||
) -> CompileResult<ModuleInner> {
|
) -> CompileResult<ModuleInner> {
|
||||||
|
let res = validate(wasm);
|
||||||
|
if let Err(e) = res {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
|
||||||
let mut mcg = MCG::new();
|
let mut mcg = MCG::new();
|
||||||
let mut chain = (self.middleware_chain_generator)();
|
let mut chain = (self.middleware_chain_generator)();
|
||||||
let info = crate::parse::read_module(
|
let info = crate::parse::read_module(
|
||||||
@ -149,7 +169,7 @@ impl<
|
|||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
cache_gen,
|
cache_gen,
|
||||||
runnable_module: Box::new(exec_context),
|
runnable_module: Box::new(exec_context),
|
||||||
info,
|
info: Arc::try_unwrap(info).unwrap(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ pub fn read_module<
|
|||||||
mcg: &mut MCG,
|
mcg: &mut MCG,
|
||||||
middlewares: &mut MiddlewareChain,
|
middlewares: &mut MiddlewareChain,
|
||||||
compiler_config: &CompilerConfig,
|
compiler_config: &CompilerConfig,
|
||||||
) -> Result<ModuleInfo, LoadError> {
|
) -> Result<Arc<ModuleInfo>, LoadError> {
|
||||||
let mut info = Arc::new(ModuleInfo {
|
let mut info = Arc::new(ModuleInfo {
|
||||||
memories: Map::new(),
|
memories: Map::new(),
|
||||||
globals: Map::new(),
|
globals: Map::new(),
|
||||||
@ -104,7 +104,7 @@ pub fn read_module<
|
|||||||
use wasmparser::ParserState;
|
use wasmparser::ParserState;
|
||||||
let state = parser.read();
|
let state = parser.read();
|
||||||
match *state {
|
match *state {
|
||||||
ParserState::EndWasm => break Ok(Arc::try_unwrap(info).unwrap()),
|
ParserState::EndWasm => break,
|
||||||
ParserState::Error(err) => Err(LoadError::Parse(err))?,
|
ParserState::Error(err) => Err(LoadError::Parse(err))?,
|
||||||
ParserState::TypeSectionEntry(ref ty) => {
|
ParserState::TypeSectionEntry(ref ty) => {
|
||||||
Arc::get_mut(&mut info)
|
Arc::get_mut(&mut info)
|
||||||
@ -385,6 +385,7 @@ pub fn read_module<
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wp_type_to_type(ty: WpType) -> Result<Type, BinaryReaderError> {
|
pub fn wp_type_to_type(ty: WpType) -> Result<Type, BinaryReaderError> {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use wabt::wat2wasm;
|
use wabt::wat2wasm;
|
||||||
use wasmer_clif_backend::CraneliftCompiler;
|
use wasmer_clif_backend::CraneliftCompiler;
|
||||||
use wasmer_runtime_core::{import::ImportObject, Instance};
|
use wasmer_runtime_core::{backend::Compiler, import::ImportObject, Instance};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let instance = create_module_1();
|
let instance = create_module_1();
|
||||||
@ -24,13 +24,38 @@ fn create_module_1() -> Instance {
|
|||||||
(elem (;1;) (i32.const 9) 1))
|
(elem (;1;) (i32.const 9) 1))
|
||||||
"#;
|
"#;
|
||||||
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
|
let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed");
|
||||||
let module = wasmer_runtime_core::compile_with(&wasm_binary[..], &CraneliftCompiler::new())
|
let module = wasmer_runtime_core::compile_with(&wasm_binary[..], &get_compiler())
|
||||||
.expect("WASM can't be compiled");
|
.expect("WASM can't be compiled");
|
||||||
module
|
module
|
||||||
.instantiate(&generate_imports())
|
.instantiate(&generate_imports())
|
||||||
.expect("WASM can't be instantiated")
|
.expect("WASM can't be instantiated")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "clif")]
|
||||||
|
fn get_compiler() -> impl Compiler {
|
||||||
|
use wasmer_clif_backend::CraneliftCompiler;
|
||||||
|
CraneliftCompiler::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "llvm")]
|
||||||
|
fn get_compiler() -> impl Compiler {
|
||||||
|
use wasmer_llvm_backend::LLVMCompiler;
|
||||||
|
LLVMCompiler::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "singlepass")]
|
||||||
|
fn get_compiler() -> impl Compiler {
|
||||||
|
use wasmer_singlepass_backend::SinglePassCompiler;
|
||||||
|
SinglePassCompiler::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "llvm", feature = "clif", feature = "singlepass")))]
|
||||||
|
fn get_compiler() -> impl Compiler {
|
||||||
|
panic!("compiler not specified, activate a compiler via features");
|
||||||
|
use wasmer_clif_backend::CraneliftCompiler;
|
||||||
|
CraneliftCompiler::new()
|
||||||
|
}
|
||||||
|
|
||||||
static IMPORT_MODULE: &str = r#"
|
static IMPORT_MODULE: &str = r#"
|
||||||
(module
|
(module
|
||||||
(type $t0 (func (param i32)))
|
(type $t0 (func (param i32)))
|
||||||
@ -44,7 +69,7 @@ static IMPORT_MODULE: &str = r#"
|
|||||||
|
|
||||||
pub fn generate_imports() -> ImportObject {
|
pub fn generate_imports() -> ImportObject {
|
||||||
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
|
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
|
||||||
let module = wasmer_runtime_core::compile_with(&wasm_binary[..], &CraneliftCompiler::new())
|
let module = wasmer_runtime_core::compile_with(&wasm_binary[..], &get_compiler())
|
||||||
.expect("WASM can't be compiled");
|
.expect("WASM can't be compiled");
|
||||||
let instance = module
|
let instance = module
|
||||||
.instantiate(&ImportObject::new())
|
.instantiate(&ImportObject::new())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user