Skip to content

Commit

Permalink
[compiler-v2] Add Bytecode verification at the end of compilation (ap…
Browse files Browse the repository at this point in the history
  • Loading branch information
vineethk authored Feb 8, 2024
1 parent 183c6c8 commit 47a2e45
Show file tree
Hide file tree
Showing 22 changed files with 3,319 additions and 50 deletions.
2 changes: 1 addition & 1 deletion third_party/move/move-compiler-v2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ move-command-line-common = { path = "../move-command-line-common" }
#move-package = { path = "../tools/move-package" }
move-compiler = { path = "../move-compiler" }
move-core-types = { path = "../move-core/types" }
move-disassembler = { path = "../tools/move-disassembler" }
move-ir-types = { path = "../move-ir/types" }
move-model = { path = "../move-model" }
move-stackless-bytecode = { path = "../move-model/bytecode" }
Expand All @@ -42,7 +43,6 @@ serde = { version = "1.0.124", features = ["derive"] }
anyhow = "1.0.52"
datatest-stable = "0.1.1"
move-command-line-common = { path = "../move-command-line-common" }
move-disassembler = { path = "../tools/move-disassembler" }
move-ir-types = { path = "../move-ir/types" }
move-prover-test-utils = { path = "../move-prover/test-utils" }
move-stdlib = { path = "../move-stdlib" }
Expand Down
55 changes: 46 additions & 9 deletions third_party/move/move-compiler-v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,19 @@ use anyhow::bail;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream, WriteColor};
pub use experiments::*;
use log::{debug, info, log_enabled, trace, Level};
use move_binary_format::binary_views::BinaryIndexedView;
use move_command_line_common::files::FileHash;
use move_compiler::{
compiled_unit::{
AnnotatedCompiledModule, AnnotatedCompiledScript, AnnotatedCompiledUnit, CompiledUnit,
FunctionInfo,
verify_units, AnnotatedCompiledModule, AnnotatedCompiledScript, AnnotatedCompiledUnit,
CompiledUnit, FunctionInfo,
},
diagnostics::FilesSourceText,
shared::{known_attributes::KnownAttribute, unique_map::UniqueMap},
};
use move_model::{model::GlobalEnv, PackageInfo};
use move_disassembler::disassembler::Disassembler;
use move_ir_types::location;
use move_model::{add_move_lang_diagnostics, model::GlobalEnv, PackageInfo};
use move_stackless_bytecode::function_target_pipeline::{
FunctionTargetPipeline, FunctionTargetsHolder, FunctionVariant,
};
Expand All @@ -60,7 +64,7 @@ pub fn run_move_compiler(
let mut env = run_checker(options.clone())?;
check_errors(&env, error_writer, "checking errors")?;

trace!("After context check, GlobalEnv={}", env.dump_env());
trace!("After context check, GlobalEnv=\n{}", env.dump_env());

// Flow-insensitive checks on AST
flow_insensitive_checkers::check_for_unused_vars_and_params(&mut env);
Expand All @@ -69,15 +73,15 @@ pub fn run_move_compiler(
check_errors(&env, error_writer, "checking errors")?;

trace!(
"After flow-insensitive checks, GlobalEnv={}",
"After flow-insensitive checks, GlobalEnv=\n{}",
env.dump_env()
);

// Run inlining.
inliner::run_inlining(&mut env);
check_errors(&env, error_writer, "inlining")?;

debug!("After inlining, GlobalEnv={}", env.dump_env());
debug!("After inlining, GlobalEnv=\n{}", env.dump_env());

// Run code generator
let mut targets = run_bytecode_gen(&env);
Expand Down Expand Up @@ -110,8 +114,17 @@ pub fn run_move_compiler(

let modules_and_scripts = run_file_format_gen(&env, &targets);
check_errors(&env, error_writer, "assembling errors")?;
let annotated = annotate_units(modules_and_scripts);
Ok((env, annotated))

debug!(
"File format bytecode:\n{}",
disassemble_compiled_units(&modules_and_scripts)?
);

let annotated_units = annotate_units(modules_and_scripts);
run_bytecode_verifier(&annotated_units, &mut env);
check_errors(&env, error_writer, "bytecode verification errors")?;

Ok((env, annotated_units))
}

/// Run the type checker and return the global env (with errors if encountered). The result
Expand Down Expand Up @@ -151,7 +164,7 @@ pub fn run_checker(options: Options) -> anyhow::Result<GlobalEnv> {
// compilation, create an entry in the functions target holder which encapsulate info
// like the generated bytecode.
pub fn run_bytecode_gen(env: &GlobalEnv) -> FunctionTargetsHolder {
info!("Bytecode Generation");
info!("Stackless bytecode Generation");
let mut targets = FunctionTargetsHolder::default();
let mut todo = BTreeSet::new();
let mut done = BTreeSet::new();
Expand Down Expand Up @@ -232,6 +245,30 @@ fn add_default_optimization_pipeline(pipeline: &mut FunctionTargetPipeline) {
pipeline.add_processor(Box::new(UnreachableCodeRemover {}));
}

/// Disassemble the given compiled units and return the disassembled code as a string.
pub fn disassemble_compiled_units(units: &[CompiledUnit]) -> anyhow::Result<String> {
let disassembled_units: anyhow::Result<Vec<_>> = units
.iter()
.map(|unit| {
let view = match unit {
CompiledUnit::Module(module) => BinaryIndexedView::Module(&module.module),
CompiledUnit::Script(script) => BinaryIndexedView::Script(&script.script),
};
Disassembler::from_view(view, location::Loc::new(FileHash::empty(), 0, 0))
.and_then(|d| d.disassemble())
})
.collect();
Ok(disassembled_units?.concat())
}

/// Run the bytecode verifier on the given compiled units and add any diagnostics to the global env.
pub fn run_bytecode_verifier(units: &[AnnotatedCompiledUnit], env: &mut GlobalEnv) {
let diags = verify_units(units);
if !diags.is_empty() {
add_move_lang_diagnostics(env, diags);
}
}

/// Report any diags in the env to the writer and fail if there are errors.
pub fn check_errors<W: WriteColor>(
env: &GlobalEnv,
Expand Down
Loading

0 comments on commit 47a2e45

Please sign in to comment.