Skip to content
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"crates/vm",
"aTester",
]
resolver = "3"

[profile.release]
panic = "abort"
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ KERNEL_OUT_DIR := crates/bootloader/bin
KERNEL_BINS := $(shell awk '/\[\[bin\]\]/{inbin=1;next} inbin && /name =/{gsub(/"/,"",$$3); print $$3; inbin=0}' $(KERNEL_MANIFEST))
KERNEL_TEST_BINS := $(filter-out kernel,$(KERNEL_BINS))

all: clean examples test utils summary
all: clean examples test atests utils summary

.PHONY: run_examples
.PHONY: kernel
.PHONY: atests

kernel:
@echo "=== Building kernel ELF ==="
Expand Down Expand Up @@ -48,6 +49,9 @@ test: generate_abis
cd crates/examples && cargo test -- --nocapture
@echo "=== Tests complete ==="

atests:
cargo test -p a_tests -- --nocapture

generate_abis:
@echo "=== Generating ABIs ==="
cd crates/examples && $(MAKE) abi
Expand Down
23 changes: 13 additions & 10 deletions aTester/tests/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,19 @@ fn examples_tests() {
let cases = all_example_cases()
.expect("failed to build example bundles")
.into_iter()
.map(|case| TestCase {
name: case.name.to_string(),
kind: TestKind::Smoke,
elf: target_dir.join("kernel.elf"),
options: RunOptions {
timeout_ms: None,
vm_memory_size: None,
verbose: false,
input: vec![case.bundle.encode(), state_bytes.clone()],
},
.map(|case| {
println!("Running example: {} - {}", case.name, case.description);
TestCase {
name: case.name.to_string(),
kind: TestKind::Smoke,
elf: target_dir.join("kernel.elf"),
options: RunOptions {
timeout_ms: None,
vm_memory_size: None,
verbose: false,
input: vec![case.bundle.encode(), state_bytes.clone()],
},
}
})
.collect::<Vec<_>>();

Expand Down
5 changes: 0 additions & 5 deletions crates/clibc/src/allocator.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
extern crate alloc;
use alloc::alloc::{GlobalAlloc, Layout};

// System call numbers for memory allocation
const SYSCALL_ALLOC: u32 = 7;
const SYSCALL_DEALLOC: u32 = 8;

/// VM Global Allocator
///
/// This allocator uses system calls to request memory from the VM host.
Expand Down Expand Up @@ -73,4 +69,3 @@ unsafe fn syscall_dealloc(ptr: *mut u8, size: usize) {
alloc::alloc::dealloc(ptr, layout);
}
}

1 change: 0 additions & 1 deletion crates/clibc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ pub use storage_map::StorageKey;

// Events
pub mod event;
pub use event::*;

// Logging macros
pub mod log;
Expand Down
3 changes: 1 addition & 2 deletions crates/clibc/src/router.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use types::result::Result;
use types::address::Address;
use types::{O};
use crate::logf;

/// Represents a function call with a selector (function ID) and arguments.
/// This is the core data structure for routing function calls in our VM.
Expand Down Expand Up @@ -204,4 +203,4 @@ pub fn route<'a>(
}

last_result
}
}
72 changes: 0 additions & 72 deletions crates/compiler/src/abi_codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,78 +255,6 @@ impl AbiCodeGenerator {
}
}

/// Generate code to encode an argument
fn generate_argument_encoding(&self, name: &str, param_type: &ParamType) -> String {
match param_type {
ParamType::Address => {
format!(" args.extend({}.0.to_vec());\n", name)
}
ParamType::Uint(8) => {
format!(" args.push({});\n", name)
}
ParamType::Uint(16) => {
format!(" args.extend({}.to_le_bytes());\n", name)
}
ParamType::Uint(32) => {
format!(" args.extend({}.to_le_bytes());\n", name)
}
ParamType::Uint(64) => {
format!(" args.extend({}.to_le_bytes());\n", name)
}
ParamType::Uint(128) => {
format!(" args.extend({}.to_le_bytes());\n", name)
}
ParamType::Bool => {
format!(" args.push(if {} {{ 1 }} else {{ 0 }});\n", name)
}
ParamType::String => {
format!(" args.extend({}.as_bytes());\n", name)
}
ParamType::Bytes => {
format!(" args.extend({});\n", name)
}
_ => {
format!(" // TODO: Encode {}\n", name)
}
}
}

