Skip to content

Commit 43d9de4

Browse files
author
Grant Wuerker
committed
hacking
1 parent e16f122 commit 43d9de4

38 files changed

+2638
-2
lines changed

Cargo.lock

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

crates/analyzer/src/db.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ pub trait AnalyzerDb: SourceDb + Upcast<dyn SourceDb> + UpcastMut<dyn SourceDb>
110110
fn module_submodules(&self, module: ModuleId) -> Rc<[ModuleId]>;
111111
#[salsa::invoke(queries::module::module_tests)]
112112
fn module_tests(&self, module: ModuleId) -> Vec<FunctionId>;
113+
#[salsa::invoke(queries::module::module_invariants)]
114+
fn module_invariants(&self, module: ModuleId) -> Vec<FunctionId>;
113115

114116
// Module Constant
115117
#[salsa::cycle(queries::module::module_constant_type_cycle)]

crates/analyzer/src/db/queries/module.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,3 +760,12 @@ pub fn module_tests(db: &dyn AnalyzerDb, ingot: ModuleId) -> Vec<FunctionId> {
760760
.filter(|function| function.is_test(db))
761761
.collect()
762762
}
763+
764+
pub fn module_invariants(db: &dyn AnalyzerDb, ingot: ModuleId) -> Vec<FunctionId> {
765+
ingot
766+
.all_functions(db)
767+
.iter()
768+
.copied()
769+
.filter(|function| function.is_invariant(db))
770+
.collect()
771+
}

crates/analyzer/src/namespace/items.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,10 @@ impl ModuleId {
555555
db.module_tests(*self)
556556
}
557557

