Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions crates/move-prover-boogie-backend/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ fn generate_function_bpl<W: WriteColor>(
let target_type = FunctionHolderTarget::Function(*qid);
let (mut targets, _) = create_and_process_bytecode(options, env, package_targets, target_type);

write_spec_hierarchy_logs(env, &targets, &options, asserts_mode);

check_errors(
env,
&options,
Expand Down Expand Up @@ -378,6 +380,8 @@ fn generate_module_bpl<W: WriteColor>(

let (mut targets, _) = create_and_process_bytecode(options, env, package_targets, target_type);

write_spec_hierarchy_logs(env, &targets, &options, asserts_mode);

check_errors(
env,
&options,
Expand Down Expand Up @@ -731,6 +735,20 @@ pub async fn verify_boogie(
Ok(())
}

/// Write spec hierarchy log files for all specs in the given targets.
/// Only writes during `AssertsMode::Check` to avoid duplicate writes.
fn write_spec_hierarchy_logs(
env: &GlobalEnv,
targets: &FunctionTargetsHolder,
options: &Options,
asserts_mode: AssertsMode,
) {
if asserts_mode == AssertsMode::Check {
let output_dir = Path::new(&options.output_path);
spec_hierarchy::display_spec_hierarchy(env, targets, output_dir);
}
}

/// Create bytecode and process it.
pub fn create_and_process_bytecode(
options: &Options,
Expand Down
76 changes: 48 additions & 28 deletions crates/move-stackless-bytecode/src/spec_hierarchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,37 +49,57 @@ struct CallInfo {
/// * `env` - Global environment containing all function and module information
/// * `targets` - Holder containing all specs and their relationships
/// * `output_dir` - Directory where .log.txt files will be written
pub fn display_spec_hierarchy(env: &GlobalEnv, targets: &FunctionTargetsHolder, output_dir: &Path) {
/// Writes the hierarchy log file for a single spec using already-built targets.
///
/// This is designed to be called during verification, reusing the
/// `FunctionTargetsHolder` that was already created with proper per-spec
/// filtering (e.g. `FunctionHolderTarget::Function`).
///
/// # Arguments
/// * `env` - Global environment
/// * `targets` - Targets holder with spec mappings (already built for this spec's context)
/// * `spec_id` - The spec to write the hierarchy for
/// * `output_dir` - Directory where .log.txt files will be written
pub fn write_spec_hierarchy_log(
env: &GlobalEnv,
targets: &FunctionTargetsHolder,
spec_id: &QualifiedId<FunId>,
output_dir: &Path,
) {
let excluded_addresses = get_excluded_addresses();
let spec_env = env.get_function(*spec_id);
let spec_name = spec_env.get_full_name_str();

for spec_id in targets.specs() {
let spec_env = env.get_function(*spec_id);
let spec_name = spec_env.get_full_name_str();
if let Some(fun_id) = targets.get_fun_by_spec(spec_id) {
let func_env = env.get_function(*fun_id);
let header = func_env.get_full_name_str();
write_spec_log_file(
env,
targets,
&func_env,
spec_name,
&header,
output_dir,
&excluded_addresses,
);
} else if targets.is_scenario_spec(spec_id) {
let header = format!("{} {}", spec_env.get_full_name_str(), SCENARIO_LABEL);
write_spec_log_file(
env,
targets,
&spec_env,
spec_name,
&header,
output_dir,
&excluded_addresses,
);
}
}

if let Some(fun_id) = targets.get_fun_by_spec(spec_id) {
let func_env = env.get_function(*fun_id);
let header = func_env.get_full_name_str();
write_spec_log_file(
env,
targets,
&func_env,
spec_name,
&header,
output_dir,
&excluded_addresses,
);
} else if targets.is_scenario_spec(spec_id) {
let header = format!("{} {}", spec_env.get_full_name_str(), SCENARIO_LABEL);
write_spec_log_file(
env,
targets,
&spec_env,
spec_name,
&header,
output_dir,
&excluded_addresses,
);
}
/// Writes hierarchy log files for all specs in the given targets.
pub fn display_spec_hierarchy(env: &GlobalEnv, targets: &FunctionTargetsHolder, output_dir: &Path) {
for spec_id in targets.specs() {
write_spec_hierarchy_log(env, targets, spec_id, output_dir);
}
}

Expand Down
19 changes: 1 addition & 18 deletions crates/sui-prover/src/prove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ use move_core_types::account_address::AccountAddress;
use move_model::model::GlobalEnv;
use move_package::{BuildConfig as MoveBuildConfig, LintFlag};
use move_prover_boogie_backend::boogie_backend::options::BoogieFileMode;
use move_prover_boogie_backend::generator::{create_and_process_bytecode, run_boogie_gen};
use move_prover_boogie_backend::generator::run_boogie_gen;
use move_stackless_bytecode::function_stats;
use move_stackless_bytecode::function_target_pipeline::FunctionHolderTarget;
use move_stackless_bytecode::package_targets::PackageTargets;
use move_stackless_bytecode::spec_hierarchy;
use move_stackless_bytecode::target_filter::TargetFilterOptions;
use std::{
collections::BTreeMap,
Expand Down Expand Up @@ -184,21 +182,6 @@ pub async fn execute(
return Ok(());
}

let mut options = move_prover_boogie_backend::generator_options::Options::default();
options.filter = filter.clone();
let (targets, _) = create_and_process_bytecode(
&options,
&model,
&package_targets,
FunctionHolderTarget::All,
);

let output_dir = std::path::Path::new(&options.output_path);
if !output_dir.exists() {
std::fs::create_dir_all(output_dir)?;
}
spec_hierarchy::display_spec_hierarchy(&model, &targets, output_dir);

execute_backend_boogie(model, &general_config, remote_config, boogie_config, filter).await
}

Expand Down
Loading