pub mod util;
#[cfg(test)]
mod unit_tests;
use bytecode_verifier::VerifiedModule;
use failure::prelude::*;
use ir_to_bytecode::{compiler::compile_program, parser::parse_program};
use std::mem;
use stdlib::stdlib_modules;
use types::{
account_address::AccountAddress,
transaction::{Program, TransactionArgument},
};
use vm::file_format::CompiledProgram;
#[derive(Clone, Debug, Default)]
pub struct Compiler<'a> {
pub address: AccountAddress,
pub code: &'a str,
pub skip_stdlib_deps: bool,
pub stdlib_address: AccountAddress,
pub extra_deps: Vec<VerifiedModule>,
#[allow(missing_docs)]
#[doc(hidden)]
pub _non_exhaustive: (),
}
impl<'a> Compiler<'a> {
pub fn into_compiled_program(mut self) -> Result<CompiledProgram> {
Ok(self.compile_impl()?.0)
}
pub fn into_compiled_program_and_deps(
mut self,
) -> Result<(CompiledProgram, Vec<VerifiedModule>)> {
self.compile_impl()
}
pub fn into_script_blob(mut self) -> Result<Vec<u8>> {
let compiled_program = self.compile_impl()?.0;
let mut serialized_script = Vec::<u8>::new();
compiled_program.script.serialize(&mut serialized_script)?;
Ok(serialized_script)
}
pub fn into_program(mut self, args: Vec<TransactionArgument>) -> Result<Program> {
let compiled_program = self.compile_impl()?.0;
let mut serialized_script = Vec::<u8>::new();
compiled_program.script.serialize(&mut serialized_script)?;
let mut serialized_modules = vec![];
for m in compiled_program.modules {
let mut module = vec![];
m.serialize(&mut module).expect("module must serialize");
serialized_modules.push(module);
}
Ok(Program::new(serialized_script, serialized_modules, args))
}
fn compile_impl(&mut self) -> Result<(CompiledProgram, Vec<VerifiedModule>)> {
let parsed_program = parse_program(self.code)?;
let deps = self.deps();
let compiled_program = compile_program(&self.address, &parsed_program, &deps)?;
Ok((compiled_program, deps))
}
fn deps(&mut self) -> Vec<VerifiedModule> {
let extra_deps = mem::replace(&mut self.extra_deps, vec![]);
if self.skip_stdlib_deps {
extra_deps
} else {
let mut deps = stdlib_modules().to_vec();
deps.extend(extra_deps);
deps
}
}
}