Skip to content

Commit 86d3dc9

Browse files
committed
Add prepare_for_function_redefine
1 parent 03c0e7e commit 86d3dc9

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cranelift/module/src/module.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,97 @@ pub trait Module {
490490
/// Define a data object, producing the data contents from the given `DataContext`.
491491
fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()>;
492492
}
493+
494+
impl<M: Module> Module for &mut M {
495+
fn isa(&self) -> &dyn isa::TargetIsa {
496+
(**self).isa()
497+
}
498+
499+
fn declarations(&self) -> &ModuleDeclarations {
500+
(**self).declarations()
501+
}
502+
503+
fn get_name(&self, name: &str) -> Option<FuncOrDataId> {
504+
(**self).get_name(name)
505+
}
506+
507+
fn target_config(&self) -> isa::TargetFrontendConfig {
508+
(**self).target_config()
509+
}
510+
511+
fn make_context(&self) -> Context {
512+
(**self).make_context()
513+
}
514+
515+
fn clear_context(&self, ctx: &mut Context) {
516+
(**self).clear_context(ctx)
517+
}
518+
519+
fn make_signature(&self) -> ir::Signature {
520+
(**self).make_signature()
521+
}
522+
523+
fn clear_signature(&self, sig: &mut ir::Signature) {
524+
(**self).clear_signature(sig)
525+
}
526+
527+
fn declare_function(
528+
&mut self,
529+
name: &str,
530+
linkage: Linkage,
531+
signature: &ir::Signature,
532+
) -> ModuleResult<FuncId> {
533+
(**self).declare_function(name, linkage, signature)
534+
}
535+
536+
fn declare_data(
537+
&mut self,
538+
name: &str,
539+
linkage: Linkage,
540+
writable: bool,
541+
tls: bool,
542+
) -> ModuleResult<DataId> {
543+
(**self).declare_data(name, linkage, writable, tls)
544+
}
545+
546+
fn declare_func_in_func(&self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef {
547+
(**self).declare_func_in_func(func, in_func)
548+
}
549+
550+
fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue {
551+
(**self).declare_data_in_func(data, func)
552+
}
553+
554+
fn declare_func_in_data(&self, func: FuncId, ctx: &mut DataContext) -> ir::FuncRef {
555+
(**self).declare_func_in_data(func, ctx)
556+
}
557+
558+
fn declare_data_in_data(&self, data: DataId, ctx: &mut DataContext) -> ir::GlobalValue {
559+
(**self).declare_data_in_data(data, ctx)
560+
}
561+
562+
fn define_function<TS>(
563+
&mut self,
564+
func: FuncId,
565+
ctx: &mut Context,
566+
trap_sink: &mut TS,
567+
) -> ModuleResult<ModuleCompiledFunction>
568+
where
569+
TS: binemit::TrapSink,
570+
{
571+
(**self).define_function(func, ctx, trap_sink)
572+
}
573+
574+
fn define_function_bytes(
575+
&mut self,
576+
func: FuncId,
577+
bytes: &[u8],
578+
relocs: &[RelocRecord],
579+
) -> ModuleResult<ModuleCompiledFunction> {
580+
(**self).define_function_bytes(func, bytes, relocs)
581+
}
582+
583+
fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()> {
584+
(**self).define_data(data, data_ctx)
585+
}
586+
}

cranelift/simplejit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ cranelift-module = { path = "../module", version = "0.68.0" }
1414
cranelift-native = { path = "../native", version = "0.68.0" }
1515
cranelift-codegen = { path = "../codegen", version = "0.68.0", default-features = false, features = ["std"] }
1616
cranelift-entity = { path = "../entity", version = "0.68.0" }
17+
anyhow = "1.0"
1718
region = "2.2.0"
1819
libc = { version = "0.2.42" }
1920
errno = "0.2.4"

cranelift/simplejit/src/backend.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,28 @@ impl SimpleJITModule {
393393
data_objects_to_finalize: Vec::new(),
394394
}
395395
}
396+
397+
/// Allow a single future `define_function` on a previously defined function. This allows for
398+
/// hot code swapping and lazy compilation of functions.
399+
pub fn prepare_for_function_redefine(&mut self, func_id: FuncId) -> ModuleResult<()> {
400+
let decl = self.declarations.get_function_decl(func_id);
401+
if !decl.linkage.is_definable() {
402+
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
403+
}
404+
405+
if self.compiled_functions[func_id].is_none() {
406+
return Err(ModuleError::Backend(anyhow::anyhow!(
407+
"Tried to redefine not yet defined function {}",
408+
decl.name
409+
)));
410+
}
411+
412+
self.compiled_functions[func_id] = None;
413+
414+
// FIXME return some kind of handle that allows for deallocating the function
415+
416+
Ok(())
417+
}
396418
}
397419

398420
impl<'simple_jit_backend> Module for SimpleJITModule {

0 commit comments

Comments
 (0)