Skip to content

Commit 91228f4

Browse files
committed
Implement driver for new db
1 parent 8134b8d commit 91228f4

12 files changed

Lines changed: 205 additions & 30 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/analyzer/src/namespace/items.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,10 @@ impl ContractId {
963963
db.contract_call_function(*self).value
964964
}
965965

966+
pub fn all_functions(&self, db: &dyn AnalyzerDb) -> Rc<[FunctionId]> {
967+
db.contract_all_functions(*self)
968+
}
969+
966970
/// User functions, public and not. Excludes `__init__` and `__call__`.
967971
pub fn functions(&self, db: &dyn AnalyzerDb) -> Rc<IndexMap<SmolStr, FunctionId>> {
968972
db.contract_function_map(*self).value
@@ -1260,6 +1264,11 @@ impl StructId {
12601264
pub fn fields(&self, db: &dyn AnalyzerDb) -> Rc<IndexMap<SmolStr, StructFieldId>> {
12611265
db.struct_field_map(*self).value
12621266
}
1267+
1268+
pub fn all_functions(&self, db: &dyn AnalyzerDb) -> Rc<[FunctionId]> {
1269+
db.struct_all_functions(*self)
1270+
}
1271+
12631272
pub fn functions(&self, db: &dyn AnalyzerDb) -> Rc<IndexMap<SmolStr, FunctionId>> {
12641273
db.struct_function_map(*self).value
12651274
}

crates/driver/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fe-abi = {path = "../abi", version = "^0.13.0-alpha"}
1616
fe-analyzer = {path = "../analyzer", version = "^0.13.0-alpha"}
1717
fe-common = {path = "../common", version = "^0.13.0-alpha"}
1818
fe-lowering = {path = "../lowering", version = "^0.13.0-alpha"}
19+
fe-mir = {path = "../mir", version = "^0.13.0-alpha"}
1920
fe-parser = {path = "../parser", version = "^0.13.0-alpha"}
2021
fe-yulgen = {path = "../yulgen", version = "^0.13.0-alpha"}
2122
fe-yulc = {path = "../yulc", version = "^0.13.0-alpha", features = ["solc-backend"], optional = true}

crates/driver/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#![allow(unused_imports, dead_code)]
22

3+
pub use fe_mir::db::NewDb;
4+
pub use fe_yulgen::Db;
5+
36
use fe_analyzer::context::Analysis;
47
use fe_analyzer::namespace::items::{IngotId, IngotMode, ModuleId};
58
use fe_analyzer::AnalyzerDb;
69
use fe_common::diagnostics::{print_diagnostics, Diagnostic};
710
use fe_common::files::{FileKind, SourceFileId};
11+
use fe_mir::db::MirDb;
812
use fe_parser::ast::SmolStr;
9-
pub use fe_yulgen::Db;
1013
use fe_yulgen::YulgenDb;
1114
use indexmap::{indexmap, IndexMap};
1215
#[cfg(feature = "solc-backend")]
@@ -81,6 +84,20 @@ pub fn compile_ingot(
8184
compile_module_id(db, main_module, with_bytecode, optimize)
8285
}
8386

87+
pub fn dump_mir_single_file(db: &mut NewDb, path: &str, src: &str) -> Result<(), CompileError> {
88+
let module = ModuleId::new_standalone(db, path, src);
89+
90+
let diags = module.diagnostics(db);
91+
if !diags.is_empty() {
92+
return Err(CompileError(diags));
93+
}
94+
let funcs = db.mir_lower_module_all_functions(module);
95+
for func in funcs.iter() {
96+
let _ = func.body(db);
97+
}
98+
Ok(())
99+
}
100+
84101
fn compile_module_id(
85102
db: &mut Db,
86103
module_id: ModuleId,

crates/fe/src/main.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ pub fn main() {
7171
.use_delimiter(false)
7272
.takes_value(true),
7373
)
74+
.arg(
75+
Arg::with_name("mir")
76+
.long("mir")
77+
.help("dump mir dot file")
78+
.takes_value(false),
79+
)
7480
.get_matches();
7581

7682
let input_path = matches.value_of("input").unwrap();
@@ -80,6 +86,10 @@ pub fn main() {
8086
let targets =
8187
values_t!(matches.values_of("emit"), CompilationTarget).unwrap_or_else(|e| e.exit());
8288
let with_bytecode = targets.contains(&CompilationTarget::Bytecode);
89+
90+
if matches.is_present("mir") {
91+
return mir_dump(input_path);
92+
}
8393
#[cfg(not(feature = "solc-backend"))]
8494
if with_bytecode {
8595
eprintln!("Warning: bytecode output requires 'solc-backend' feature. Try `cargo build --release --features solc-backend`. Skipping.");
@@ -255,3 +265,25 @@ fn verify_nonexistent_or_empty(dir: &Path) -> Result<(), String> {
255265
))
256266
}
257267
}
268+
269+
fn mir_dump(input_path: &str) {
270+
let mut db = fe_driver::NewDb::default();
271+
if Path::new(input_path).is_file() {
272+
let content = match std::fs::read_to_string(input_path) {
273+
Err(err) => {
274+
eprintln!("Failed to load file: `{}`. Error: {}", input_path, err);
275+
std::process::exit(1)
276+
}
277+
Ok(content) => content,
278+
};
279+
280+
if let Err(err) = fe_driver::dump_mir_single_file(&mut db, input_path, &content) {
281+
eprintln!("Unable to dump mir {}", input_path);
282+
print_diagnostics(&db, &err.0);
283+
std::process::exit(1)
284+
}
285+
} else {
286+
eprintln!("mir doesn't support ingot yet");
287+
std::process::exit(1)
288+
}
289+
}

crates/mir/src/db.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
11
use std::rc::Rc;
22

33
use fe_analyzer::{
4+
db::AnalyzerDbStorage,
45
namespace::{items as analyzer_items, types as analyzer_types},
56
AnalyzerDb,
67
};
7-
use fe_common::db::Upcast;
8+
use fe_common::db::{SourceDb, SourceDbStorage, Upcast, UpcastMut};
89

910
use crate::ir::{self, ConstantId, TypeId};
1011

1112
mod queries;
1213

1314
#[salsa::query_group(MirDbStorage)]
14-
pub trait MirDb: AnalyzerDb + Upcast<dyn AnalyzerDb> {
15+
pub trait MirDb: AnalyzerDb + Upcast<dyn AnalyzerDb> + UpcastMut<dyn AnalyzerDb> {
1516
#[salsa::interned]
1617
fn mir_intern_const(&self, data: Rc<ir::Constant>) -> ir::ConstantId;
1718
#[salsa::interned]
1819
fn mir_intern_type(&self, data: Rc<ir::Type>) -> ir::TypeId;
1920
#[salsa::interned]
2021
fn mir_intern_function(&self, data: Rc<ir::FunctionSignature>) -> ir::FunctionId;
2122

23+
#[salsa::invoke(queries::module::mir_lower_module_all_functions)]
24+
fn mir_lower_module_all_functions(
25+
&self,
26+
module: analyzer_items::ModuleId,
27+
) -> Rc<Vec<ir::FunctionId>>;
28+
29+
#[salsa::invoke(queries::contract::mir_lower_contract_all_functions)]
30+
fn mir_lower_contract_all_functions(
31+
&self,
32+
contract: analyzer_items::ContractId,
33+
) -> Rc<Vec<ir::FunctionId>>;
34+
35+
#[salsa::invoke(queries::structs::mir_lower_struct_all_functions)]
36+
fn mir_lower_struct_all_functions(
37+
&self,
38+
struct_: analyzer_items::StructId,
39+
) -> Rc<Vec<ir::FunctionId>>;
40+
2241
#[salsa::invoke(queries::types::mir_lowered_type)]
2342
fn mir_lowered_type(&self, analyzer_type: analyzer_types::Type) -> TypeId;
2443
#[salsa::invoke(queries::types::mir_lowered_event_type)]
@@ -35,3 +54,34 @@ pub trait MirDb: AnalyzerDb + Upcast<dyn AnalyzerDb> {
3554
#[salsa::invoke(queries::function::mir_lowered_func_body)]
3655
fn mir_lowered_func_body(&self, func: ir::FunctionId) -> Rc<ir::FunctionBody>;
3756
}
57+
58+
#[salsa::database(SourceDbStorage, AnalyzerDbStorage, MirDbStorage)]
59+
#[derive(Default)]
60+
pub struct NewDb {
61+
storage: salsa::Storage<NewDb>,
62+
}
63+
impl salsa::Database for NewDb {}
64+
65+
impl Upcast<dyn SourceDb> for NewDb {
66+
fn upcast(&self) -> &(dyn SourceDb + 'static) {
67+
&*self
68+
}
69+
}
70+
71+
impl UpcastMut<dyn SourceDb> for NewDb {
72+
fn upcast_mut(&mut self) -> &mut (dyn SourceDb + 'static) {
73+
&mut *self
74+
}
75+
}
76+
77+
impl Upcast<dyn AnalyzerDb> for NewDb {
78+
fn upcast(&self) -> &(dyn AnalyzerDb + 'static) {
79+
&*self
80+
}
81+
}
82+
83+
impl UpcastMut<dyn AnalyzerDb> for NewDb {
84+
fn upcast_mut(&mut self) -> &mut (dyn AnalyzerDb + 'static) {
85+
&mut *self
86+
}
87+
}

crates/mir/src/db/queries.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
pub mod constant;
2+
pub mod contract;
23
pub mod function;
4+
pub mod module;
5+
pub mod structs;
36
pub mod types;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use std::rc::Rc;
2+
3+
use fe_analyzer::namespace::items::{self as analyzer_items};
4+
5+
use crate::{db::MirDb, ir::FunctionId};
6+
7+
pub fn mir_lower_contract_all_functions(
8+
db: &dyn MirDb,
9+
contract: analyzer_items::ContractId,
10+
) -> Rc<Vec<FunctionId>> {
11+
contract
12+
.all_functions(db.upcast())
13+
.iter()
14+
.map(|func| db.mir_lowered_func_signature(*func))
15+
.collect::<Vec<_>>()
16+
.into()
17+
}

crates/mir/src/db/queries/function.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ impl ir::FunctionId {
2929
self.data(db).analyzer_func_id
3030
}
3131

32+
pub fn body(self, db: &dyn MirDb) -> Rc<ir::FunctionBody> {
33+
db.mir_lowered_func_body(self)
34+
}
35+
3236
pub fn module(self, db: &dyn MirDb) -> analyzer_items::ModuleId {
3337
let analyzer_func = self.analyzer_func(db);
3438
analyzer_func.module(db.upcast())
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use std::rc::Rc;
2+
3+
use fe_analyzer::namespace::items::{self as analyzer_items, TypeDef};
4+
5+
use crate::{db::MirDb, ir::FunctionId};
6+
7+
pub fn mir_lower_module_all_functions(
8+
db: &dyn MirDb,
9+
module: analyzer_items::ModuleId,
10+
) -> Rc<Vec<FunctionId>> {
11+
let mut functions = vec![];
12+
13+
let items = module.all_items(db.upcast());
14+
items.iter().for_each(|item| match item {
15+
analyzer_items::Item::Function(func) => {
16+
functions.push(db.mir_lowered_func_signature(*func))
17+
}
18+
19+
analyzer_items::Item::Type(TypeDef::Contract(contract)) => {
20+
functions.extend_from_slice(&db.mir_lower_contract_all_functions(*contract))
21+
}
22+
23+
analyzer_items::Item::Type(TypeDef::Struct(struct_)) => {
24+
functions.extend_from_slice(&db.mir_lower_struct_all_functions(*struct_))
25+
}
26+
27+
_ => {}
28+
});
29+
30+
functions.into()
31+
}

0 commit comments

Comments
 (0)