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

POC: Shrinking generated binary #223

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
139 changes: 139 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions clar2wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ lazy_static = "1.4.0"
sha2 = { version = "0.10.7", optional = true }
chrono = { version = "0.4.20", optional = true }
rusqlite = { version = "0.28.0", optional = true }
wasm-opt = "0.116.0"
tempfile = "3.8.1"

[build-dependencies]
wat = "1.0.74"
Expand Down
6 changes: 2 additions & 4 deletions clar2wasm/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn main() {
let cost_track = LimitedCostTracker::new_free();

// Pass the source code to the compiler.
let result = clar2wasm::compile(
let mut result = clar2wasm::compile(
&source,
&contract_id,
cost_track,
Expand All @@ -68,8 +68,6 @@ fn main() {
}
});

let mut module = result.module;

// Write the compiled WebAssembly to a file.
let output = args.output.unwrap_or_else(|| {
// Use the input file name with a .wasm extension
Expand All @@ -80,7 +78,7 @@ fn main() {
output
});

if let Err(error) = module.emit_wasm_file(output.as_str()) {
if let Err(error) = result.to_wasm_file(output.as_str()) {
eprintln!("Error writing Wasm file, {}: {}", output, error);
std::process::exit(1);
}
Expand Down
28 changes: 28 additions & 0 deletions clar2wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
extern crate lazy_static;

use std::path::Path;

use clarity::types::StacksEpochId;
use clarity::vm::analysis::{run_analysis, AnalysisDatabase, ContractAnalysis};
use clarity::vm::ast::{build_ast_with_diagnostics, ContractAST};
Expand All @@ -9,6 +11,7 @@ use clarity::vm::types::QualifiedContractIdentifier;
use clarity::vm::ClarityVersion;
pub use walrus::Module;
use wasm_generator::{GeneratorError, WasmGenerator};
use wasm_opt::{Feature, OptimizationOptions, Pass};

mod deserialize;
mod serialize;
Expand Down Expand Up @@ -38,6 +41,31 @@ pub struct CompileResult {
pub contract_analysis: ContractAnalysis,
}

impl CompileResult {
pub fn to_wasm(&mut self) -> Vec<u8> {
if let Ok(tmpfile) = tempfile::NamedTempFile::new() {
self.module
.emit_wasm_file(tmpfile.path())
.expect("Error in writing temporary wasm file");
OptimizationOptions::new_opt_level_4()
.enable_feature(Feature::Multivalue)
.enable_feature(Feature::Simd)
.enable_feature(Feature::BulkMemory)
.add_pass(Pass::RemoveUnusedModuleElements)
.run(tmpfile.path(), tmpfile.path())
.expect("error while optimizing");
std::fs::read(tmpfile.path()).expect("error reading resulting optimized wasm")
} else {
eprintln!("Could not optimize wasm");
self.module.emit_wasm()
}
}

pub fn to_wasm_file(&mut self, path: impl AsRef<Path>) -> std::io::Result<()> {
std::fs::write(path, self.to_wasm())
}
}

#[derive(Debug)]
pub enum CompileError {
Generic {
Expand Down
74 changes: 0 additions & 74 deletions clar2wasm/src/standard/standard.wat
Original file line number Diff line number Diff line change
Expand Up @@ -3278,78 +3278,4 @@
;; FIXME: Implement this function
(i32.const 0)
)

(export "stdlib.add-uint" (func $stdlib.add-uint))
(export "stdlib.add-int" (func $stdlib.add-int))
(export "stdlib.sub-uint" (func $stdlib.sub-uint))
(export "stdlib.sub-int" (func $stdlib.sub-int))
(export "stdlib.mul-uint" (func $stdlib.mul-uint))
(export "stdlib.mul-int" (func $stdlib.mul-int))
(export "stdlib.div-uint" (func $stdlib.div-uint))
(export "stdlib.div-int" (func $stdlib.div-int))
(export "stdlib.mod-uint" (func $stdlib.mod-uint))
(export "stdlib.mod-int" (func $stdlib.mod-int))
(export "stdlib.lt-uint" (func $stdlib.lt-uint))
(export "stdlib.gt-uint" (func $stdlib.gt-uint))
(export "stdlib.le-uint" (func $stdlib.le-uint))
(export "stdlib.ge-uint" (func $stdlib.ge-uint))
(export "stdlib.lt-int" (func $stdlib.lt-int))
(export "stdlib.gt-int" (func $stdlib.gt-int))
(export "stdlib.le-int" (func $stdlib.le-int))
(export "stdlib.ge-int" (func $stdlib.ge-int))
(export "stdlib.lt-buff" (func $stdlib.lt-buff))
(export "stdlib.gt-buff" (func $stdlib.gt-buff))
(export "stdlib.le-buff" (func $stdlib.le-buff))
(export "stdlib.ge-buff" (func $stdlib.ge-buff))
(export "stdlib.log2-uint" (func $stdlib.log2-uint))
(export "stdlib.log2-int" (func $stdlib.log2-int))
(export "stdlib.sqrti-uint" (func $stdlib.sqrti-uint))
(export "stdlib.sqrti-int" (func $stdlib.sqrti-int))
(export "stdlib.bit-and-uint" (func $stdlib.bit-and))
(export "stdlib.bit-and-int" (func $stdlib.bit-and))
(export "stdlib.bit-not-uint" (func $stdlib.bit-not))
(export "stdlib.bit-not-int" (func $stdlib.bit-not))
(export "stdlib.bit-or-uint" (func $stdlib.bit-or))
(export "stdlib.bit-or-int" (func $stdlib.bit-or))
(export "stdlib.bit-xor-uint" (func $stdlib.bit-xor))
(export "stdlib.bit-xor-int" (func $stdlib.bit-xor))
(export "stdlib.bit-shift-left-uint" (func $stdlib.bit-shift-left))
(export "stdlib.bit-shift-left-int" (func $stdlib.bit-shift-left))
(export "stdlib.bit-shift-right-uint" (func $stdlib.bit-shift-right-uint))
(export "stdlib.bit-shift-right-int" (func $stdlib.bit-shift-right-int))
(export "stdlib.pow-uint" (func $stdlib.pow-uint))
(export "stdlib.pow-int" (func $stdlib.pow-int))
(export "stdlib.sha256-buf" (func $stdlib.sha256-buf))
(export "stdlib.sha256-int" (func $stdlib.sha256-int))
(export "stdlib.hash160-buf" (func $stdlib.hash160-buf))
(export "stdlib.hash160-int" (func $stdlib.hash160-int))
(export "stdlib.store-i32-be" (func $stdlib.store-i32-be))
(export "stdlib.store-i64-be" (func $stdlib.store-i64-be))
(export "stdlib.load-i32-be" (func $stdlib.load-i32-be))
(export "stdlib.buff-to-uint-be" (func $stdlib.buff-to-uint-be))
(export "stdlib.buff-to-uint-le" (func $stdlib.buff-to-uint-le))
(export "stdlib.not" (func $stdlib.not))
(export "stdlib.is-eq-int" (func $stdlib.is-eq-int))
(export "stdlib.is-eq-bytes" (func $stdlib.is-eq-bytes))
(export "stdlib.principal-construct" (func $stdlib.principal-construct))
(export "stdlib.is-valid-contract-name" (func $stdlib.is-valid-contract-name))
(export "stdlib.is-alpha" (func $stdlib.is-alpha))
(export "stdlib.is-valid-char" (func $stdlib.is-valid-char))
(export "stdlib.is-transient" (func $stdlib.is-transient))
(export "stdlib.is-version-valid" (func $stdlib.is-version-valid))
(export "stdlib.string-to-int" (func $stdlib.string-to-int))
(export "stdlib.string-to-uint" (func $stdlib.string-to-uint))
(export "stdlib.utf8-to-uint" (func $stdlib.utf8-to-uint))
(export "stdlib.utf8-to-int" (func $stdlib.utf8-to-int))
(export "stdlib.uint-to-string" (func $stdlib.uint-to-string))
(export "stdlib.uint-to-utf8" (func $stdlib.uint-to-utf8))
(export "stdlib.int-to-string" (func $stdlib.int-to-string))
(export "stdlib.int-to-utf8" (func $stdlib.int-to-utf8))
(export "stdlib.to-uint" (func $stdlib.to-uint))
(export "stdlib.to-int" (func $stdlib.to-int))
(export "stdlib.sha512-buf" (func $stdlib.sha512-buf))
(export "stdlib.sha512-int" (func $stdlib.sha512-int))
(export "stdlib.convert-scalars-to-utf8" (func $stdlib.convert-scalars-to-utf8))
(export "stdlib.convert-utf8-to-scalars" (func $stdlib.convert-utf8-to-scalars))
(export "stdlib.is-valid-string-ascii" (func $stdlib.is-valid-string-ascii))
)
2 changes: 1 addition & 1 deletion clar2wasm/src/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl TestEnvironment {

let mut contract_context = ContractContext::new(contract_id.clone(), self.version);
// compile_result.module.emit_wasm_file("test.wasm").unwrap();
contract_context.set_wasm_module(compile_result.module.emit_wasm());
contract_context.set_wasm_module(compile_result.to_wasm());

let mut cost_tracker = LimitedCostTracker::new_free();
std::mem::swap(&mut self.cost_tracker, &mut cost_tracker);
Expand Down
Loading
Loading