Skip to content

Commit

Permalink
feat(codegen): introduce offset in jump table
Browse files Browse the repository at this point in the history
  • Loading branch information
clearloop committed Oct 24, 2023
1 parent 3034943 commit b82a5b3
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 8 deletions.
2 changes: 1 addition & 1 deletion codegen/src/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::collections::BTreeMap;
/// Backtrace implementation for the code generation.
///
/// TODO: full implementation (#21)
#[derive(Default)]
#[derive(Debug, Default)]
pub struct Backtrace {
/// Compiled instructions.
///
Expand Down
13 changes: 11 additions & 2 deletions codegen/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,24 @@ impl Dispatcher {

let func = self.query_func(&abi.name)?;

// Jump to the end of the dispatcher.
//
// TODO: detect the bytes of the position.
self.asm.increment_sp(1)?;
let pc = self.asm.pc_offset();
self.table.offset(pc, if last { 0xb } else { 0xc });

if !last {
self.asm._dup1()?;
self.asm._dup2()?;
}

self.asm.push(&selector)?;
self.asm._eq()?;
self.asm.increment_sp(1)?;

self.table.call(self.asm.pc_offset(), func);
self.asm._jumpi()?;
self.asm._jumpdest()?;

Ok(())
}
Expand All @@ -182,7 +191,7 @@ impl Dispatcher {

let mut len = selectors.len();
for (_, func) in selectors.iter() {
self.emit_selector(func, len == 0)?;
self.emit_selector(func, len == 1)?;
len -= 1;
}

Expand Down
15 changes: 11 additions & 4 deletions codegen/src/jump/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ mod relocate;
mod table;

/// Jump types
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Jump {
/// Jump to the given label, the label here is the original
/// program counter.
/// offset to the program counter.
Offset(u16),
/// Jump to the given label, the label here
/// is the original program counter.
Label(u16),
/// Jump to function.
Func(u32),
Expand All @@ -23,6 +25,11 @@ pub enum Jump {
impl Jump {
/// If the target is a label.
pub fn is_label(&self) -> bool {
matches!(self, Jump::Label(_))
matches!(self, Jump::Label { .. })
}

/// If the target is fixed to offset of the program counter.
pub fn is_offset(&self) -> bool {
matches!(self, Jump::Offset(_))
}
}
7 changes: 6 additions & 1 deletion codegen/src/jump/relocate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ impl JumpTable {
tracing::debug!("run relocateion for {jump:?}",);

let offset = relocate::offset(pc)?;
relocate::pc(buffer, pc, self.target(&jump)?, offset)?;
let mut target = self.target(&jump)?;
if jump.is_offset() {
target += pc;
}

relocate::pc(buffer, pc, target, offset)?;
self.shift_label_pc(pc, offset)?;
}

Expand Down
7 changes: 7 additions & 0 deletions codegen/src/jump/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
use std::collections::BTreeMap;

/// Jump table implementation.
///
#[derive(Default, Debug)]
pub struct JumpTable {
/// Jump table.
Expand Down Expand Up @@ -49,6 +50,11 @@ impl JumpTable {
self.jump.insert(pc, Jump::Label(label));
}

/// Register a label.
pub fn offset(&mut self, pc: u16, offset: u16) {
self.jump.insert(pc, Jump::Offset(offset));
}

/// Merge two jump tables.
///
/// Merge other jump table into this one, update the program
Expand Down Expand Up @@ -80,6 +86,7 @@ impl JumpTable {
/// Get the target of a jump.
pub fn target(&mut self, jump: &Jump) -> Result<u16> {
match jump {
Jump::Offset(offset) => Ok(*offset),
Jump::Label(label) => Ok(*label),
Jump::Func(func) => Ok(*self.func.get(func).ok_or(Error::FuncNotFound(*func))?),
Jump::ExtFunc(ext) => Ok(self.code.offset_of(ext).ok_or(Error::ExtNotFound(*ext))?),
Expand Down
2 changes: 2 additions & 0 deletions codegen/src/visitor/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ impl CodeGen {

// TODO: handle the length of results > u8::MAX.
self.masm.shift_pc(len, false)?;

// TODO: [PC, PUSHN, BYTES, JUMPDEST]
self.masm.push(&[0x04])?;
self.masm._add()?;
self.masm._jump()?;
Expand Down

0 comments on commit b82a5b3

Please sign in to comment.