Skip to content

Commit

Permalink
refactor(compiler): remove constructor handler
Browse files Browse the repository at this point in the history
  • Loading branch information
clearloop committed Sep 14, 2024
1 parent 434bbf4 commit 7262f7b
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 78 deletions.
3 changes: 2 additions & 1 deletion codegen/src/codegen/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ impl Constructor {
///
/// Here we override the memory totally with
/// the runtime bytecode.
pub fn finish(&mut self, init_code: Buffer, runtime_bytecode: Buffer) -> Result<Buffer> {
pub fn finish(&mut self, runtime_bytecode: Buffer) -> Result<Buffer> {
let init_code: Buffer = Default::default();
let init_code_len = init_code.len();
let runtime_bytecode_len = runtime_bytecode.len();
let runtime_bytecode_size = runtime_bytecode_len.to_ls_bytes();
Expand Down
12 changes: 0 additions & 12 deletions codegen/src/wasm/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,6 @@ impl<'f> Functions<'f> {
);
}

/// Remove constructor function
pub fn remove_constructor(&mut self, exports: &Exports) -> Option<Function<'f>> {
tracing::trace!("exports: {:?}", exports);
for (index, export) in exports.iter() {
if export.as_str() == "constructor" {
return self.remove(index);
}
}

None
}

/// Remove all selector functions
pub fn drain_selectors(&mut self, exports: &Exports) -> Self {
let mut functions = Self::default();
Expand Down
13 changes: 11 additions & 2 deletions compiler/src/artifact.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
//! Zink compiler artifact
use crate::Config;
use anyhow::Result;
use zabi::Abi;
use zingen::{Buffer, Constructor};

/// Zink compiler artifact
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Default, Debug)]
pub struct Artifact {
/// Contract ABIs
pub abi: Vec<Abi>,
/// Bytecode of the contract.
pub bytecode: Vec<u8>,
/// Compiler configuration.
pub config: Config,
/// Runtime bytecode of the contract.
pub runtime_bytecode: Vec<u8>,
}

