From c04ae9a5c394badd6bf9474a106e78fbd476f4aa Mon Sep 17 00:00:00 2001 From: xermicus Date: Fri, 8 Dec 2023 19:11:00 +0100 Subject: [PATCH] define pointer size Signed-off-by: xermicus --- crates/cli/src/main.rs | 2 +- crates/ir-tac/src/instruction.rs | 54 +++++++++-- crates/ir-tac/src/lib.rs | 2 + crates/ir-tac/src/symbol.rs | 156 ++++++++++++++++--------------- 4 files changed, 128 insertions(+), 86 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index c239beb..5dc5cab 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -6,5 +6,5 @@ fn main() { let bytecode = hex::decode(hexcode.trim()).unwrap(); let instructions = bytecode.disassemble(); - Program::new(instructions).dot(BasicBlockFormatOption::Ir); + Program::new(instructions).dot(BasicBlockFormatOption::ByteCode); } diff --git a/crates/ir-tac/src/instruction.rs b/crates/ir-tac/src/instruction.rs index 93f8e3d..6b3d37a 100644 --- a/crates/ir-tac/src/instruction.rs +++ b/crates/ir-tac/src/instruction.rs @@ -2,7 +2,10 @@ use evmil::bytecode::Instruction as EvmInstruction; use primitive_types::U256; use std::fmt::Write; -use crate::symbol::{Global, Symbol, SymbolTable, Type}; +use crate::{ + symbol::{Global, Symbol, SymbolTable, Type}, + POINTER_SIZE, +}; #[derive(PartialEq, Debug)] pub enum Instruction { @@ -162,7 +165,7 @@ fn decrement_stack_height(symbol_table: &mut SymbolTable) -> Instruction { x: symbol_table.global(Global::StackHeight), y: symbol_table.global(Global::StackHeight), operator: Operator::Sub, - z: symbol_table.constant(U256::one(), Some(Type::Int(4))), + z: symbol_table.constant(U256::one(), Some(Global::StackHeight.typ())), } } @@ -191,7 +194,7 @@ fn increment_stack_height(symbol_table: &mut SymbolTable) -> Instruction { x: symbol_table.global(Global::StackHeight), y: symbol_table.global(Global::StackHeight), operator: Operator::Add, - z: symbol_table.constant(U256::one(), Some(Type::Int(4))), + z: symbol_table.constant(U256::one(), Some(Global::StackHeight.typ())), } } @@ -305,6 +308,41 @@ pub fn translate(opcode: &EvmInstruction, symbol_table: &mut SymbolTable) -> Vec ] } + STOP => { + vec![Instruction::Procedure { + symbol: Global::Stop, + parameters: Default::default(), + }] + } + + INVALID => { + let offset = symbol_table.constant(U256::zero(), Some(Type::Int(POINTER_SIZE))); + let size = symbol_table.constant(U256::zero(), Some(Type::Int(POINTER_SIZE))); + + vec![Instruction::Procedure { + symbol: Global::Revert, + parameters: vec![offset, size], + }] + } + + REVERT => { + let offset = stack_pop(symbol_table); + let size = stack_pop(symbol_table); + + let procedure = Instruction::Procedure { + symbol: Global::Revert, + parameters: vec![offset.load.target_address(), size.load.target_address()], + }; + + vec![ + offset.decrement, + offset.load, + size.decrement, + size.load, + procedure, + ] + } + //_ => todo!("{opcode}"), _ => Vec::new(), } @@ -333,12 +371,12 @@ mod tests { Instruction::IndexedAssign { x: Symbol { address: Address::Label(Global::Stack), - type_hint: Type::Word, + type_hint: Global::Stack.typ(), kind: Global::Stack.kind(), }, index: Symbol { address: Address::Label(Global::StackHeight), - type_hint: Type::Int(4), + type_hint: Global::StackHeight.typ(), kind: Global::StackHeight.kind(), }, y: Symbol { @@ -350,18 +388,18 @@ mod tests { Instruction::BinaryAssign { x: Symbol { address: Address::Label(Global::StackHeight), - type_hint: Type::Int(4), + type_hint: Global::StackHeight.typ(), kind: Global::StackHeight.kind(), }, y: Symbol { address: Address::Label(Global::StackHeight), - type_hint: Type::Int(4), + type_hint: Global::StackHeight.typ(), kind: Global::StackHeight.kind(), }, operator: Operator::Add, z: Symbol { address: Address::Constant(U256::one()), - type_hint: Type::Int(4), + type_hint: Global::StackHeight.typ(), kind: Kind::Value, }, }, diff --git a/crates/ir-tac/src/lib.rs b/crates/ir-tac/src/lib.rs index c0bd695..cda4348 100644 --- a/crates/ir-tac/src/lib.rs +++ b/crates/ir-tac/src/lib.rs @@ -2,6 +2,8 @@ pub mod cfg; pub mod instruction; pub mod symbol; +pub static POINTER_SIZE: usize = 32; + #[cfg(test)] mod tests { diff --git a/crates/ir-tac/src/symbol.rs b/crates/ir-tac/src/symbol.rs index 3df2fd1..147fbc4 100644 --- a/crates/ir-tac/src/symbol.rs +++ b/crates/ir-tac/src/symbol.rs @@ -1,26 +1,53 @@ use indexmap::IndexSet; use primitive_types::U256; -#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] -pub enum Address { - Constant(U256), - Temporary(usize), - Label(Global), +use crate::POINTER_SIZE; + +#[derive(Debug, Default)] +pub struct SymbolTable { + symbols: IndexSet, + nonce: usize, } -impl std::fmt::Display for Address { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Constant(value) => write!(f, "{value:02x}"), - Self::Temporary(n) => write!(f, "tmp_{n}"), - Self::Label(label) => write!(f, "{label:?}"), - } +impl SymbolTable { + fn next(&mut self) -> usize { + let current = self.nonce; + self.nonce += 1; + current } -} -impl Address { - pub fn from_be_bytes(bytes: &[u8]) -> Self { - Self::Constant(U256::from_big_endian(bytes)) + pub fn temporary(&mut self, type_hint: Option) -> Symbol { + let id = self.next(); + let symbol = Symbol { + address: Address::Temporary(id), + type_hint: type_hint.unwrap_or_default(), + kind: Kind::Value, + }; + assert!(self.symbols.insert(symbol)); + + symbol + } + + pub fn constant(&mut self, value: U256, type_hint: Option) -> Symbol { + let symbol = Symbol { + address: Address::Constant(value), + type_hint: type_hint.unwrap_or_default(), + kind: Kind::Value, + }; + self.symbols.insert(symbol); + + symbol + } + + pub fn global(&mut self, label: Global) -> Symbol { + let symbol = Symbol { + address: Address::Label(label), + type_hint: label.typ(), + kind: label.kind(), + }; + self.symbols.insert(symbol); + + symbol } } @@ -33,33 +60,43 @@ pub struct Symbol { impl std::fmt::Display for Symbol { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "({}) {}", self.type_hint, self.address) + write!(f, "({} {})", self.type_hint, self.address)?; + + match self.kind { + Kind::Pointer => write!(f, "*"), + _ => Ok(()), + } } } -impl Symbol { - fn global(symbol: Global) -> Self { - let type_hint = match symbol { - Global::StackHeight => Type::Int(4), - _ => Default::default(), - }; +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] +pub enum Address { + Constant(U256), + Temporary(usize), + Label(Global), +} - Self::new(Address::Label(symbol), type_hint, symbol.kind()) - } - - fn new(address: Address, type_hint: Type, kind: Kind) -> Self { - Self { - address, - type_hint, - kind, +impl std::fmt::Display for Address { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Constant(value) => write!(f, "0x{value:02x}"), + Self::Temporary(n) => write!(f, "tmp_{n}"), + Self::Label(label) => write!(f, "{label:?}"), } } } +impl Address { + pub fn from_be_bytes(bytes: &[u8]) -> Self { + Self::Constant(U256::from_big_endian(bytes)) + } +} + #[derive(Debug, PartialEq, Eq, Hash, Default, Clone, Copy)] pub enum Type { #[default] Word, + UInt(usize), Int(usize), Bytes(usize), Bool, @@ -69,7 +106,8 @@ impl std::fmt::Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Word => write!(f, "word"), - Self::Int(size) => write!(f, "int{}", size * 8), + Self::UInt(size) => write!(f, "u{}", size), + Self::Int(size) => write!(f, "i{}", size), Self::Bytes(size) => write!(f, "bytes{size}"), Self::Bool => write!(f, "bool"), } @@ -78,7 +116,7 @@ impl std::fmt::Display for Type { impl Type { pub fn pointer() -> Self { - Self::Int(4) + Self::UInt(POINTER_SIZE) } } @@ -140,6 +178,14 @@ pub enum Global { } impl Global { + pub fn typ(&self) -> Type { + match self { + Self::Stack | Self::CallData | Self::Memory | Self::ReturnData => Type::pointer(), + Self::StackHeight => Type::UInt(POINTER_SIZE), + _ => Type::Word, + } + } + pub fn kind(&self) -> Kind { match self { Self::Stack | Self::CallData | Self::Memory | Self::ReturnData => Kind::Pointer, @@ -148,47 +194,3 @@ impl Global { } } } - -#[derive(Debug, Default)] -pub struct SymbolTable { - symbols: IndexSet, - nonce: usize, -} - -impl SymbolTable { - fn next(&mut self) -> usize { - let current = self.nonce; - self.nonce += 1; - current - } - - pub fn temporary(&mut self, type_hint: Option) -> Symbol { - let id = self.next(); - let symbol = Symbol::new( - Address::Temporary(id), - type_hint.unwrap_or_default(), - Kind::Value, - ); - assert!(self.symbols.insert(symbol)); - - symbol - } - - pub fn constant(&mut self, value: U256, type_hint: Option) -> Symbol { - let symbol = Symbol::new( - Address::Constant(value), - type_hint.unwrap_or_default(), - Kind::Value, - ); - self.symbols.insert(symbol); - - symbol - } - - pub fn global(&mut self, label: Global) -> Symbol { - let symbol = Symbol::global(label); - self.symbols.insert(symbol); - - symbol - } -}