Skip to content

Commit 677bc2a

Browse files
committed
Renaming of ABI dispatch functions.
squash
1 parent 81a1289 commit 677bc2a

3 files changed

Lines changed: 49 additions & 59 deletions

File tree

compiler/src/abi/mod.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@ mod builder;
77
pub mod elements;
88

99
/// Builds the appropriate ABIs for a given source `&str`.
10-
///
11-
/// # Example
12-
/// ```
13-
/// use vyper_compiler::abi;
14-
///
15-
/// let abis = abi::build(src)?;
16-
/// let json_abis = abis.json()?;
17-
/// ```
1810
pub fn build(src: &str) -> Result<elements::ModuleABIs, CompileError> {
1911
let tokens = parser::get_parse_tokens(src)?;
2012
let module = parser::parsers::file_input(&tokens[..])?.1.node;

compiler/src/yul/mappers/contracts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn contract_def(
2727
.collect::<Vec<yul::Statement>>();
2828

2929
statements.append(&mut runtime_functions::all());
30-
statements.push(runtime_abi::switch(
30+
statements.push(runtime_abi::dispatcher(
3131
&contract_scope.borrow().interface,
3232
&contract_scope.borrow().defs,
3333
)?);

compiler/src/yul/runtime/abi.rs

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,65 +6,51 @@ use std::collections::HashMap;
66
use tiny_keccak::{Hasher, Keccak};
77
use yultsur::*;
88

9-
/// Builds a switch statement from the contract ABI that handles contract calls.
10-
pub fn switch(
9+
/// Builds a switch statement that dispatches calls to the contract.
10+
pub fn dispatcher(
1111
interface: &Vec<String>,
1212
defs: &HashMap<String, ContractDef>,
1313
) -> Result<yul::Statement, CompileError> {
14-
let cases = interface
14+
let arms = interface
1515
.into_iter()
16-
.map(|name| case(name.to_owned(), defs))
16+
.map(|name| dispatch_arm(name.to_owned(), defs))
1717
.collect::<Result<Vec<yul::Case>, CompileError>>()?;
1818

1919
Ok(switch! {
2020
switch (cloadn(0, 4))
21-
[cases...]
21+
[arms...]
2222
})
2323
}
2424

25-
fn case(name: String, defs: &HashMap<String, ContractDef>) -> Result<yul::Case, CompileError> {
26-
if let Some(def) = defs.get(&name) {
27-
return match def {
28-
ContractDef::Function { params, returns } => {
29-
function_call_case(name, params, returns.to_owned())
30-
}
31-
_ => Err(CompileError::static_str(
32-
"Cannot create case from definition",
33-
)),
34-
};
25+
fn dispatch_arm(
26+
name: String,
27+
defs: &HashMap<String, ContractDef>
28+
) -> Result<yul::Case, CompileError> {
29+
if let Some(ContractDef::Function { params, returns }) = defs.get(&name) {
30+
let selector = selector(name.clone(), &params);
31+
32+
if let Some(returns) = returns {
33+
let selection = selection(name, &params)?;
34+
let return_data = returns.encode(selection)?;
35+
let return_size = literal_expression! {(returns.padded_size())};
36+
37+
let selection_with_return = statement! { return([return_data], [return_size]) };
38+
39+
return Ok(case! { case [selector] { [selection_with_return] } })
40+
}
41+
42+
let selection = selection_as_statement(name, &params)?;
43+
44+
return Ok(case! { case [selector] { [selection] } })
3545
}
3646

3747
Err(CompileError::static_str("No definition for name"))
3848
}
3949

40-
fn function_call_case(
50+
fn selector(
4151
name: String,
42-
params: &Vec<FixedSize>,
43-
returns: Option<FixedSize>,
44-
) -> Result<yul::Case, CompileError> {
45-
let selector = selector_literal(name.clone(), &params);
46-
let name = identifier! {(name)};
47-
let params = parameter_expressions(&params)?;
48-
49-
if let Some(returns) = returns {
50-
let return_size = literal_expression! {(returns.padded_size())};
51-
let function_call = expression! { [name]([params...]) };
52-
53-
Ok(case! {
54-
case [selector] {
55-
(return([returns.encode(function_call)?], [return_size]))
56-
}
57-
})
58-
} else {
59-
let function_call = statement! { [name]([params...]) };
60-
61-
Ok(case! {
62-
case [selector] { [function_call] }
63-
})
64-
}
65-
}
66-
67-
fn selector_literal(name: String, params: &Vec<FixedSize>) -> yul::Literal {
52+
params: &Vec<FixedSize>
53+
) -> yul::Literal {
6854
let signature = format!(
6955
"{}({})",
7056
name,
@@ -84,31 +70,43 @@ fn selector_literal(name: String, params: &Vec<FixedSize>) -> yul::Literal {
8470
literal! {(format!("0x{}", hex::encode(selector)))}
8571
}
8672

87-
fn parameter_expressions(params: &Vec<FixedSize>) -> Result<Vec<yul::Expression>, CompileError> {
73+
fn selection(
74+
name: String,
75+
params: &Vec<FixedSize>
76+
) -> Result<yul::Expression, CompileError> {
8877
let mut ptr = 4;
89-
let mut expressions = vec![];
78+
let mut decoded_params = vec![];
9079

9180
for param in params.iter() {
92-
expressions.push(param.decode(literal_expression! {(ptr)})?);
81+
decoded_params.push(param.decode(literal_expression! {(ptr)})?);
9382
ptr += param.padded_size();
9483
}
9584

96-
Ok(expressions)
85+
let name = identifier! {(name)};
86+
87+
Ok(expression! { [name]([decoded_params...]) })
88+
}
89+
90+
91+
fn selection_as_statement(
92+
name: String,
93+
params: &Vec<FixedSize>
94+
) -> Result<yul::Statement, CompileError> {
95+
Ok(yul::Statement::Expression(selection(name, params)?))
9796
}
9897

9998
#[test]
100-
fn selector_literal_basic() {
99+
fn test_selector_literal_basic() {
101100
assert_eq!(
102-
selector_literal("foo".to_string(), &vec![]).to_string(),
101+
selector("foo".to_string(), &vec![]).to_string(),
103102
String::from("0xc2985578"),
104-
"Incorrect selector"
105103
)
106104
}
107105

108106
#[test]
109107
fn test_selector_literal() {
110108
assert_eq!(
111-
selector_literal("bar".to_string(), &vec![FixedSize::Base(Base::U256)]).to_string(),
109+
selector("bar".to_string(), &vec![FixedSize::Base(Base::U256)]).to_string(),
112110
String::from("0x0423a132"),
113111
)
114112
}

0 commit comments

Comments
 (0)