pub struct CodeBuffer { /* private fields */ }Expand description
A buffer of output to be produced, fixed up, and then emitted to a CodeSink in bulk.
This struct uses SmallVecs to support small-ish function bodies without
any heap allocation. As such, it will be several kilobytes large. This is
likely fine as long as it is stack-allocated for function emission then
thrown away; but beware if many buffer objects are retained persistently.
Implementations§
Source§impl CodeBuffer
impl CodeBuffer
Sourcepub fn new(env: Environment) -> Self
pub fn new(env: Environment) -> Self
Creates a buffer for env.
pub fn clear(&mut self)
Sourcepub fn error(&self) -> Option<&AsmError>
pub fn error(&self) -> Option<&AsmError>
Returns the first error recorded by a void assembler operation.
pub fn env(&self) -> &Environment
pub fn data(&self) -> &[u8]
pub fn relocs(&self) -> &[AsmReloc]
pub fn put1(&mut self, value: u8)
pub fn put2(&mut self, value: u16)
pub fn put4(&mut self, value: u32)
pub fn put8(&mut self, value: u64)
pub fn write_u8(&mut self, value: u8)
pub fn write_u16(&mut self, value: u16)
pub fn write_u32(&mut self, value: u32)
pub fn write_u64(&mut self, value: u64)
pub fn add_symbol( &mut self, name: impl Into<ExternalName>, distance: RelocDistance, ) -> Sym
Sourcepub fn extern_sym(
&mut self,
name: impl Into<Cow<'static, str>>,
distance: RelocDistance,
) -> Sym
pub fn extern_sym( &mut self, name: impl Into<Cow<'static, str>>, distance: RelocDistance, ) -> Sym
Declares an external symbol by name, deduplicating: repeated calls with
the same name return the same Sym (the distance of the first
declaration wins).
The returned symbol can be passed to the architecture assemblers (e.g.
ptr64_sym on x86) which then record the appropriate relocation based
on the symbol’s distance.
Sourcepub fn extern_user(
&mut self,
namespace: u32,
index: u32,
distance: RelocDistance,
) -> Sym
pub fn extern_user( &mut self, namespace: u32, index: u32, distance: RelocDistance, ) -> Sym
Declares an external symbol by user namespace+index, deduplicating:
repeated calls with the same key return the same Sym (the distance of
the first declaration wins).
Sourcepub fn bind_symbol(&mut self, name: impl Into<ExternalName>, label: Label)
pub fn bind_symbol(&mut self, name: impl Into<ExternalName>, label: Label)
Exports label under name, making it a defined symbol that other
modules can resolve at link time (see crate::core::linker::Linker).
name may be a string (ExternalName::Symbol) or a user key
(ExternalName::User).
pub fn symbol_distance(&self, sym: Sym) -> Option<RelocDistance>
pub fn symbol_name(&self, sym: Sym) -> Option<&ExternalName>
pub fn get_label(&mut self) -> Label
pub fn is_bound(&self, label: Label) -> bool
Sourcepub fn label_count(&self) -> u32
pub fn label_count(&self) -> u32
Number of labels created so far; label ids below this count are valid.
pub fn get_label_for_constant(&mut self, constant: Constant) -> Label
pub fn add_constant(&mut self, constant: impl Into<ConstantData>) -> Constant
pub fn use_label_at_offset( &mut self, offset: CodeOffset, label: Label, kind: LabelUse, )
Sourcepub fn try_align_to(&mut self, align_to: CodeOffset) -> Result<(), AsmError>
pub fn try_align_to(&mut self, align_to: CodeOffset) -> Result<(), AsmError>
Align up to the given alignment.
pub fn align_to(&mut self, align_to: CodeOffset)
pub fn cur_offset(&self) -> CodeOffset
pub fn try_bind_label(&mut self, label: Label) -> Result<(), AsmError>
pub fn bind_label(&mut self, label: Label)
pub fn label_offset(&self, label: Label) -> u32
pub fn add_reloc(&mut self, kind: Reloc, target: RelocTarget, addend: i64)
pub fn add_reloc_at_offset( &mut self, offset: CodeOffset, kind: Reloc, target: RelocTarget, addend: i64, )
Sourcepub fn reserve_patch_block(
&mut self,
size: CodeOffset,
align: CodeOffset,
) -> Result<PatchableBlock, AsmError>
pub fn reserve_patch_block( &mut self, size: CodeOffset, align: CodeOffset, ) -> Result<PatchableBlock, AsmError>
Reserve a nop-filled island for later custom rewriting (JSC padBeforePatch).
Returns a PatchableBlock handle; the block is also recorded in the patch catalog
for finish_patched / linker rebasing.
pub fn record_patch_block( &mut self, offset: CodeOffset, size: CodeOffset, align: CodeOffset, ) -> PatchBlockId
pub fn try_record_patch_block( &mut self, offset: CodeOffset, size: CodeOffset, align: CodeOffset, ) -> Result<PatchBlockId, AsmError>
pub fn record_patch_site( &mut self, offset: CodeOffset, kind: LabelUse, target_offset: CodeOffset, ) -> PatchSiteId
pub fn try_record_patch_site( &mut self, offset: CodeOffset, kind: LabelUse, target_offset: CodeOffset, ) -> Result<PatchSiteId, AsmError>
pub fn record_label_patch_site( &mut self, offset: CodeOffset, label: Label, kind: LabelUse, ) -> PatchSiteId
pub fn try_record_label_patch_site( &mut self, offset: CodeOffset, label: Label, kind: LabelUse, ) -> Result<PatchSiteId, AsmError>
Sourcepub fn emit_veneer(
&mut self,
label: Label,
offset: CodeOffset,
kind: LabelUse,
) -> Result<(), AsmError>
pub fn emit_veneer( &mut self, label: Label, offset: CodeOffset, kind: LabelUse, ) -> Result<(), AsmError>
Emits a “veneer” the kind code at offset to jump to label.
This will generate extra machine code, using kind, to get a
larger-jump-kind than kind allows. The code at offset is then
patched to jump to our new code, and then the new code is enqueued for
a fixup to get processed at some later time.
Sourcepub fn island_needed(&mut self, distance: CodeOffset) -> bool
pub fn island_needed(&mut self, distance: CodeOffset) -> bool
Is an island needed within the next N bytes?
Sourcepub fn emit_island(&mut self, distance: CodeOffset) -> Result<(), AsmError>
pub fn emit_island(&mut self, distance: CodeOffset) -> Result<(), AsmError>
Emit all pending constants and required pending veneers.