harn_vm/bytecode_cache/
graph.rs1use std::path::Path;
4
5use crate::context_manifest::ContextManifest;
6use crate::module_artifact::ModuleCompilationContext;
7use crate::VmError;
8
9pub fn prepare_entry_store(source_path: &Path, source: &str) -> super::LookupOutcome {
15 let source_hash = super::sha256(source.as_bytes());
16 let (context_hash, manifest) = super::GraphWalk::new(source_path, source).finish();
17 super::LookupOutcome {
18 key: super::CacheKey {
19 source_hash,
20 context_hash,
21 harn_version: std::borrow::Cow::Borrowed(super::HARN_VERSION),
22 compiler_tag: super::compiler_options_tag(super::CompilerOptions::from_env()),
23 provenance: super::ModuleProvenance::User,
24 },
25 chunk: None,
26 manifest,
27 link_table: None,
28 }
29}
30
31pub(crate) fn derive_interface(
33 source_path: &Path,
34 source: &str,
35) -> Result<(ModuleCompilationContext, Option<ContextManifest>), VmError> {
36 let result = super::walk_import_graph_fingerprinted(
37 source_path,
38 source,
39 super::CODEGEN_FINGERPRINT,
40 true,
41 );
42 let context = match result.entry_compilation_context {
43 Some(context) => {
44 #[cfg(test)]
45 crate::module_artifact::INTERFACE_RESOLUTIONS.with(|count| count.set(count.get() + 1));
46 context
47 }
48 None => crate::module_artifact::module_compilation_context_for_source(source_path, source)?,
49 };
50 Ok((context, result.manifest))
51}
52
53pub(super) fn relative_path_label(base: &Path, target: &Path) -> Option<String> {
55 let base_components = base.components().collect::<Vec<_>>();
56 let target_components = target.components().collect::<Vec<_>>();
57 let common = base_components
58 .iter()
59 .zip(&target_components)
60 .take_while(|(left, right)| left == right)
61 .count();
62 if common == 0 && (base.is_absolute() || target.is_absolute()) {
63 return None;
64 }
65
66 let mut parts = Vec::new();
67 for component in &base_components[common..] {
68 if matches!(component, std::path::Component::Normal(_)) {
69 parts.push("..".to_string());
70 }
71 }
72 for component in &target_components[common..] {
73 match component {
74 std::path::Component::Normal(part) => parts.push(part.to_string_lossy().into_owned()),
75 std::path::Component::ParentDir => parts.push("..".to_string()),
76 std::path::Component::CurDir => {}
77 std::path::Component::RootDir | std::path::Component::Prefix(_) => return None,
78 }
79 }
80 Some(if parts.is_empty() {
81 ".".to_string()
82 } else {
83 parts.join("/")
84 })
85}