/// Generate code to encode an argument for direct calls
fn generate_argument_encoding_direct(&self, name: &str, param_type: &ParamType) -> String {
match param_type {
ParamType::Address => {
format!(" data.extend({}.0.to_vec());\n", name)
}
ParamType::Uint(8) => {
format!(" data.push({});\n", name)
}
ParamType::Uint(16) => {
format!(" data.extend({}.to_le_bytes());\n", name)
}
ParamType::Uint(32) => {
format!(" data.extend({}.to_le_bytes());\n", name)
}
ParamType::Uint(64) => {
format!(" data.extend({}.to_le_bytes());\n", name)
}
ParamType::Uint(128) => {
format!(" data.extend({}.to_le_bytes());\n", name)
}
ParamType::Bool => {
format!(" data.push(if {} {{ 1 }} else {{ 0 }});\n", name)
}
ParamType::String => {
format!(" data.extend({}.as_bytes());\n", name)
}
ParamType::Bytes => {
format!(" data.extend({});\n", name)
}
_ => {
format!(" // TODO: Encode {}\n", name)
}
}
}

/// Generate Rust client code from an ABI file
pub fn from_abi_file<P: AsRef<Path>>(abi_path: P, contract_name: String) -> std::io::Result<String> {
let abi_json = fs::read_to_string(abi_path)?;
Expand Down
52 changes: 4 additions & 48 deletions crates/compiler/src/abi_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,56 +241,12 @@ impl AbiGenerator {
functions
}

/// Parse a selector pattern like "0x01 => function_name(call.args)" or "0x01 => { function_name(caller, call.args); }"
fn parse_selector_pattern<'a>(&self, line: &'a str) -> Option<(u8, &'a str)> {
let parts: Vec<&str> = line.split("=>").collect();
if parts.len() != 2 {
return None;
}

let selector_str = parts[0].trim();
let function_part = parts[1].trim();

// Extract selector
if !selector_str.starts_with("0x") {
return None;
}

let selector = u8::from_str_radix(&selector_str[2..], 16).ok()?;

// Extract function name - handle both patterns:
// 1. "function_name(call.args)"
// 2. "{ function_name(caller, call.args); }"
let function_name = if function_part.starts_with('{') {
// Pattern 2: extract from inside braces
let inner = function_part.trim_start_matches('{').trim_end_matches('}');
// Look for function call pattern: function_name(...)
if let Some(start) = inner.find('(') {
inner[..start].trim()
} else {
return None;
}
} else {
// Pattern 1: extract directly
if let Some(start) = function_part.find('(') {
function_part[..start].trim()
} else {
return None;
}
};

// Skip empty function names
if function_name.is_empty() {
return None;
}

Some((selector, function_name))
}

/// Find function definition and create FunctionAbi
fn find_function_definition(&self, lines: &[&str], start_line: usize, function_name: &str) -> Option<FunctionAbi> {
// Look for function definition pattern: fn function_name(...)
for i in 0..lines.len() {
let forward = start_line..lines.len();
let backward = 0..start_line;
for i in forward.chain(backward) {
let trimmed = lines[i].trim();
if trimmed.starts_with("fn ") && trimmed.contains(function_name) {
// Extract function signature
Expand All @@ -299,7 +255,7 @@ impl AbiGenerator {
}
}
}

None
}

Expand Down
8 changes: 4 additions & 4 deletions crates/compiler/src/bin/avm32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn main() {
}
}

