Move logic out of more Module methods

This commit is contained in:
bjorn3
2020-09-30 17:12:27 +02:00
parent 80f4ecf9b5
commit c2ffcdc6d0
4 changed files with 67 additions and 83 deletions

View File

@@ -63,7 +63,6 @@ where
fn define_function<TS>( fn define_function<TS>(
&mut self, &mut self,
id: FuncId, id: FuncId,
name: &str,
ctx: &Context, ctx: &Context,
declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
code_size: u32, code_size: u32,
@@ -78,7 +77,6 @@ where
fn define_function_bytes( fn define_function_bytes(
&mut self, &mut self,
id: FuncId, id: FuncId,
name: &str,
bytes: &[u8], bytes: &[u8],
declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
) -> ModuleResult<()>; ) -> ModuleResult<()>;
@@ -89,10 +87,6 @@ where
fn define_data( fn define_data(
&mut self, &mut self,
id: DataId, id: DataId,
name: &str,
writable: bool,
tls: bool,
align: Option<u8>,
data_ctx: &DataContext, data_ctx: &DataContext,
declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
) -> ModuleResult<()>; ) -> ModuleResult<()>;

View File

@@ -201,6 +201,7 @@ impl DataDeclaration {
/// This provides a view to the state of a module which allows `ir::ExternalName`s to be translated /// This provides a view to the state of a module which allows `ir::ExternalName`s to be translated
/// into `FunctionDeclaration`s and `DataDeclaration`s. /// into `FunctionDeclaration`s and `DataDeclaration`s.
#[derive(Default)]
pub struct ModuleDeclarations { pub struct ModuleDeclarations {
names: HashMap<String, FuncOrDataId>, names: HashMap<String, FuncOrDataId>,
functions: PrimaryMap<FuncId, FunctionDeclaration>, functions: PrimaryMap<FuncId, FunctionDeclaration>,
@@ -361,7 +362,7 @@ where
/// Return the target information needed by frontends to produce Cranelift IR /// Return the target information needed by frontends to produce Cranelift IR
/// for the current target. /// for the current target.
pub fn target_config(&self) -> isa::TargetFrontendConfig { pub fn target_config(&self) -> isa::TargetFrontendConfig {
self.backend.isa().frontend_config() self.isa().frontend_config()
} }
/// Create a new `Context` initialized for use with this `Module`. /// Create a new `Context` initialized for use with this `Module`.
@@ -370,7 +371,7 @@ where
/// convention for the `TargetIsa`. /// convention for the `TargetIsa`.
pub fn make_context(&self) -> Context { pub fn make_context(&self) -> Context {
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.func.signature.call_conv = self.backend.isa().default_call_conv(); ctx.func.signature.call_conv = self.isa().default_call_conv();
ctx ctx
} }
@@ -380,14 +381,14 @@ where
/// convention for the `TargetIsa`. /// convention for the `TargetIsa`.
pub fn clear_context(&self, ctx: &mut Context) { pub fn clear_context(&self, ctx: &mut Context) {
ctx.clear(); ctx.clear();
ctx.func.signature.call_conv = self.backend.isa().default_call_conv(); ctx.func.signature.call_conv = self.isa().default_call_conv();
} }
/// Create a new empty `Signature` with the default calling convention for /// Create a new empty `Signature` with the default calling convention for
/// the `TargetIsa`, to which parameter and return types can be added for /// the `TargetIsa`, to which parameter and return types can be added for
/// declaring a function to be called by this `Module`. /// declaring a function to be called by this `Module`.
pub fn make_signature(&self) -> ir::Signature { pub fn make_signature(&self) -> ir::Signature {
ir::Signature::new(self.backend.isa().default_call_conv()) ir::Signature::new(self.isa().default_call_conv())
} }
/// Clear the given `Signature` and reset for use with a new function. /// Clear the given `Signature` and reset for use with a new function.
@@ -395,7 +396,7 @@ where
/// This ensures that the `Signature` is initialized with the default /// This ensures that the `Signature` is initialized with the default
/// calling convention for the `TargetIsa`. /// calling convention for the `TargetIsa`.
pub fn clear_signature(&self, sig: &mut ir::Signature) { pub fn clear_signature(&self, sig: &mut ir::Signature) {
sig.clear(self.backend.isa().default_call_conv()); sig.clear(self.isa().default_call_conv());
} }
/// Declare a function in this module. /// Declare a function in this module.
@@ -429,14 +430,8 @@ where
let (id, decl) = self let (id, decl) = self
.declarations .declarations
.declare_data(name, linkage, writable, tls, align)?; .declare_data(name, linkage, writable, tls, align)?;
self.backend.declare_data( self.backend
id, .declare_data(id, name, decl.linkage, decl.writable, decl.tls, decl.align);
name,
decl.linkage,
decl.writable,
decl.tls,
decl.align,
);
Ok(id) Ok(id)
} }
@@ -499,19 +494,9 @@ where
ctx.func.display(self.backend.isa()) ctx.func.display(self.backend.isa())
); );
let CodeInfo { total_size, .. } = ctx.compile(self.backend.isa())?; let CodeInfo { total_size, .. } = ctx.compile(self.backend.isa())?;
let decl = &self.declarations.functions[func];
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
self.backend.define_function( self.backend
func, .define_function(func, ctx, &self.declarations, total_size, trap_sink)?;
&decl.name,
ctx,
&self.declarations,
total_size,
trap_sink,
)?;
Ok(ModuleCompiledFunction { size: total_size }) Ok(ModuleCompiledFunction { size: total_size })
} }
@@ -530,9 +515,6 @@ where
) -> ModuleResult<ModuleCompiledFunction> { ) -> ModuleResult<ModuleCompiledFunction> {
info!("defining function {} with bytes", func); info!("defining function {} with bytes", func);
let decl = &self.declarations.functions[func]; let decl = &self.declarations.functions[func];
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
let total_size: u32 = match bytes.len().try_into() { let total_size: u32 = match bytes.len().try_into() {
Ok(total_size) => total_size, Ok(total_size) => total_size,
@@ -540,28 +522,18 @@ where
}; };
self.backend self.backend
.define_function_bytes(func, &decl.name, bytes, &self.declarations)?; .define_function_bytes(func, bytes, &self.declarations)?;
Ok(ModuleCompiledFunction { size: total_size }) Ok(ModuleCompiledFunction { size: total_size })
} }
/// Define a data object, producing the data contents from the given `DataContext`. /// Define a data object, producing the data contents from the given `DataContext`.
pub fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()> { pub fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()> {
let decl = &self.declarations.data_objects[data];
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
self.backend.define_data( self.backend.define_data(
data, data,
&decl.name,
decl.writable,
decl.tls,
decl.align,
data_ctx, data_ctx,
&self.declarations, &self.declarations,
)?; )
Ok(())
} }
/// Return the target isa /// Return the target isa

