Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Y-Nak committed Nov 28, 2022
1 parent 3b56b80 commit 839cea9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 25 deletions.
17 changes: 13 additions & 4 deletions crates/codegen/src/yul/isel/context.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fe_mir::ir::FunctionSigId;
use indexmap::IndexSet;

use fe_analyzer::namespace::items::ContractId;
use fe_mir::ir::FunctionId;
use fxhash::FxHashSet;
use yultsur::yul;

Expand All @@ -15,9 +15,9 @@ use super::{lower_contract_deployable, lower_function};
pub struct Context {
pub runtime: Box<dyn RuntimeProvider>,
pub(super) contract_dependency: IndexSet<ContractId>,
pub(super) function_dependency: IndexSet<FunctionId>,
pub(super) string_constants: IndexSet<String>,
pub(super) lowered_functions: FxHashSet<FunctionId>,
pub(super) function_dependency: IndexSet<FunctionSigId>,
lowered_functions: FxHashSet<FunctionSigId>,
}

impl Default for Context {
Expand Down Expand Up @@ -48,7 +48,16 @@ impl Context {
// Ignore dependency if it's already lowered.
continue;
} else {
funcs.push(lower_function(db, self, dependency))
// Intrinsic functions are already inlined in the legalization phase.
// TODO: Add linker to allow linking to external functions.
let func = dependency
.analyzer_sig(db.upcast())
.function(db.upcast())
.expect(&format!(
"`{}` is not defined",
dependency.name(db.upcast())
));
funcs.push(lower_function(db, self, dependency, func))
}
}
}
Expand Down
44 changes: 23 additions & 21 deletions crates/codegen/src/yul/isel/contract.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use fe_analyzer::namespace::items::ContractId;
use fe_mir::ir::{function::Linkage, FunctionId};
use fe_mir::ir::{function::Linkage, FunctionSigId};
use yultsur::{yul, *};

use crate::{
Expand All @@ -12,9 +12,10 @@ use super::context::Context;
pub fn lower_contract_deployable(db: &dyn CodegenDb, contract: ContractId) -> yul::Object {
let mut context = Context::default();

let constructor = if let Some(init) = contract.init_function(db.upcast()) {
let init = db.mir_lowered_func_signature(init);
make_init(db, &mut context, contract, init)
let constructor = if let Some(init_func) = contract.init_function(db.upcast()) {
let init_sig = init_func.sig(db.upcast());
let init_sig = db.mir_lowered_func_signature(init_sig);
make_init(db, &mut context, contract, init_sig)
} else {
statements! {}
};
Expand Down Expand Up @@ -65,9 +66,9 @@ pub fn lower_contract(db: &dyn CodegenDb, contract: ContractId) -> yul::Object {
let exported_funcs: Vec<_> = db
.mir_lower_contract_all_functions(contract)
.iter()
.filter_map(|fid| {
if fid.signature(db.upcast()).linkage == Linkage::Export {
Some(*fid)
.filter_map(|(sig, _)| {
if sig.linkage(db.upcast()) == Linkage::Export {
Some(*sig)
} else {
None
}
Expand All @@ -76,9 +77,10 @@ pub fn lower_contract(db: &dyn CodegenDb, contract: ContractId) -> yul::Object {

let mut context = Context::default();
let dispatcher = if let Some(call_fn) = contract.call_function(db.upcast()) {
let call_fn = db.mir_lowered_func_signature(call_fn);
context.function_dependency.insert(call_fn);
let call_symbol = identifier! { (db.codegen_function_symbol_name(call_fn)) };
let call_fn_sig = call_fn.sig(db.upcast());
let call_fn_sig = db.mir_lowered_func_signature(call_fn_sig);
context.function_dependency.insert(call_fn_sig);
let call_symbol = identifier! { (db.codegen_function_symbol_name(call_fn_sig)) };
statement! {
([call_symbol]())
}
Expand Down Expand Up @@ -122,11 +124,11 @@ pub fn lower_contract(db: &dyn CodegenDb, contract: ContractId) -> yul::Object {
fn make_dispatcher(
db: &dyn CodegenDb,
context: &mut Context,
funcs: &[FunctionId],
funcs: &[FunctionSigId],
) -> yul::Statement {
let arms = funcs
.iter()
.map(|func| dispatch_arm(db, context, *func))
.map(|sig| dispatch_arm(db, context, *sig))
.collect::<Vec<_>>();

if arms.is_empty() {
Expand All @@ -143,9 +145,9 @@ fn make_dispatcher(
}
}

fn dispatch_arm(db: &dyn CodegenDb, context: &mut Context, func: FunctionId) -> yul::Case {
context.function_dependency.insert(func);
let func_sig = db.codegen_legalized_signature(func);
fn dispatch_arm(db: &dyn CodegenDb, context: &mut Context, sig: FunctionSigId) -> yul::Case {
context.function_dependency.insert(sig);
let func_sig = db.codegen_legalized_signature(sig);
let mut param_vars = Vec::with_capacity(func_sig.params.len());
let mut param_tys = Vec::with_capacity(func_sig.params.len());
func_sig.params.iter().for_each(|param| {
Expand All @@ -165,7 +167,7 @@ fn dispatch_arm(db: &dyn CodegenDb, context: &mut Context, func: FunctionId) ->
};

let call_and_encode_return = {
let name = identifier! { (db.codegen_function_symbol_name(func)) };
let name = identifier! { (db.codegen_function_symbol_name(sig)) };
// we pass in a `0` for the expected `Context` argument
let call = expression! {[name]([(param_vars.iter().map(YulVariable::expr).collect::<Vec<_>>())...])};
if let Some(mut return_type) = func_sig.return_type {
Expand Down Expand Up @@ -197,7 +199,7 @@ fn dispatch_arm(db: &dyn CodegenDb, context: &mut Context, func: FunctionId) ->
}
};

let abi_sig = db.codegen_abi_function(func);
let abi_sig = db.codegen_abi_function(sig);
let selector = literal! { (format!("0x{}", abi_sig.selector().hex())) };
case! {
case [selector] {
Expand All @@ -211,13 +213,13 @@ fn make_init(
db: &dyn CodegenDb,
context: &mut Context,
contract: ContractId,
init: FunctionId,
init_sig: FunctionSigId,
) -> Vec<yul::Statement> {
context.function_dependency.insert(init);
let init_func_name = identifier! { (db.codegen_function_symbol_name(init)) };
context.function_dependency.insert(init_sig);
let init_func_name = identifier! { (db.codegen_function_symbol_name(init_sig)) };
let contract_name = identifier_expression! { (format!{r#""{}""#, db.codegen_contract_deployer_symbol_name(contract)}) };

let func_sig = db.codegen_legalized_signature(init);
let func_sig = db.codegen_legalized_signature(init_sig);
let mut param_vars = Vec::with_capacity(func_sig.params.len());
let mut param_tys = Vec::with_capacity(func_sig.params.len());
let program_size = YulVariable::new("$program_size");
Expand Down

0 comments on commit 839cea9

Please sign in to comment.