Prevent finalize being called more than once per func/data (fixes #407)
This commit is contained in:
@@ -1,9 +1,14 @@
|
|||||||
extern crate cranelift_codegen;
|
extern crate cranelift_codegen;
|
||||||
|
extern crate cranelift_entity;
|
||||||
|
extern crate cranelift_frontend;
|
||||||
extern crate cranelift_module;
|
extern crate cranelift_module;
|
||||||
extern crate cranelift_simplejit;
|
extern crate cranelift_simplejit;
|
||||||
|
|
||||||
use cranelift_codegen::ir::*;
|
use cranelift_codegen::ir::*;
|
||||||
use cranelift_codegen::settings::*;
|
use cranelift_codegen::settings::*;
|
||||||
|
use cranelift_codegen::Context;
|
||||||
|
use cranelift_entity::EntityRef;
|
||||||
|
use cranelift_frontend::*;
|
||||||
use cranelift_module::*;
|
use cranelift_module::*;
|
||||||
use cranelift_simplejit::*;
|
use cranelift_simplejit::*;
|
||||||
|
|
||||||
@@ -25,3 +30,50 @@ fn error_on_incompatible_sig_in_declare_function() {
|
|||||||
.err()
|
.err()
|
||||||
.unwrap(); // Make sure this is an error
|
.unwrap(); // Make sure this is an error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn define_simple_function(module: &mut Module<SimpleJITBackend>) -> FuncId {
|
||||||
|
let sig = Signature {
|
||||||
|
params: vec![],
|
||||||
|
returns: vec![],
|
||||||
|
call_conv: CallConv::SystemV,
|
||||||
|
argument_bytes: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let func_id = module
|
||||||
|
.declare_function("abc", Linkage::Local, &sig)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut ctx = Context::new();
|
||||||
|
ctx.func = Function::with_name_signature(ExternalName::user(0, func_id.index() as u32), sig);
|
||||||
|
let mut func_ctx = FunctionBuilderContext::new();
|
||||||
|
{
|
||||||
|
let mut bcx: FunctionBuilder<Variable> = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
|
||||||
|
let ebb = bcx.create_ebb();
|
||||||
|
bcx.switch_to_block(ebb);
|
||||||
|
bcx.ins().return_(&[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.define_function(func_id, &mut ctx).unwrap();
|
||||||
|
|
||||||
|
func_id
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "function can't be finalized twice")]
|
||||||
|
fn panic_on_double_finalize() {
|
||||||
|
let mut module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
|
||||||
|
|
||||||
|
let func_id = define_simple_function(&mut module);
|
||||||
|
module.finalize_function(func_id);
|
||||||
|
module.finalize_function(func_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Result::unwrap()` on an `Err` value: DuplicateDefinition(\"abc\")")]
|
||||||
|
fn panic_on_define_after_finalize() {
|
||||||
|
let mut module: Module<SimpleJITBackend> = Module::new(SimpleJITBuilder::new());
|
||||||
|
|
||||||
|
let func_id = define_simple_function(&mut module);
|
||||||
|
module.finalize_function(func_id);
|
||||||
|
define_simple_function(&mut module);
|
||||||
|
}
|
||||||
|
|||||||
@@ -562,6 +562,10 @@ where
|
|||||||
|
|
||||||
/// Perform all outstanding relocations on the given function. This requires all `Local`
|
/// Perform all outstanding relocations on the given function. This requires all `Local`
|
||||||
/// and `Export` entities referenced to be defined.
|
/// and `Export` entities referenced to be defined.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// When the function has already been finalized this panics
|
||||||
pub fn finalize_function(&mut self, func: FuncId) -> B::FinalizedFunction {
|
pub fn finalize_function(&mut self, func: FuncId) -> B::FinalizedFunction {
|
||||||
let output = {
|
let output = {
|
||||||
let info = &self.contents.functions[func];
|
let info = &self.contents.functions[func];
|
||||||
@@ -569,6 +573,7 @@ where
|
|||||||
info.decl.linkage.is_definable(),
|
info.decl.linkage.is_definable(),
|
||||||
"imported function cannot be finalized"
|
"imported function cannot be finalized"
|
||||||
);
|
);
|
||||||
|
assert!(!info.finalized, "function can't be finalized twice");
|
||||||
self.backend.finalize_function(
|
self.backend.finalize_function(
|
||||||
info.compiled
|
info.compiled
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -584,6 +589,10 @@ where
|
|||||||
|
|
||||||
/// Perform all outstanding relocations on the given data object. This requires all
|
/// Perform all outstanding relocations on the given data object. This requires all
|
||||||
/// `Local` and `Export` entities referenced to be defined.
|
/// `Local` and `Export` entities referenced to be defined.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// When the data object has already been finalized this panics
|
||||||
pub fn finalize_data(&mut self, data: DataId) -> B::FinalizedData {
|
pub fn finalize_data(&mut self, data: DataId) -> B::FinalizedData {
|
||||||
let output = {
|
let output = {
|
||||||
let info = &self.contents.data_objects[data];
|
let info = &self.contents.data_objects[data];
|
||||||
@@ -591,6 +600,7 @@ where
|
|||||||
info.decl.linkage.is_definable(),
|
info.decl.linkage.is_definable(),
|
||||||
"imported data cannot be finalized"
|
"imported data cannot be finalized"
|
||||||
);
|
);
|
||||||
|
assert!(!info.finalized, "data object can't be finalized twice");
|
||||||
self.backend.finalize_data(
|
self.backend.finalize_data(
|
||||||
info.compiled
|
info.compiled
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
Reference in New Issue
Block a user