View File

@@ -208,18 +208,22 @@ impl Backend for ObjectBackend {
fn define_function<TS>( fn define_function<TS>(
&mut self, &mut self,
func_id: FuncId, func_id: FuncId,
name: &str,
ctx: &cranelift_codegen::Context, ctx: &cranelift_codegen::Context,
_declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
code_size: u32, code_size: u32,
trap_sink: &mut TS, trap_sink: &mut TS,
) -> ModuleResult<()> ) -> ModuleResult<()>
where where
TS: TrapSink, TS: TrapSink,
{ {
let decl = declarations.get_function_decl(func_id);
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
let &mut (symbol, ref mut defined) = self.functions[func_id].as_mut().unwrap(); let &mut (symbol, ref mut defined) = self.functions[func_id].as_mut().unwrap();
if *defined { if *defined {
return Err(ModuleError::DuplicateDefinition(name.to_owned())); return Err(ModuleError::DuplicateDefinition(decl.name.clone()));
} }
*defined = true; *defined = true;
@@ -269,13 +273,17 @@ impl Backend for ObjectBackend {
fn define_function_bytes( fn define_function_bytes(
&mut self, &mut self,
func_id: FuncId, func_id: FuncId,
name: &str,
bytes: &[u8], bytes: &[u8],
_declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
) -> ModuleResult<()> { ) -> ModuleResult<()> {
let decl = declarations.get_function_decl(func_id);
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
let &mut (symbol, ref mut defined) = self.functions[func_id].as_mut().unwrap(); let &mut (symbol, ref mut defined) = self.functions[func_id].as_mut().unwrap();
if *defined { if *defined {
return Err(ModuleError::DuplicateDefinition(name.to_owned())); return Err(ModuleError::DuplicateDefinition(decl.name.clone()));
} }
*defined = true; *defined = true;
@@ -302,16 +310,17 @@ impl Backend for ObjectBackend {
fn define_data( fn define_data(
&mut self, &mut self,
data_id: DataId, data_id: DataId,
name: &str,
writable: bool,
tls: bool,
align: Option<u8>,
data_ctx: &DataContext, data_ctx: &DataContext,
_declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
) -> ModuleResult<()> { ) -> ModuleResult<()> {
let decl = declarations.get_data_decl(data_id);
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
let &mut (symbol, ref mut defined) = self.data_objects[data_id].as_mut().unwrap(); let &mut (symbol, ref mut defined) = self.data_objects[data_id].as_mut().unwrap();
if *defined { if *defined {
return Err(ModuleError::DuplicateDefinition(name.to_owned())); return Err(ModuleError::DuplicateDefinition(decl.name.clone()));
} }
*defined = true; *defined = true;
@@ -353,14 +362,14 @@ impl Backend for ObjectBackend {
let section = if custom_segment_section.is_none() { let section = if custom_segment_section.is_none() {
let section_kind = if let Init::Zeros { .. } = *init { let section_kind = if let Init::Zeros { .. } = *init {
if tls { if decl.tls {
StandardSection::UninitializedTls StandardSection::UninitializedTls
} else { } else {
StandardSection::UninitializedData StandardSection::UninitializedData
} }
} else if tls { } else if decl.tls {
StandardSection::Tls StandardSection::Tls
} else if writable { } else if decl.writable {
StandardSection::Data StandardSection::Data
} else if relocs.is_empty() { } else if relocs.is_empty() {
StandardSection::ReadOnlyData StandardSection::ReadOnlyData
@@ -369,7 +378,7 @@ impl Backend for ObjectBackend {
}; };
self.object.section_id(section_kind) self.object.section_id(section_kind)
} else { } else {
if tls { if decl.tls {
return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!( return Err(cranelift_module::ModuleError::Backend(anyhow::anyhow!(
"Custom section not supported for TLS" "Custom section not supported for TLS"
))); )));
@@ -378,7 +387,7 @@ impl Backend for ObjectBackend {
self.object.add_section( self.object.add_section(
seg.clone().into_bytes(), seg.clone().into_bytes(),
sec.clone().into_bytes(), sec.clone().into_bytes(),
if writable { if decl.writable {
SectionKind::Data SectionKind::Data
} else if relocs.is_empty() { } else if relocs.is_empty() {
SectionKind::ReadOnlyData SectionKind::ReadOnlyData
@@ -388,7 +397,7 @@ impl Backend for ObjectBackend {
) )
}; };
let align = u64::from(align.unwrap_or(1)); let align = u64::from(decl.align.unwrap_or(1));
let offset = match *init { let offset = match *init {
Init::Uninitialized => { Init::Uninitialized => {
panic!("data is not initialized yet"); panic!("data is not initialized yet");

View File

@@ -413,17 +413,21 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
fn define_function<TS>( fn define_function<TS>(
&mut self, &mut self,
id: FuncId, id: FuncId,
name: &str,
ctx: &cranelift_codegen::Context, ctx: &cranelift_codegen::Context,
_declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
code_size: u32, code_size: u32,
trap_sink: &mut TS, trap_sink: &mut TS,
) -> ModuleResult<()> ) -> ModuleResult<()>
where where
TS: TrapSink, TS: TrapSink,
{ {
let decl = declarations.get_function_decl(id);
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
if !self.functions[id].is_none() { if !self.functions[id].is_none() {
return Err(ModuleError::DuplicateDefinition(name.to_owned())); return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
} }
self.functions_to_finalize.push(id); self.functions_to_finalize.push(id);
@@ -434,7 +438,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
.allocate(size, EXECUTABLE_DATA_ALIGNMENT) .allocate(size, EXECUTABLE_DATA_ALIGNMENT)
.expect("TODO: handle OOM etc."); .expect("TODO: handle OOM etc.");
self.record_function_for_perf(ptr, size, name); self.record_function_for_perf(ptr, size, &decl.name);
let mut reloc_sink = SimpleJITRelocSink::new(); let mut reloc_sink = SimpleJITRelocSink::new();
let mut stack_map_sink = SimpleJITStackMapSink::new(); let mut stack_map_sink = SimpleJITStackMapSink::new();
@@ -460,12 +464,16 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
fn define_function_bytes( fn define_function_bytes(
&mut self, &mut self,
id: FuncId, id: FuncId,
name: &str,
bytes: &[u8], bytes: &[u8],
_declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
) -> ModuleResult<()> { ) -> ModuleResult<()> {
let decl = declarations.get_function_decl(id);
if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
}
if !self.functions[id].is_none() { if !self.functions[id].is_none() {
return Err(ModuleError::DuplicateDefinition(name.to_owned())); return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
} }
self.functions_to_finalize.push(id); self.functions_to_finalize.push(id);
@@ -476,7 +484,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
.allocate(size, EXECUTABLE_DATA_ALIGNMENT) .allocate(size, EXECUTABLE_DATA_ALIGNMENT)
.expect("TODO: handle OOM etc."); .expect("TODO: handle OOM etc.");
self.record_function_for_perf(ptr, size, name); self.record_function_for_perf(ptr, size, &decl.name);
unsafe { unsafe {
ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, size); ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, size);
@@ -494,18 +502,19 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
fn define_data( fn define_data(
&mut self, &mut self,
id: DataId, id: DataId,
name: &str,
writable: bool,
tls: bool,
align: Option<u8>,
data: &DataContext, data: &DataContext,
_declarations: &ModuleDeclarations, declarations: &ModuleDeclarations,
) -> ModuleResult<()> { ) -> ModuleResult<()> {
if !self.data_objects[id].is_none() { let decl = declarations.get_data_decl(id);
return Err(ModuleError::DuplicateDefinition(name.to_owned())); if !decl.linkage.is_definable() {
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
} }
assert!(!tls, "SimpleJIT doesn't yet support TLS"); if !self.data_objects[id].is_none() {
return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
}
assert!(!decl.tls, "SimpleJIT doesn't yet support TLS");
self.data_objects_to_finalize.push(id); self.data_objects_to_finalize.push(id);
@@ -519,15 +528,15 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
} = data.description(); } = data.description();
let size = init.size(); let size = init.size();
let storage = if writable { let storage = if decl.writable {
self.memory self.memory
.writable .writable
.allocate(size, align.unwrap_or(WRITABLE_DATA_ALIGNMENT)) .allocate(size, decl.align.unwrap_or(WRITABLE_DATA_ALIGNMENT))
.expect("TODO: handle OOM etc.") .expect("TODO: handle OOM etc.")
} else { } else {
self.memory self.memory
.readonly .readonly
.allocate(size, align.unwrap_or(READONLY_DATA_ALIGNMENT)) .allocate(size, decl.align.unwrap_or(READONLY_DATA_ALIGNMENT))
.expect("TODO: handle OOM etc.") .expect("TODO: handle OOM etc.")
}; };