impl Artifact {
/// Generate the creation bytecode just in time
pub fn bytecode(&self) -> Result<Buffer> {
Constructor::default()
.finish(self.runtime_bytecode.clone().into())
.map_err(Into::into)
}
}
2 changes: 1 addition & 1 deletion compiler/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Compile {
let artifact = compiler.compile(&fs::read(&self.input)?)?;

output.parent().map(fs::create_dir_all);
fs::write(&output, artifact.bytecode)?;
fs::write(&output, artifact.runtime_bytecode)?;

if !self.abi {
return Ok(());
Expand Down
39 changes: 4 additions & 35 deletions compiler/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{parser::Parser, Artifact, Config, Error, Result};
use zabi::Abi;
use zingen::{
wasm::{self, Env},
Buffer, Constructor, Dispatcher, Function, JumpTable, BUFFER_LIMIT,
Buffer, Dispatcher, Function, JumpTable, BUFFER_LIMIT,
};

/// Zink Compiler
Expand Down Expand Up @@ -36,7 +36,6 @@ impl Compiler {
let mut parser = Parser::try_from(wasm)?;

let env = parser.to_func_env();
let cst = parser.remove_constructor();
self.compile_dispatcher(&mut parser)?;
for func in parser.funcs.into_funcs() {
self.compile_func(env.clone(), func)?;
Expand All @@ -45,57 +44,27 @@ impl Compiler {
self.table.code_offset(self.buffer.len() as u16);
self.table.relocate(&mut self.buffer)?;

self.artifact(cst)
self.artifact()
}

/// Generate artifact
///
/// yields runtime bytecode and construct bytecode
fn artifact(self, mb_cst: Option<wasm::Function<'_>>) -> Result<Artifact> {
fn artifact(self) -> Result<Artifact> {
let Compiler {
abi,
buffer,
config,
..
} = self;

// NOTE: constructor function could not perform internal calls atm
let runtime_bytecode = buffer.to_vec();
let bytecode = Self::compile_constructor(mb_cst, &runtime_bytecode)?.to_vec();

Ok(Artifact {
abi,
bytecode,
config,
runtime_bytecode,
runtime_bytecode: buffer.to_vec(),
})
}

/// Compile constructor
fn compile_constructor(
mb_cst: Option<wasm::Function<'_>>,
runtime_bytecode: &[u8],
) -> Result<Buffer> {
let mut constructor = Constructor::default();
let Some(mut cst) = mb_cst else {
tracing::debug!("No constructor detected");
return constructor
.finish(Default::default(), runtime_bytecode.into())
.map_err(Into::into);
};

let mut locals_reader = cst.body.get_locals_reader()?;
let mut ops_reader = cst.body.get_operators_reader()?;

let mut codegen = Function::new(Default::default(), cst.sig()?, true)?;
codegen.emit_locals(&mut locals_reader, &mut cst.validator)?;
codegen.emit_operators(&mut ops_reader, &mut cst.validator)?;

constructor
.finish(codegen.masm.buffer().into(), runtime_bytecode.into())
.map_err(Into::into)
}

/// Compile EVM dispatcher.
///
/// Drain selectors anyway, if dispatcher is
Expand Down
7 changes: 1 addition & 6 deletions compiler/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use wasmparser::{
Data, DataKind, Export, ExternalKind, Import, Operator, Payload, SectionLimited, TypeRef,
ValidPayload, Validator,
};
use zingen::wasm::{Data as DataSet, Env, Exports, Function, Functions, HostFunc, Imports};
use zingen::wasm::{Data as DataSet, Env, Exports, Functions, HostFunc, Imports};

/// WASM module parser
#[derive(Default)]
Expand Down Expand Up @@ -104,11 +104,6 @@ impl<'p> Parser<'p> {
Ok(imports)
}

/// Returns constructor if some.
pub fn remove_constructor(&mut self) -> Option<Function<'p>> {
self.funcs.remove_constructor(&self.exports)
}

/// Returns full environment.
pub fn to_env(&self) -> Env {
Env {
Expand Down
2 changes: 1 addition & 1 deletion elko/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Build {
let artifact = Compiler::new(config).compile(&wasm)?;
let dst = builder.output()?.with_extension("bin");

fs::write(dst, artifact.bytecode)?;
fs::write(dst, artifact.runtime_bytecode)?;
Ok(())
}
}
32 changes: 16 additions & 16 deletions examples/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@ pub fn constructor(num: i32) {
#[cfg(not(target_arch = "wasm32"))]
fn main() {}

#[ignore]
#[test]
fn deploy() -> anyhow::Result<()> {
use zint::{Bytes32, Contract, EVM};

let contract = Contract::search("constructor")?.compile()?;

let mut evm = EVM::default();
let mut info = evm.deploy(contract.bytecode())?;
info = evm
.calldata(&contract.encode(&["get()"])?)
.call(info.address)?;

assert_eq!(info.ret, 1.to_bytes32());
Ok(())
}
// #[ignore]
// #[test]
// fn deploy() -> anyhow::Result<()> {
// use zint::{Bytes32, Contract, EVM};
//
// let contract = Contract::search("constructor")?.compile()?;
//
// let mut evm = EVM::default();
// let mut info = evm.deploy(contract.bytecode())?;
// info = evm
// .calldata(&contract.encode(&["get()"])?)
// .call(info.address)?;
//
// assert_eq!(info.ret, 1.to_bytes32());
// Ok(())
// }
2 changes: 1 addition & 1 deletion examples/empty_constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn deploy() -> anyhow::Result<()> {
let contract = Contract::search("empty_constructor")?.compile()?;

let mut evm = EVM::default();
let mut info = evm.deploy(&contract.bytecode())?;
let mut info = evm.deploy(&contract.bytecode()?)?;
info = evm
.calldata(&contract.encode(&["get()"])?)
.call(info.address)?;
Expand Down
9 changes: 6 additions & 3 deletions zint/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@ where

impl Contract {
/// Get the bytecode of the contract.
pub fn bytecode(&self) -> &[u8] {
&self.artifact.bytecode
pub fn bytecode(&self) -> Result<Vec<u8>> {
self.artifact
.bytecode()
.map(|v| v.to_vec())
.map_err(Into::into)
}

/// Compile WASM to EVM bytecode.
Expand All @@ -44,7 +47,7 @@ impl Contract {
self.artifact = compiler.compile(&self.wasm)?;

tracing::debug!("abi: {:#}", self.json_abi()?);
tracing::debug!("bytecode: {:?}", hex::encode(&self.artifact.bytecode));
// tracing::debug!("bytecode: {:?}", hex::encode(&self.artifact.bytecode));
Ok(self)
}

Expand Down

0 comments on commit 7262f7b

Please sign in to comment.