Implement canon lower of a canon lift function in the same component (#4347)
* Implement `canon lower` of a `canon lift` function in the same component This commit implements the "degenerate" logic for implementing a function within a component that is lifted and then immediately lowered again. In this situation the lowered function will immediately generate a trap and doesn't need to implement anything else. The implementation in this commit is somewhat heavyweight but I think is probably justified moreso in future additions to the component model rather than what exactly is here right now. It's not expected that this "always trap" functionality will really be used all that often since it would generally mean a buggy component, but the functionality plumbed through here is hopefully going to be useful for implementing component-to-component adapter trampolines. Specifically this commit implements a strategy where the `canon.lower`'d function is generated by Cranelift and simply has a single trap instruction when called, doing nothing else. The main complexity comes from juggling around all the data associated with these functions, primarily plumbing through the traps into the `ModuleRegistry` to ensure that the global `is_wasm_trap_pc` function returns `true` and at runtime when we lookup information about the trap it's all readily available (e.g. translating the trapping pc to a `TrapCode`). * Fix non-component build * Fix some offset calculations * Only create one "always trap" per signature Use an internal map to deduplicate during compilation.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use crate::component::{Component, ComponentTypes, LowerImport, LoweredIndex};
|
||||
use crate::{PrimaryMap, SignatureIndex, Trampoline};
|
||||
use crate::component::{
|
||||
Component, ComponentTypes, LowerImport, LoweredIndex, RuntimeAlwaysTrapIndex,
|
||||
};
|
||||
use crate::{PrimaryMap, SignatureIndex, Trampoline, WasmFuncType};
|
||||
use anyhow::Result;
|
||||
use object::write::Object;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -16,6 +18,19 @@ pub struct LoweringInfo {
|
||||
pub length: u32,
|
||||
}
|
||||
|
||||
/// Description of an "always trap" function generated by
|
||||
/// `ComponentCompiler::compile_always_trap`.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct AlwaysTrapInfo {
|
||||
/// The byte offset from the start of the text section where this trampoline
|
||||
/// starts.
|
||||
pub start: u32,
|
||||
/// The byte length of this trampoline's function body.
|
||||
pub length: u32,
|
||||
/// The offset from `start` of where the trapping instruction is located.
|
||||
pub trap_offset: u32,
|
||||
}
|
||||
|
||||
/// Compilation support necessary for components.
|
||||
pub trait ComponentCompiler: Send + Sync {
|
||||
/// Creates a trampoline for a `canon.lower`'d host function.
|
||||
@@ -42,6 +57,13 @@ pub trait ComponentCompiler: Send + Sync {
|
||||
types: &ComponentTypes,
|
||||
) -> Result<Box<dyn Any + Send>>;
|
||||
|
||||
/// Creates a function which will always trap that has the `ty` specified.
|
||||
///
|
||||
/// This will create a small trampoline whose only purpose is to generate a
|
||||
/// trap at runtime. This is used to implement the degenerate case of a
|
||||
/// `canon lift`'d function immediately being `canon lower`'d.
|
||||
fn compile_always_trap(&self, ty: &WasmFuncType) -> Result<Box<dyn Any + Send>>;
|
||||
|
||||
/// Emits the `lowerings` and `trampolines` specified into the in-progress
|
||||
/// ELF object specified by `obj`.
|
||||
///
|
||||
@@ -53,7 +75,12 @@ pub trait ComponentCompiler: Send + Sync {
|
||||
fn emit_obj(
|
||||
&self,
|
||||
lowerings: PrimaryMap<LoweredIndex, Box<dyn Any + Send>>,
|
||||
always_trap: PrimaryMap<RuntimeAlwaysTrapIndex, Box<dyn Any + Send>>,
|
||||
tramplines: Vec<(SignatureIndex, Box<dyn Any + Send>)>,
|
||||
obj: &mut Object<'static>,
|
||||
) -> Result<(PrimaryMap<LoweredIndex, LoweringInfo>, Vec<Trampoline>)>;
|
||||
) -> Result<(
|
||||
PrimaryMap<LoweredIndex, LoweringInfo>,
|
||||
PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>,
|
||||
Vec<Trampoline>,
|
||||
)>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user