make it compile

This commit is contained in:
Steve Biedermann 2024-12-05 11:42:36 +01:00
parent d5f621e44a
commit cbeeb0e60d
9 changed files with 315 additions and 136 deletions

135
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "addr2line" name = "addr2line"
@ -54,10 +54,59 @@ dependencies = [
] ]
[[package]] [[package]]
name = "anyhow" name = "anstream"
version = "1.0.93" version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
[[package]] [[package]]
name = "arbitrary" name = "arbitrary"
@ -233,12 +282,66 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69371e34337c4c984bbe322360c2547210bf632eb2814bbe78a6e87a2935bd2b"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e24c1b4099818523236a8ca881d2b45db98dadfb4625cf6608c12069fcbbde1"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
[[package]] [[package]]
name = "cobs" name = "cobs"
version = "0.2.3" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "common"
version = "0.1.0"
dependencies = [
"extism-pdk",
"serde",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.7" version = "0.8.7"
@ -761,7 +864,11 @@ dependencies = [
name = "hecate" name = "hecate"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow",
"clap",
"common",
"extism", "extism",
"serde",
"wasm-bindgen", "wasm-bindgen",
] ]
@ -978,6 +1085,12 @@ version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.12.1" version = "0.12.1"
@ -1492,8 +1605,8 @@ dependencies = [
name = "rust-pdk-template" name = "rust-pdk-template"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"common",
"extism-pdk", "extism-pdk",
"hecate",
"serde", "serde",
] ]
@ -1680,6 +1793,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.6.1" version = "2.6.1"
@ -1957,6 +2076,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.11.0" version = "1.11.0"

View File

@ -4,8 +4,12 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.94"
clap = { version = "4.5.22", features = ["derive"] }
common = { version = "0.1.0", path = "common" }
extism = "1.9.1" extism = "1.9.1"
serde = { version = "1.0.215", features = ["derive"] }
wasm-bindgen = "0.2.97" wasm-bindgen = "0.2.97"
[workspace] [workspace]
members = ["std_cpu"] members = ["common", "std_cpu"]

8
common/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "common"
version = "0.1.0"
edition = "2021"
[dependencies]
extism-pdk = "1.3.0"
serde = { version = "1.0.215", features = ["derive"] }

62
common/src/lib.rs Normal file
View File

@ -0,0 +1,62 @@
use extism_pdk::*;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, ToBytes, FromBytes)]
#[encoding(Json)]
pub struct Init {
pub verbose: bool,
pub mem_size: usize,
pub registers: usize,
}
#[derive(Serialize, Deserialize, ToBytes, FromBytes)]
#[encoding(Json)]
pub struct SetVerbose(pub bool);
#[derive(Serialize, Deserialize, ToBytes, FromBytes)]
#[encoding(Json)]
pub struct SetMemory {
pub offset: usize,
pub memory: Vec<u8>,
}
#[derive(Serialize, Deserialize, ToBytes, FromBytes)]
#[encoding(Json)]
pub enum RunResult {
Success,
}
pub trait CpuTrait {
fn new() -> Self
where
Self: Sized;
fn set_verbose(&mut self, verbose: bool);
fn load_memory(&mut self, memory: &[u8]);
fn execute(&mut self, run_mode: RunMode);
fn get_registers(&self) -> &[u16];
fn get_memory(&self) -> &[u8];
}
#[derive(Serialize, Deserialize, ToBytes, FromBytes)]
#[encoding(Json)]
pub enum RunMode {
Run, // Run to completion
Debug(DebugMode), // Debug mode
StepOver, // Step over calls
StepInto, // Step into calls
StepOut, // Step out of calls
RunFor(usize), // Run for a specific number of cycles
}
#[derive(Serialize, Deserialize, ToBytes, FromBytes)]
#[encoding(Json)]
pub enum DebugMode {
All, // Break on any breakpoint
Code, // Break on code breakpoints
Data, // Break on data breakpoints
}

View File

