Skip to content

Commit

Permalink
Disassembler (#166, DFI-455)
Browse files Browse the repository at this point in the history
* Move disassembler.

* Refactoring.

* Added disassemble documentation.
  • Loading branch information
RIg410 authored Aug 7, 2020
1 parent c05cab2 commit cd6b176
Show file tree
Hide file tree
Showing 68 changed files with 4,711 additions and 928 deletions.
127 changes: 78 additions & 49 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ rand = "0.7.3"
log = "0.4.8"
termcolor = "1.1.0"
reqwest = { version = "0.10.4", features = ["blocking", "json"] }
itertools = "0.9.0"

[dev-dependencies]
ds = { path = "../data-source", package = "dvm-data-source" }
1 change: 1 addition & 0 deletions compiler/src/cmd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::manifest::MoveToml;
use crate::mv::builder::Builder;
use crate::mv::dependence::loader::make_rest_loader;

/// Execute build command.
pub fn execute(project_dir: &Path, manifest: MoveToml) -> Result<()> {
let loader = make_rest_loader(&project_dir, &manifest)?;
let builder = Builder::new(project_dir, manifest, &loader, true, true);
Expand Down
1 change: 1 addition & 0 deletions compiler/src/cmd/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::manifest::MoveToml;
use crate::mv::builder::Builder;
use crate::mv::dependence::loader::make_rest_loader;

/// Execute check command.
pub fn execute(project_dir: &Path, manifest: MoveToml) -> Result<()> {
let loader = make_rest_loader(project_dir, &manifest)?;
let builder = Builder::new(project_dir, manifest, &loader, true, true);
Expand Down
1 change: 1 addition & 0 deletions compiler/src/cmd/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::path::Path;
use crate::manifest::{MANIFEST, MoveToml, store_manifest, Layout};
use std::fs;

/// Execute init command.
pub fn execute(
project_dir: &Path,
source_dir: String,
Expand Down
5 changes: 5 additions & 0 deletions compiler/src/cmd/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/// Project builder.
pub mod build;
/// Project checker.
pub mod check;
/// Project initializer.
pub mod init;
/// Project creator.
pub mod new;
/// Project dependencies loader.
pub mod update;
1 change: 1 addition & 0 deletions compiler/src/cmd/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::path::Path;
use std::fs;
use crate::cmd::init;

/// Execute create project command.
pub fn execute(
root: &Path,
source_dir: String,
Expand Down
1 change: 1 addition & 0 deletions compiler/src/cmd/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::path::Path;
use crate::manifest::MoveToml;
use std::fs;

/// Execute update dependencies command.
pub fn execute(project_dir: &Path, manifest: MoveToml) -> Result<(), Error> {
let cache_path = manifest
.layout
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/embedded/ds_loader.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::mv::dependence::loader::BytecodeSource;
use crate::mv::dependence::loader::BytecodeLoader;
use anyhow::Result;
use libra::prelude::*;

Expand All @@ -16,7 +16,7 @@ where
}
}

impl<S> BytecodeSource for StateViewLoader<S>
impl<S> BytecodeLoader for StateViewLoader<S>
where
S: StateView + Clone,
{
Expand Down
10 changes: 10 additions & 0 deletions compiler/src/embedded/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::manifest::{MoveToml, Layout};
use std::fs::OpenOptions;
use std::io::Write;

/// Embedded move compiler.
#[derive(Clone)]
pub struct Compiler<S: StateView + Clone> {
loader: Option<Loader<StateViewLoader<S>>>,
Expand All @@ -22,12 +23,14 @@ impl<S> Compiler<S>
where
S: StateView + Clone,
{
/// Create move compiler.
pub fn new(view: S) -> Compiler<S> {
Compiler {
loader: Some(Loader::new(None, StateViewLoader::new(view))),
}
}

/// Compile multiple sources.
pub fn compile_source_map(
&self,
source_map: HashMap<String, String>,
Expand Down Expand Up @@ -69,6 +72,7 @@ where
builder.verify(text_source, units)
}

/// Compiler source codes.
pub fn compile(&self, code: &str, address: Option<AccountAddress>) -> Result<Vec<u8>> {
let mut source_map = HashMap::new();
source_map.insert("source".to_string(), code.to_string());
Expand All @@ -81,11 +85,14 @@ where
}
}

/// Temp directory.
/// Random temporary directory which will be removed when 'TempDir' drop.
pub struct TempDir {
path: PathBuf,
}

impl TempDir {
/// Create a new temporary directory.
pub fn new() -> Result<TempDir> {
let dir = env::temp_dir();
let mut rng = rand::thread_rng();
Expand All @@ -98,6 +105,7 @@ impl TempDir {
Ok(TempDir { path })
}

/// Returns the directory path.
pub fn path(&self) -> &Path {
&self.path
}
Expand All @@ -116,11 +124,13 @@ impl Drop for TempDir {
}
}

/// Compiler string with move source code.
pub fn compile(code: &str, address: Option<AccountAddress>) -> Result<Vec<u8>> {
let compiler = Compiler::new(ZeroStateView);
compiler.compile(code, address)
}

/// State view mock.
#[derive(Clone)]
struct ZeroStateView;

Expand Down
8 changes: 8 additions & 0 deletions compiler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
//! Move compiler.
#![deny(missing_docs)]

#[macro_use]
extern crate anyhow;
#[macro_use]
extern crate log;

/// Movec commands handler.
pub mod cmd;
/// Move embedded compiler.
mod embedded;
/// Movec configuration.
pub mod manifest;
/// Move compiler components.
mod mv;

pub use mv::*;
Expand Down
20 changes: 20 additions & 0 deletions compiler/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,50 @@ use std::fs::OpenOptions;
use std::io::Write;
use toml::Value;

/// Movec manifest name.
pub const MANIFEST: &str = "Move.toml";

/// Movec manifest.
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct MoveToml {
/// Project info.
pub package: Package,
/// Project layout.
pub layout: Option<Layout>,
}

/// Project info.
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct Package {
/// Project name.
pub name: Option<String>,
/// Project AccountAddress.
pub account_address: Option<String>,
/// Authors list.
pub authors: Option<Vec<String>>,
/// dnode base url.
pub blockchain_api: Option<String>,
}

/// Project layout.
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct Layout {
/// Directory with module sources.
pub module_dir: Option<String>,
/// Directory with script sources.
pub script_dir: Option<String>,
/// Movec cache.
pub bytecode_cache: Option<String>,
/// Directory with compiled modules.
pub module_output: Option<String>,
/// Directory with compiled scripts.
pub script_output: Option<String>,
/// Processing directory.
pub temp_dir: Option<String>,
}

impl Layout {
/// Create a new layout.
pub fn new() -> Layout {
Layout {
module_dir: None,
Expand All @@ -44,6 +61,7 @@ impl Layout {
}
}

/// Fill layout with default values.
pub fn fill(&mut self) {
self.module_dir
.get_or_insert_with(|| "src/modules".to_owned());
Expand All @@ -60,10 +78,12 @@ impl Layout {
}
}

/// Reads the manifest by path.
pub fn read_manifest(path: &Path) -> Result<MoveToml, Error> {
Ok(toml::from_str(&fs::read_to_string(path)?)?)
}

/// Stores the manifest by path.
pub fn store_manifest(path: &Path, manifest: MoveToml) -> Result<(), Error> {
let value = toml::to_vec(&Value::try_from(manifest)?)?;
let mut f = OpenOptions::new()
Expand Down
21 changes: 15 additions & 6 deletions compiler/src/mv/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ use walkdir::WalkDir;
use std::fs::{File, OpenOptions};
use crate::mv::bech32::bech32_into_libra;
use std::io::Write;
use crate::mv::{preprocessor, disassembler};
use crate::mv::{preprocessor};
use anyhow::{Result, Error};
use libra::{prelude::*, compiler::*};
use crate::mv::dependence::extractor::{extract_from_source, extract_from_bytecode};
use crate::mv::dependence::loader::{BytecodeSource, Loader};
use crate::mv::dependence::loader::{BytecodeLoader, Loader};
use std::collections::{HashMap, HashSet};
use termcolor::{StandardStream, ColorChoice, Buffer};
use crate::mv::disassembler::unit::{CompiledUnit as Unit};
use crate::mv::disassembler::{Config, Disassembler};

/// Move builder.
pub struct Builder<'a, S: BytecodeSource> {
pub struct Builder<'a, S: BytecodeLoader> {
/// movec project directory.
project_dir: &'a Path,
/// movec manifest.
Expand All @@ -31,7 +33,7 @@ pub struct Builder<'a, S: BytecodeSource> {

impl<'a, S> Builder<'a, S>
where
S: BytecodeSource,
S: BytecodeLoader,
{
/// Creates a new move builder.
pub fn new(
Expand Down Expand Up @@ -135,7 +137,14 @@ where
let mut path_list = Vec::with_capacity(bytecode.len());

for (id, bytecode) in bytecode {
let signature = disassembler::module_signature(&bytecode)?.to_string();
let config = Config {
light_version: true,
};
let unit = Unit::new(&bytecode)?;
let disasm = Disassembler::new(&unit, config);
let source_unit = disasm.make_source_unit();
let signature = source_unit.code_string()?;

let path = deps.join(format!("{}_{}.move", id.address(), id.name().as_str()));

let mut f = OpenOptions::new()
Expand Down Expand Up @@ -436,7 +445,7 @@ pub fn convert_path(path_list: &[PathBuf]) -> Result<Vec<String>> {

impl<'a, S> Drop for Builder<'a, S>
where
S: BytecodeSource,
S: BytecodeLoader,
{
/// Cleans up the builder layout.
fn drop(&mut self) {
Expand Down
Loading

0 comments on commit cd6b176

Please sign in to comment.