fn cmd_build(mut args: Vec<String>, paths: &Paths) -> Result<(), String> {
fn cmd_build(args: Vec<String>, paths: &Paths) -> Result<(), String> {
let mut bin: Option<String> = None;
let mut features: Option<String> = None;
let mut release = true;
Expand Down Expand Up @@ -211,7 +211,7 @@ fn cmd_build(mut args: Vec<String>, paths: &Paths) -> Result<(), String> {
Ok(())
}

fn cmd_abi(mut args: Vec<String>, paths: &Paths) -> Result<(), String> {
fn cmd_abi(args: Vec<String>, paths: &Paths) -> Result<(), String> {
let mut bin: Option<String> = None;
let mut src: Option<PathBuf> = None;
let mut out: Option<PathBuf> = None;
Expand Down Expand Up @@ -284,7 +284,7 @@ fn cmd_abi(mut args: Vec<String>, paths: &Paths) -> Result<(), String> {
Ok(())
}

fn cmd_client(mut args: Vec<String>, _paths: &Paths) -> Result<(), String> {
fn cmd_client(args: Vec<String>, _paths: &Paths) -> Result<(), String> {
let mut abi_path: Option<PathBuf> = None;
let mut out: Option<PathBuf> = None;
let mut contract: Option<String> = None;
Expand Down Expand Up @@ -342,7 +342,7 @@ fn cmd_client(mut args: Vec<String>, _paths: &Paths) -> Result<(), String> {
Ok(())
}

fn cmd_all(mut args: Vec<String>, paths: &Paths) -> Result<(), String> {
fn cmd_all(args: Vec<String>, paths: &Paths) -> Result<(), String> {
let mut bin: Option<String> = None;
let mut out_dir: Option<PathBuf> = None;
let mut cargo_cmd: Option<String> = None;
Expand Down
6 changes: 0 additions & 6 deletions crates/examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ k256 = { version = "0.13", default-features = false, features = ["arithmetic", "
default = []
binaries = [] # Enable this feature to build RISC-V binaries

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

# Note: These binaries are designed for RISC-V target and will cause linking errors
# when building for host architecture during tests. Use --features binaries to build them.
[[bin]]
Expand Down
2 changes: 1 addition & 1 deletion crates/examples/src/allocator_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use clibc::{
DataParser, entrypoint, require, types::address::Address, types::result::Result, vm_panic,
};

/// Guest program that demonstrates heap allocation using VM syscalls
entrypoint!(main);
/// Guest program that demonstrates heap allocation using VM syscalls
fn main(program: Address, _caller: Address, data: &[u8]) -> Result {
let _ = program;
// Need to import alloc types after entrypoint macro includes the allocator
Expand Down
6 changes: 3 additions & 3 deletions crates/examples/src/erc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

extern crate clibc;
use clibc::{
DataParser, Map, StorageKey, entrypoint, event, fire_event, log, logf, persist_struct,
DataParser, Map, StorageKey, entrypoint, event, fire_event, logf, persist_struct,
require, router::route, types::{address::Address, o::O, result::Result}, vm_panic,
};

Expand Down Expand Up @@ -47,7 +47,7 @@ impl StorageKey for AllowanceKey {
}

unsafe fn main_entry(program: Address, caller: Address, data: &[u8]) -> Result {
route(data, program, caller, |to, from, call| {
route(data, program, caller, |_to, _from, call| {
match call.selector {
0x01 => {
init(&program, caller, call.args);
Expand Down Expand Up @@ -89,7 +89,7 @@ unsafe fn main_entry(program: Address, caller: Address, data: &[u8]) -> Result {
fn init(program: &Address, caller: Address, args: &[u8]) {
logf!("init called");
let mut meta = match Metadata::load(program) {
O::Some(m) => vm_panic(b"already initialized"),
O::Some(_) => vm_panic(b"already initialized"),
O::None => Metadata {
total_supply: 0,
decimals: 0,
Expand Down
2 changes: 1 addition & 1 deletion crates/examples/src/multi_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use clibc::{DataParser, entrypoint, require, types::result::Result, vm_panic};
fn my_vm_entry(program: Address, _caller: Address, data: &[u8]) -> Result {
// EDUCATIONAL: Use the router to handle multiple function calls
// The router decodes the input data and calls the appropriate function
route(data, program, _caller, |to, from, call| {
route(data, program, _caller, |_to, _from, call| {
match call.selector {
0x01 => compare(call.args), // Function selector 0x01 = compare function
0x02 => other(call.args), // Function selector 0x02 = other function
Expand Down
11 changes: 7 additions & 4 deletions crates/examples/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ fn my_vm_entry(program: Address, _caller: Address, _data: &[u8]) -> Result {
// ... change local copy ...
user.level = 5;
user.id = 40001;

// ... later ...
require(user.level == 5, b"user local level must be 5");
require(user.id == 40001, b"user local id must be 40001");

let reloaded_user = User::load(&program).expect("user not found");
require(reloaded_user.level == 4, b"user level must be 4");
Expand All @@ -60,8 +60,11 @@ fn my_vm_entry(program: Address, _caller: Address, _data: &[u8]) -> Result {
// ... change local copy ...
config.retries = 15;
config.timeout_ms = 103000;

// ... later ...
require(config.retries == 15, b"config local retries must be 15");
require(
config.timeout_ms == 103000,
b"config local timeout_ms must be 103000",
);

let reloaded_config = Config::load(&program).expect("config not found");
require(reloaded_config.retries == 13, b"config retries must be 13");
Expand Down
1 change: 0 additions & 1 deletion crates/kernel/src/bundle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ fn execute_transaction(tx: &Transaction) -> bool {
transfer(tx);
true
}
_ => panic!("unsupported transaction type"),
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/kernel/src/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ pub static ROOT_PPN: Global<u32> = Global::new(0);
/// Page allocator backing store.
pub static PAGE_ALLOC: Global<Option<PageAllocator>> = Global::new(None);
/// Kernel heap allocator instance.
pub static KERNEL_HEAP: Global<BumpAllocator> = Global::new(BumpAllocator::empty());
pub(crate) static KERNEL_HEAP: Global<BumpAllocator> = Global::new(BumpAllocator::empty());

const fn align_up(val: usize, align: usize) -> usize {
(val + (align - 1)) & !(align - 1)
Expand Down
Loading
Loading