Skip to content

Commit

Permalink
rust: introduce evmc-loader wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
axic committed Jun 1, 2022
1 parent 2e25a9a commit 69c9a14
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .bumpversion.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ replace = version = "{new_version}"
search = version = "{current_version}"
replace = version = "{new_version}"

[bumpversion:file:bindings/rust/evmc-loader/Cargo.toml]
search = version = "{current_version}"
replace = version = "{new_version}"

[bumpversion:file:examples/example-rust-vm/Cargo.toml]
search = version = "{current_version}"
replace = version = "{new_version}"
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ members = [
"bindings/rust/evmc-vm",
"bindings/rust/evmc-declare",
"bindings/rust/evmc-declare-tests",
"bindings/rust/evmc-loader",
"examples/example-rust-vm"
]
3 changes: 3 additions & 0 deletions bindings/rust/evmc-loader/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
**/*.rs.bk
/Cargo.lock
16 changes: 16 additions & 0 deletions bindings/rust/evmc-loader/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# EVMC: Ethereum Client-VM Connector API.
# Copyright 2022 The EVMC Authors.
# Licensed under the Apache License, Version 2.0.

[package]
name = "evmc-loader"
version = "10.0.0-alpha.5"
authors = ["Alex Beregszaszi <[email protected]>"]
license = "Apache-2.0"
repository = "https://github.com/ethereum/evmc"
description = "Bindings to EVMC (Loader bindings)"
edition = "2018"

[build-dependencies]
bindgen = "0.59"
cmake = "0.1"
5 changes: 5 additions & 0 deletions bindings/rust/evmc-loader/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# evmc-loader

This is a Rust interface to [EVMC](https://github.com/ethereum/evmc).

This crate contains a wrapper for the loader functionality.
40 changes: 40 additions & 0 deletions bindings/rust/evmc-loader/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2022 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

extern crate bindgen;
extern crate cmake;

use cmake::Config;
use std::env;
use std::path::PathBuf;

fn main() {
let dst = Config::new("../../../").build();

println!("cargo:rustc-link-lib=static=evmc-loader");
println!(
"cargo:rustc-link-search=native={}/build/lib/loader",
dst.display()
);

let bindings = bindgen::Builder::default()
.header("loader.h")
.generate_comments(false)
// do not generate an empty enum for EVMC_ABI_VERSION
.constified_enum("")
// generate Rust enums for each evmc enum
.rustified_enum("*")
.allowlist_type("evmc_.*")
.allowlist_function("evmc_.*")
.blocklist_type("evmc_vm")
// TODO: consider removing this
.size_t_is_usize(true)
.generate()
.expect("Unable to generate bindings");

let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Could not write bindings");
}
1 change: 1 addition & 0 deletions bindings/rust/evmc-loader/loader.h
37 changes: 37 additions & 0 deletions bindings/rust/evmc-loader/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2022 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

use std::ffi::{CStr, CString};

mod sys;

pub fn load_and_configure(
config: &str,
) -> Result<*mut sys::evmc_vm, (sys::evmc_loader_error_code, String)> {
let config_cstr = CString::new(config).unwrap();
let mut error_code = sys::evmc_loader_error_code::EVMC_LOADER_UNSPECIFIED_ERROR;
let instance = unsafe { sys::evmc_load_and_configure(config_cstr.as_ptr(), &mut error_code) };

if error_code == sys::evmc_loader_error_code::EVMC_LOADER_SUCCESS {
assert!(!instance.is_null());
Ok(instance)
} else {
assert!(instance.is_null());
let error_msg = unsafe { CStr::from_ptr(sys::evmc_last_error_msg()) }
.to_str()
.expect("well formed error message") // TODO free the vm
.to_string();
Err((error_code, error_msg))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn load_fail() {
println!("{:?}", load_and_configure("test.so"));
}
}
31 changes: 31 additions & 0 deletions bindings/rust/evmc-loader/src/sys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// EVMC: Ethereum Client-VM Connector API.
// Copyright 2022 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

// Defining evmc_vm here, because bindgen cannot create a useful declaration yet.

pub type evmc_vm = ::std::os::raw::c_void;

#[cfg(test)]
mod tests {
use std::ffi::CString;
use std::os::raw::c_char;

use super::*;

#[test]
fn load_fail() {
let c_str = CString::new("test.so").unwrap();
unsafe {
let mut error_code = evmc_loader_error_code::EVMC_LOADER_UNSPECIFIED_ERROR;
let instance = evmc_load_and_create(c_str.as_ptr() as *const c_char, &mut error_code);
println!("{:?} {:?}", error_code, instance);
}
}
}

0 comments on commit 69c9a14

Please sign in to comment.