Skip to content

Commit

Permalink
feat(compile): compile w/dependencies and options (#965)
Browse files Browse the repository at this point in the history
* feat(compile): compile w/dependencies and options

* choir: Adds missing crate dependency

* fix(compile): returns unwrapped result

* choir(fmt): Fixing fmt

* choir: Updated to match result

---------

Co-authored-by: Koby <koby@aztecprotocol.com>
  • Loading branch information
kobyhallx and Koby authored Mar 9, 2023
1 parent 870ea46 commit 3f897f6
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 10 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion crates/noirc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use noirc_frontend::hir::def_map::{Contract, CrateDefMap};
use noirc_frontend::hir::Context;
use noirc_frontend::monomorphization::monomorphize;
use noirc_frontend::node_interner::FuncId;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};

mod program;
Expand All @@ -23,7 +24,7 @@ pub struct Driver {
language: Language,
}

#[derive(Args, Clone, Debug)]
#[derive(Args, Clone, Debug, Serialize, Deserialize)]
pub struct CompileOptions {
/// Emit debug information for the intermediate SSA IR
#[arg(short, long)]
Expand Down
1 change: 1 addition & 0 deletions crates/noirc_errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ codespan-reporting.workspace = true
codespan.workspace = true
fm.workspace = true
chumsky.workspace = true
serde.workspace = true
3 changes: 2 additions & 1 deletion crates/noirc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ mod position;
pub mod reporter;
pub use position::{Location, Position, Span, Spanned};
pub use reporter::{CustomDiagnostic, DiagnosticKind};
use serde::{Deserialize, Serialize};

/// Returned when the Reporter finishes after reporting errors
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Serialize, Deserialize)]
pub struct ReportedError;

#[derive(Debug, PartialEq, Eq)]
Expand Down
1 change: 1 addition & 0 deletions crates/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ crate-type = ["cdylib"]

acvm.workspace = true
noirc_driver.workspace = true
noirc_frontend.workspace = true
wasm-bindgen.workspace = true
serde.workspace = true

Expand Down
67 changes: 59 additions & 8 deletions crates/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use acvm::acir::circuit::Circuit;
use gloo_utils::format::JsValueSerdeExt;
use noirc_driver::{CompileOptions, Driver};
use noirc_frontend::graph::{CrateName, CrateType};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use wasm_bindgen::prelude::*;
Expand All @@ -15,24 +17,73 @@ pub struct BuildInfo {
dirty: &'static str,
}

#[derive(Serialize, Deserialize)]
pub struct WASMCompileOptions {
// Compile each contract function used within the program
#[serde(default = "bool::default")]
contracts: bool,

#[serde(default)]
compile_options: CompileOptions,

#[serde(default)]
optional_dependencies_set: Vec<String>,
}

const BUILD_INFO: BuildInfo = BuildInfo {
git_hash: env!("GIT_COMMIT"),
version: env!("CARGO_PKG_VERSION"),
dirty: env!("GIT_DIRTY"),
};

// Returns a compiled program which is the ACIR circuit along with the ABI
pub fn add_noir_lib(driver: &mut Driver, crate_name: String) {
let path_to_lib = PathBuf::from(&crate_name).join("lib.nr");
let library_crate = driver.create_non_local_crate(path_to_lib, CrateType::Library);

driver.propagate_dep(library_crate, &CrateName::new(crate_name.as_str()).unwrap());
}

#[wasm_bindgen]
pub fn compile(src: String) -> JsValue {
pub fn compile(args: JsValue) -> JsValue {
console_error_panic_hook::set_once();
let options: WASMCompileOptions = JsValueSerdeExt::into_serde(&args).unwrap();
// For now we default to plonk width = 3, though we can add it as a parameter
let language = acvm::Language::PLONKCSat { width: 3 };
let path = PathBuf::from(src);
let compiled_program = match noirc_driver::Driver::compile_file(path, language) {
Ok(compiled_program) => compiled_program,
Err(_) => panic!("Compilation Error: Failed to compile circuit"),
};
<JsValue as JsValueSerdeExt>::from_serde(&compiled_program).unwrap()
let path = PathBuf::from("main.nr");
let mut driver = noirc_driver::Driver::new(&language);

driver.create_local_crate(path, CrateType::Binary);

for dependency in options.optional_dependencies_set {
add_noir_lib(&mut driver, dependency);
}

driver.check_crate(&options.compile_options).unwrap_or_else(|_| panic!("Crate check failed"));

if options.contracts {
let mut collected_compiled_programs = vec![];

for contract in driver.get_all_contracts() {
contract.functions.into_iter().for_each(|function| {
let name = driver.function_name(function);
let key = format!("{}-{name}", &contract.name);
let compiled_program = driver
.compile_no_check(&options.compile_options, function)
.unwrap_or_else(|_| panic!("Compilation of `{key}` failed"));
collected_compiled_programs.push((key, compiled_program));
});
}

<JsValue as JsValueSerdeExt>::from_serde(&collected_compiled_programs).unwrap()
} else {
let main =
driver.main_function().unwrap_or_else(|_| panic!("Could not find main function!"));
let compiled_program = driver
.compile_no_check(&options.compile_options, main)
.unwrap_or_else(|_| panic!("Compilation failed"));

<JsValue as JsValueSerdeExt>::from_serde(&compiled_program).unwrap()
}
}

// Deserializes bytes into ACIR structure
Expand Down

0 comments on commit 3f897f6

Please sign in to comment.