@ -1,30 +0,0 @@
pub trait CpuTrait {
fn new() -> Self
where
Self: Sized;
fn set_verbose(&mut self, verbose: bool);
fn load_memory(&mut self, memory: &[u8]);
fn execute(&mut self, run_mode: RunMode);
fn get_registers(&self) -> &[u16];
fn get_memory(&self) -> &[u8];
}
pub enum RunMode {
Run, // Run to completion
Debug(DebugMode), // Debug mode
StepOver, // Step over calls
StepInto, // Step into calls
StepOut, // Step out of calls
RunFor(usize), // Run for a specific number of cycles
}
pub enum DebugMode {
All, // Break on any breakpoint
Code, // Break on code breakpoints
Data, // Break on data breakpoints
}

View File

@ -1,70 +1,41 @@
mod cpu_trait; use common::{RunMode, RunResult, SetVerbose};
use extism::*;
pub use cpu_trait::{CpuTrait, DebugMode, RunMode}; pub struct WasmCpu {
plugin: Plugin,
#[wasm_bindgen]
impl WasmCpu {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
WasmCpu {
memory: [0; 64 * 1024],
registers: [0; 8],
ip: 0,
sp: 0xFFFF,
flags: 0,
verbose: false,
} }
impl WasmCpu {
pub fn new(manifest: Manifest) -> anyhow::Result<Self> {
let plugin = PluginBuilder::new(manifest).build()?;
Ok(WasmCpu { plugin })
}
pub fn from_path<P: AsRef<std::path::Path>>(path: P) -> anyhow::Result<Self> {
let manifest = Manifest::new([Wasm::file(path)]);
Self::new(manifest)
}
pub fn from_url(url: &str) -> anyhow::Result<Self> {
let manifest = Manifest::new([Wasm::url(url)]);
Self::new(manifest)
} }
pub fn set_verbose(&mut self, verbose: bool) { pub fn set_verbose(&mut self, verbose: bool) {
self.verbose = verbose; self.plugin
.call::<SetVerbose, ()>("set_verbose", SetVerbose(verbose))
.unwrap()
} }
pub fn load_memory(&mut self, memory: &[u8]) { pub fn load_memory(&mut self, memory: &[u8]) {
self.memory[..memory.len()].copy_from_slice(memory); self.plugin
.call::<&[u8], ()>("load_memory", memory)
.unwrap()
} }
pub fn execute(&mut self, run_mode: RunMode) { pub fn execute(&mut self, run_mode: RunMode) -> RunResult {
match run_mode { self.plugin
RunMode::Run => self.run(), .call::<RunMode, RunResult>("execute", run_mode)
RunMode::Debug(debug_mode) => self.debug(debug_mode), .unwrap()
RunMode::StepOver => self.step_over(),
RunMode::StepInto => self.step_into(),
RunMode::StepOut => self.step_out(),
RunMode::RunFor(cycles) => self.run_for(cycles),
}
}
fn run(&mut self) {
while self.ip < self.memory.len() as u16 {
self.step();
}
}
fn debug(&mut self, _debug_mode: DebugMode) {
// Implement debug functionality
}
fn run_for(&mut self, cycles: usize) {
for _ in 0..cycles {
self.step();
}
}
fn step_over(&mut self) {
self.step(); // Placeholder for step-over functionality
}
fn step_into(&mut self) {
self.step(); // Placeholder for step-into functionality
}
fn step_out(&mut self) {
self.step(); // Placeholder for step-out functionality
}
fn step(&mut self) {
// Fetch and execute instructions
} }
} }

View File

@ -1,28 +1,19 @@
use wasmtime::*; use std::path::PathBuf;
use crate::cpu_trait::{CpuTrait, RunMode, DebugMode};
fn main() -> Result<(), Box<dyn std::error::Error>> { use hecate::WasmCpu;
// Create an engine and module use clap::Parser;
let engine = Engine::default();
let module = Module::from_file(&engine, "path/to/wasm_cpu.wasm")?;
// Create a linker and instantiate the module #[derive(Parser)]
let mut linker = Linker::new(&engine); struct Args {
let instance = linker.instantiate(&module)?; cpu: PathBuf,
memory: PathBuf,
}
// Access the exported functions fn main() -> anyhow::Result<()> {
let new = instance.get_func("new").unwrap().get0::<i32>()?; let Args { cpu, memory } = Args::parse();
let execute = instance.get_func("execute").unwrap().get1::<i32, ()>()?; let mut cpu = WasmCpu::from_path(cpu)?;
let mem = std::fs::read(memory)?;
// Create a CPU instance cpu.load_memory(&mem);
let cpu = new();
// Load memory into the CPU
let memory = instance.get_memory("memory").unwrap();
memory.write(0, &[0x01, 0x02, 0x03])?;
// Execute the CPU
execute(cpu, RunMode::Run.into());
Ok(()) Ok(())
} }

