Skip to content

Commit 37c2226

Browse files
committed
chore: move file field to SourceCode
1 parent 39e9678 commit 37c2226

File tree

5 files changed

+77
-70
lines changed

5 files changed

+77
-70
lines changed

src/functions/cache.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ use stable_mir::{
1010
CrateDef, DefId,
1111
mir::{Body, mono::Instance},
1212
};
13-
use std::{cell::RefCell, sync::Arc};
13+
use std::{cell::RefCell, cmp::Ordering, sync::Arc};
1414

1515
thread_local! {
16-
static CACHE: RefCell<Cache> = RefCell::new(Cache::default());
16+
static CACHE: RefCell<Cache> = RefCell::new(Cache::new());
1717
}
1818

1919
pub fn set_rustc_ctx(tcx: TyCtxt) {
@@ -29,8 +29,12 @@ pub fn clear_rustc_ctx() {
2929
CACHE.with(|c| c.borrow_mut().rustc = None);
3030
}
3131

32+
fn get_cache<T>(f: impl FnOnce(&mut Cache) -> T) -> T {
33+
CACHE.with(|c| f(&mut c.borrow_mut()))
34+
}
35+
3236
fn get_cache_func<T>(inst: &Instance, f: impl FnOnce(&CacheFunction) -> T) -> Option<T> {
33-
CACHE.with(|c| c.borrow_mut().get_or_insert(inst).map(f))
37+
get_cache(|cache| cache.get_or_insert(inst).map(f))
3438
}
3539

3640
pub fn get_body<T>(inst: &Instance, f: impl FnOnce(&Body) -> T) -> Option<T> {
@@ -41,20 +45,37 @@ pub fn get_source_code(inst: &Instance) -> Option<SourceCode> {
4145
get_cache_func(inst, |cf| cf.src.clone())
4246
}
4347

44-
#[derive(Default)]
48+
pub fn cmp_callees(a: &Instance, b: &Instance) -> Ordering {
49+
get_cache(|cache| {
50+
cache.get_or_insert(a);
51+
cache.get_or_insert(b);
52+
let func_a = cache.set.get(&a.def.def_id()).unwrap().as_ref().map(|f| &f.src);
53+
let func_b = cache.set.get(&b.def.def_id()).unwrap().as_ref().map(|f| &f.src);
54+
func_a.cmp(&func_b)
55+
})
56+
}
57+
4558
struct Cache {
46-
rustc: Option<RustcCxt>,
4759
set: FxHashMap<DefId, Option<CacheFunction>>,
60+
rustc: Option<RustcCxt>,
61+
path_prefixes: PathPrefixes,
4862
}
4963

5064
impl Cache {
65+
fn new() -> Self {
66+
let (set, rustc) = Default::default();
67+
let path_prefixes = PathPrefixes::new();
68+
Cache { set, rustc, path_prefixes }
69+
}
70+
5171
fn get_or_insert(&mut self, inst: &Instance) -> Option<&CacheFunction> {
5272
self.set
5373
.entry(inst.def.def_id())
5474
.or_insert_with(|| {
5575
let body = inst.body()?;
5676
let rustc = self.rustc.as_ref()?;
57-
let src = source_code_with(body.span, rustc.tcx, &rustc.src_map);
77+
let prefix = self.path_prefixes.prefixes();
78+
let src = source_code_with(body.span, rustc.tcx, &rustc.src_map, prefix);
5879
Some(CacheFunction { body, src })
5980
})
6081
.as_ref()
@@ -70,3 +91,24 @@ struct CacheFunction {
7091
body: Body,
7192
src: SourceCode,
7293
}
94+
95+
struct PathPrefixes {
96+
pwd: String,
97+
sysroot: String,
98+
}
99+
100+
impl PathPrefixes {
101+
fn new() -> Self {
102+
let mut pwd = std::env::current_dir().unwrap().into_os_string().into_string().unwrap();
103+
pwd.push('/');
104+
105+
let out = std::process::Command::new("rustc").arg("--print=sysroot").output().unwrap();
106+
let sysroot = std::str::from_utf8(&out.stdout).unwrap().trim();
107+
let sysroot = format!("{sysroot}/lib/rustlib/src/rust/");
108+
PathPrefixes { pwd, sysroot }
109+
}
110+
111+
fn prefixes(&self) -> [&str; 2] {
112+
[&*self.pwd, &self.sysroot]
113+
}
114+
}

src/functions/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl Function {
7575

7676
let mut callees = IndexSet::new();
7777
callgraph.recursive_callees(item, &mut callees);
78-
callees.sort_by(utils::cmp_callees);
78+
callees.sort_by(cache::cmp_callees);
7979

8080
let this = Function { instance, attrs, callees };
8181
filter(&this).then_some(this)

src/functions/serialization.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use super::{
2-
cache,
3-
utils::{self, SourceCode},
4-
};
1+
use super::{cache, utils::SourceCode};
52
use rustc_stable_hash::{FromStableHash, SipHasher128Hash, StableHasher, hashers::SipHasher128};
63
use serde::Serialize;
74
use stable_mir::{CrateDef, mir::mono::Instance};
@@ -13,9 +10,6 @@ pub struct SerFunction {
1310
hash: String,
1411
/// DefId in stable_mir.
1512
def_id: String,
16-
/// Every funtion must be declared in a specific file, even for those
17-
/// generated by macros.
18-
file: String,
1913
/// Attributes are attached the function, but it seems that attributes
2014
/// and function must be separated to query.
2115
attrs: Vec<String>,
@@ -29,31 +23,28 @@ impl SerFunction {
2923
pub fn new(fun: super::Function) -> Self {
3024
let inst = fun.instance;
3125
let def_id = format_def_id(&inst);
32-
let file = utils::file_path(&inst);
3326
let attrs: Vec<_> = fun.attrs.iter().map(|a| a.as_str().to_owned()).collect();
3427
// Though this is from body span, fn name and signature are included.
3528
let func = cache::get_source_code(&inst).unwrap_or_default();
36-
let callees: Vec<_> = fun.callees.iter().map(|x| Callee::new(x)).collect();
29+
let callees: Vec<_> = fun.callees.iter().map(Callee::new).collect();
3730

3831
// Hash
3932
let mut hasher = StableHasher::<SipHasher128>::new();
40-
hasher.write_str(&file);
4133
func.with_hasher(&mut hasher);
4234
hasher.write_length_prefix(attrs.len());
4335
attrs.iter().for_each(|a| hasher.write_str(a));
4436
hasher.write_length_prefix(callees.len());
4537
callees.iter().for_each(|c| {
46-
hasher.write_str(&c.file);
4738
c.func.with_hasher(&mut hasher);
4839
});
4940
let Hash128(hash) = hasher.finish();
5041

51-
SerFunction { hash, def_id, file, attrs, func, callees }
42+
SerFunction { hash, def_id, attrs, func, callees }
5243
}
5344

5445
/// Compare by file and func string.
5546
pub fn cmp_by_file_and_func(&self, other: &Self) -> Ordering {
56-
(&*self.file, &self.func).cmp(&(&*other.file, &other.func))
47+
self.func.cmp(&other.func)
5748
}
5849
}
5950

@@ -76,15 +67,13 @@ fn format_def_id(inst: &Instance) -> String {
7667
#[derive(Debug, Serialize)]
7768
pub struct Callee {
7869
def_id: String,
79-
file: String,
8070
func: SourceCode,
8171
}
8272

8373
impl Callee {
8474
fn new(inst: &Instance) -> Self {
8575
let def_id = format_def_id(inst);
86-
let file = utils::file_path(inst);
8776
let func = cache::get_source_code(inst).unwrap_or_default();
88-
Callee { def_id, file, func }
77+
Callee { def_id, func }
8978
}
9079
}

src/functions/utils.rs

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,29 @@ use rustc_smir::rustc_internal::internal;
33
use rustc_span::{Span, source_map::SourceMap};
44
use rustc_stable_hash::{StableHasher, hashers::SipHasher128};
55
use serde::Serialize;
6-
use stable_mir::{CrateDef, mir::mono::Instance};
7-
use std::{cmp::Ordering, hash::Hasher};
8-
9-
use super::cache;
6+
use std::hash::Hasher;
107

118
/// Source code and potential source code before expansion.
129
///
13-
/// Refer to
10+
/// The field order matters, since this struct implements Ord.
1411
#[derive(Clone, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord, Default)]
1512
pub struct SourceCode {
16-
// TODO:
17-
// file: String,
18-
//
13+
// A file path where src lies.
14+
// The path is stripped with pwd or sysroot prefix.
15+
pub file: String,
16+
1917
/// Source that a stable_mir span points to.
2018
pub src: String,
19+
2120
/// Is the stable_mir span from a macro expansion?
2221
/// If it is from an expansion, what's the source code before expansion?
2322
/// * Some(_) happens when the src (stable_mir) span comes from expansion, and tells
2423
/// the source before the expansion.
2524
/// * None if the src is not from a macro expansion.
25+
///
26+
/// Refer to [#31] to know sepecific cases.
27+
///
28+
/// [#31]: https://github.com/os-checker/distributed-verification/issues/31
2629
pub before_expansion: Option<String>,
2730
}
2831

@@ -54,46 +57,22 @@ pub fn source_code_with(
5457
stable_mir_span: stable_mir::ty::Span,
5558
tcx: TyCtxt,
5659
src_map: &SourceMap,
60+
path_prefixes: [&str; 2],
5761
) -> SourceCode {
5862
let span = internal(tcx, stable_mir_span);
5963
let src = span_to_source(span, src_map);
6064
let before_expansion = span.from_expansion().then(|| {
6165
let ancestor_span = span.find_oldest_ancestor_in_same_ctxt();
6266
span_to_source(ancestor_span, src_map)
6367
});
64-
SourceCode { src, before_expansion }
65-
}
66-
67-
pub fn cmp_callees(a: &Instance, b: &Instance) -> Ordering {
68-
let filename_a = file_path(a);
69-
let filename_b = file_path(b);
70-
match filename_a.cmp(&filename_b) {
71-
Ordering::Equal => (),
72-
ord => return ord,
73-
}
74-
75-
let body_a = cache::get_source_code(a);
76-
let body_b = cache::get_source_code(b);
77-
body_a.cmp(&body_b)
78-
}
79-
80-
pub fn file_path(inst: &Instance) -> String {
81-
use std::sync::LazyLock;
82-
static PREFIXES: LazyLock<[String; 2]> = LazyLock::new(|| {
83-
let mut pwd = std::env::current_dir().unwrap().into_os_string().into_string().unwrap();
84-
pwd.push('/');
85-
86-
let out = std::process::Command::new("rustc").arg("--print=sysroot").output().unwrap();
87-
let sysroot = std::str::from_utf8(&out.stdout).unwrap().trim();
88-
let sysroot = format!("{sysroot}/lib/rustlib/src/rust/");
89-
[pwd, sysroot]
90-
});
9168

92-
let file = inst.def.span().get_filename();
93-
for prefix in &*PREFIXES {
94-
if let Some(file) = file.strip_prefix(prefix) {
95-
return file.to_owned();
69+
let mut file = stable_mir_span.get_filename();
70+
for prefix in path_prefixes {
71+
if let Some(file_stripped) = file.strip_prefix(prefix) {
72+
file = file_stripped.to_owned();
73+
break;
9674
}
9775
}
98-
file
76+
77+
SourceCode { file, src, before_expansion }
9978
}

src/lib.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pub struct SerFunction {
66
pub hash: String,
77
/// DefId in stable_mir.
88
pub def_id: String,
9-
/// Every funtion must be declared in a specific file, even for those
10-
/// generated by macros.
11-
pub file: String,
129
/// Attributes are attached the function, but it seems that attributes
1310
/// and function must be separated to query.
1411
pub attrs: Vec<String>,
@@ -21,15 +18,15 @@ pub struct SerFunction {
2118
#[derive(Debug, Serialize, Deserialize)]
2219
pub struct Callee {
2320
pub def_id: String,
24-
pub file: String,
2521
pub func: SourceCode,
2622
}
2723

2824
#[derive(Debug, Serialize, Deserialize)]
2925
pub struct SourceCode {
30-
// TODO:
31-
// file: String,
32-
//
26+
// A file path where src lies.
27+
// The path is stripped with pwd or sysroot prefix.
28+
file: String,
29+
3330
/// Source that a stable_mir span points to.
3431
pub src: String,
3532
/// Is the stable_mir span from a macro expansion?

0 commit comments

Comments
 (0)