558+
pub fn invariants(&self, db: &dyn AnalyzerDb) -> Vec<FunctionId> {
559+
db.module_invariants(*self)
560+
}
561+
558562
/// Returns `true` if the `item` is in scope of the module.
559563
pub fn is_in_scope(&self, db: &dyn AnalyzerDb, item: Item) -> bool {
560564
if let Some(val) = item.module(db) {
@@ -1351,6 +1355,13 @@ impl FunctionId {
13511355
.iter()
13521356
.any(|attribute| attribute.name(db) == "test")
13531357
}
1358+
1359+
pub fn is_invariant(&self, db: &dyn AnalyzerDb) -> bool {
1360+
Item::Function(*self)
1361+
.attributes(db)
1362+
.iter()
1363+
.any(|attribute| attribute.name(db) == "invariant")
1364+
}
13541365
}
13551366

13561367
trait FunctionsAsItems {

crates/codegen/src/yul/isel/test.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,21 @@ pub fn lower_test(db: &dyn CodegenDb, test: FunctionId) -> yul::Object {
2222
.map(yul::Statement::FunctionDefinition)
2323
.collect();
2424
let test_func_name = identifier! { (db.codegen_function_symbol_name(test)) };
25-
let call = function_call_statement! {[test_func_name]()};
25+
let call_args = test
26+
.signature(db.upcast())
27+
.params
28+
.iter()
29+
.enumerate()
30+
.filter_map(|(n, param)| {
31+
if param.name == "ctx" {
32+
None
33+
} else {
34+
let value = literal_expression! { (n * 32) };
35+
Some(expression! { calldataload([value]) })
36+
}
37+
})
38+
.collect::<Vec<_>>();
39+
let call = function_call_statement! {[test_func_name]([call_args...])};
2640

2741
let code = code! {
2842
[dep_functions...]

crates/codegen/src/yul/runtime/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ pub trait RuntimeProvider {
163163
expression! { signextend([significant], [value]) }
164164
} else {
165165
let mask = BitMask::new(from_size);
166-
expression! { and([value], [mask.as_expr()]) }
166+
// expression! { and([value], [mask.as_expr()]) }
167+
value
167168
}
168169
}
169170

crates/driver/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ fe-codegen = {path = "../codegen", version = "^0.22.0"}
2020
fe-parser = {path = "../parser", version = "^0.22.0"}
2121
fe-yulc = {path = "../yulc", version = "^0.22.0", features = ["solc-backend"], optional = true}
2222
fe-test-runner = {path = "../test-runner", version = "^0.22.0"}
23+
fe-specgen = {path = "../specgen", version = "^0.22.0"}
2324
indexmap = "1.6.2"
2425
vfs = "0.5.1"
2526
smol_str = "0.1.21"

crates/driver/src/lib.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use fe_common::db::Upcast;
77
use fe_common::diagnostics::Diagnostic;
88
use fe_common::files::FileKind;
99
use fe_parser::ast::SmolStr;
10+
use fe_specgen::KSpec;
1011
use fe_test_runner::TestSink;
1112
use indexmap::{indexmap, IndexMap};
1213
use serde_json::Value;
@@ -86,6 +87,23 @@ pub fn compile_single_file_tests(
8687
}
8788
}
8889

90+
#[cfg(feature = "solc-backend")]
91+
pub fn generate_single_file_specs(
92+
db: &mut Db,
93+
path: &str,
94+
src: &str,
95+
optimize: bool,
96+
) -> Result<Vec<KSpec>, CompileError> {
97+
let module = ModuleId::new_standalone(db, path, src);
98+
let diags = module.diagnostics(db);
99+
100+
if diags.is_empty() {
101+
Ok(generate_module_specs(db, module, optimize))
102+
} else {
103+
Err(CompileError(diags))
104+
}
105+
}
106+
89107
// Run analysis with ingot
90108
// Return vector error,waring...
91109
pub fn check_ingot(
@@ -176,6 +194,46 @@ pub fn compile_ingot_tests(
176194
}
177195
}
178196

197+
#[cfg(feature = "solc-backend")]
198+
pub fn generate_ingot_specs(
199+
db: &mut Db,
200+
name: &str,
201+
files: &[(impl AsRef<str>, impl AsRef<str>)],
202+
optimize: bool,
203+
) -> Result<Vec<KSpec>, CompileError> {
204+
let std = IngotId::std_lib(db);
205+
let ingot = IngotId::from_files(
206+
db,
207+
name,
208+
IngotMode::Main,
209+
FileKind::Local,
210+
files,
211+
indexmap! { "std".into() => std },
212+
);
213+
214+
let mut diags = ingot.diagnostics(db);
215+
ingot.sink_external_ingot_diagnostics(db, &mut diags);
216+
if !diags.is_empty() {
217+
return Err(CompileError(diags));
218+
}
219+
220+
if diags.is_empty() {
221+
// Ok(ingot
222+
// .all_modules(db)
223+
// .iter()
224+
// .fold(vec![], |mut accum, module| {
225+
// accum.push((
226+
// module.name(db),
227+
// generate_module_specs(db, *module, optimize),
228+
// ));
229+
// accum
230+
// }))
231+
Ok(vec![])
232+
} else {
233+
Err(CompileError(diags))
234+
}
235+
}
236+
179237
/// Returns graphviz string.
180238
// TODO: This is temporary function for debugging.
181239
pub fn dump_mir_single_file(db: &mut Db, path: &str, src: &str) -> Result<String, CompileError> {
@@ -196,6 +254,7 @@ fn compile_test(db: &mut Db, test: FunctionId, optimize: bool) -> CompiledTest {
196254
let yul_test = fe_codegen::yul::isel::lower_test(db, test)
197255
.to_string()
198256
.replace('"', "\\\"");
257+
// panic!("{}", yul_test);
199258
let bytecode = compile_to_evm("test", &yul_test, optimize);
200259
CompiledTest::new(test.name(db), bytecode)
201260
}
@@ -209,6 +268,21 @@ fn compile_module_tests(db: &mut Db, module_id: ModuleId, optimize: bool) -> Vec
209268
.collect()
210269
}
211270

271+
#[cfg(feature = "solc-backend")]
272+
fn generate_spec(db: &mut Db, test: FunctionId, optimize: bool) -> KSpec {
273+
let code = compile_test(db, test, optimize).bytecode;
274+
KSpec::new(test.name(db), code, test.signature(db).params.len())
275+
}
276+
277+
#[cfg(feature = "solc-backend")]
278+
fn generate_module_specs(db: &mut Db, module_id: ModuleId, optimize: bool) -> Vec<KSpec> {
279+
module_id
280+
.invariants(db)
281+
.iter()
282+
.map(|test| generate_spec(db, *test, optimize))
283+
.collect()
284+
}
285+
212286
#[cfg(feature = "solc-backend")]
213287
fn compile_module(
214288
db: &mut Db,

crates/fe/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ fe-test-runner = {path = "../test-runner", version = "^0.22.0"}
2424
fe-common = {path = "../common", version = "^0.22.0"}
2525
fe-driver = {path = "../driver", version = "^0.22.0"}
2626
fe-parser = {path = "../parser", version = "^0.22.0"}
27+
fe-specgen = {path = "../specgen", version = "^0.22.0"}

crates/fe/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,9 @@ fn main() {
3030
Commands::Test(arg) => {
3131
task::test(arg);
3232
}
33+
#[cfg(feature = "solc-backend")]
34+
Commands::Specs(arg) => {
35+
task::specs(arg);
36+
}
3337
}
3438
}

0 commit comments

Comments
 (0)