View File

@ -9,5 +9,5 @@ crate-type = ["cdylib"]
[dependencies] [dependencies]
extism-pdk = "1.3.0" extism-pdk = "1.3.0"
hecate = { version = "0.1.0", path = ".." }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
common = { version = "0.1.0", path = "../common" }

View File

@ -1,9 +1,11 @@
use extism_pdk::*; use extism_pdk::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use hecate::cpu_trait::{CpuTrait, DebugMode, RunMode}; use common::{DebugMode, Init, RunMode, RunResult, SetMemory, SetVerbose};
pub struct WasmCpu { #[derive(Serialize, Deserialize, ToBytes, FromBytes)]
#[encoding(Json)]
pub struct Cpu {
memory: Vec<u8>, memory: Vec<u8>,
registers: Vec<u16>, registers: Vec<u16>,
ip: u16, ip: u16,
@ -12,14 +14,6 @@ pub struct WasmCpu {
verbose: bool, verbose: bool,
} }
#[derive(serde::Deserialize, FromBytes)]
#[encoding(Json)]
struct Init {
verbose: bool,
mem_size: usize,
registers: usize,
}
// start with something simple // start with something simple
#[plugin_fn] #[plugin_fn]
pub fn init( pub fn init(
@ -29,23 +23,77 @@ pub fn init(
registers, registers,
}: Init, }: Init,
) -> FnResult<()> { ) -> FnResult<()> {
var::set_var!( var::set(
"cpu", "cpu",
WasmCpu { Cpu {
memory: vec![0; mem_size], memory: vec![0; mem_size],
registers: vec![0; 8], registers: vec![0; registers],
ip: 0, ip: 0,
sp: 0xFFFF, sp: 0xFFFF,
flags: 0, flags: 0,
verbose, verbose,
} },
); )?;
Ok(()) Ok(())
} }
#[plugin_fn] #[plugin_fn]
pub fn add(input: Add) -> FnResult<Sum> { pub fn set_verbose(verbose: SetVerbose) -> FnResult<()> {
Ok(Sum { let mut cpu: Cpu = var::get("cpu")?.unwrap();
value: input.left + input.right, cpu.verbose = verbose.0;
}) var::set("cpu", cpu)?;
Ok(())
}
#[plugin_fn]
pub fn load_memory(SetMemory { offset, memory }: SetMemory) -> FnResult<()> {
let mut cpu: Cpu = var::get("cpu")?.unwrap();
cpu.memory[offset..memory.len()].copy_from_slice(&memory);
var::set("cpu", cpu)?;
Ok(())
}
#[plugin_fn]
pub fn execute(run_mode: RunMode) -> FnResult<RunResult> {
match run_mode {
RunMode::Run => run(),
RunMode::Debug(debug_mode) => debug(debug_mode),
RunMode::StepOver => step_over(),
RunMode::StepInto => step_into(),
RunMode::StepOut => step_out(),
RunMode::RunFor(cycles) => run_for(cycles),
}
}
pub fn run() -> FnResult<RunResult> {
// while self.ip < self.memory.len() as u16 {
// }
Ok(RunResult::Success)
}
pub fn debug(_debug_mode: DebugMode) -> FnResult<RunResult> {
// Implement debug functionality
Ok(RunResult::Success)
}
pub fn run_for(cycles: usize) -> FnResult<RunResult> {
for _ in 0..cycles {}
Ok(RunResult::Success)
}
pub fn step_over() -> FnResult<RunResult> {
Ok(RunResult::Success)
}
pub fn step_into() -> FnResult<RunResult> {
Ok(RunResult::Success)
}
pub fn step_out() -> FnResult<RunResult> {
Ok(RunResult::Success)
}
pub fn step() -> FnResult<RunResult> {
// Fetch and execute instructions
Ok(RunResult::Success)
} }