Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(compile): compile w/dependencies and options #965

Merged
merged 6 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
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")]
kobyhallx marked this conversation as resolved.
Show resolved Hide resolved
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