Skip to content

Commit

Permalink
Merge branch 'main' into morgan/issue/135
Browse files Browse the repository at this point in the history
  • Loading branch information
morganthomas committed Apr 8, 2024
2 parents 28b8c5f + 898d5ce commit a3c35c8
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ members = [
"range",
"static_data",
"util",
"verifier"
"verifier",
]

[workspace.dependencies]
Expand Down
2 changes: 2 additions & 0 deletions basic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ rand = "0.8.5"
rand_pcg = "0.3.1"
rand_seeder = "0.2.3"
tracing = "0.1.37"
reedline-repl-rs = "1.1.1"
valida-alu-u32 = { path = "../alu_u32" }
valida-assembler = { path = "../assembler" }
valida-bus = { path = "../bus" }
Expand Down Expand Up @@ -51,6 +52,7 @@ p3-merkle-tree = { workspace = true }
p3-poseidon = { workspace = true }
p3-symmetric = { workspace = true }


[dev-dependencies]
ciborium = "0.2.2"
p3-challenger = { workspace = true }
Expand Down
237 changes: 235 additions & 2 deletions basic/src/bin/valida.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use p3_baby_bear::BabyBear;

use p3_fri::{FriConfig, TwoAdicFriPcs, TwoAdicFriPcsConfig};
use valida_cpu::MachineWithCpuChip;
use valida_machine::{Machine, MachineProof, StdinAdviceProvider};
use valida_machine::{Machine, MachineProof, ProgramROM, StdinAdviceProvider};
use valida_memory::MachineWithMemoryChip;

use valida_elf::{load_executable_file, Program};
use valida_program::MachineWithProgramChip;
Expand All @@ -30,9 +31,12 @@ use valida_machine::StarkConfigImpl;
use valida_machine::__internal::p3_commit::ExtensionMmcs;
use valida_output::MachineWithOutputChip;

use reedline_repl_rs::clap::{Arg, ArgMatches, Command};
use reedline_repl_rs::{Repl, Result};

#[derive(Parser)]
struct Args {
/// Command option either "run" or "prove" or "verify"
/// Command option either "run" or "prove" or "verify" or "interactive"
#[arg(name = "Action Option")]
action: String,

Expand All @@ -49,9 +53,238 @@ struct Args {
stack_height: u32,
}

struct Context<'a> {
machine_: BasicMachine<BabyBear>,
args_: &'a Args,
breakpoints_: Vec<u32>,
stopped_: bool,
last_fp_: u32,
recorded_current_fp_: u32,
last_fp_size_: u32,
}

impl Context<'_> {
fn new(args: &Args) -> Context {
let mut context = Context {
machine_: BasicMachine::<BabyBear>::default(),
args_: args.clone(),
breakpoints_: Vec::new(),
stopped_: false,
last_fp_: args.stack_height,
recorded_current_fp_: args.stack_height,
last_fp_size_: 0,
};

let rom = match ProgramROM::from_file(&args.program) {
Ok(contents) => contents,
Err(e) => panic!("Failure to load file: {}. {}", &args.program, e),
};

context.machine_.program_mut().set_program_rom(&rom);
context.machine_.cpu_mut().fp = args.stack_height;
context.machine_.cpu_mut().save_register_state();

context
}

fn step(&mut self) -> (bool, u32) {
// do not execute if already stopped
if self.stopped_ {
return (true, 0);
}
let state = self.machine_.step(&mut StdinAdviceProvider);
let pc = self.machine_.cpu().pc;
let fp = self.machine_.cpu().fp;

// check if fp is changed
if fp != self.recorded_current_fp_ {
self.last_fp_size_ = self.recorded_current_fp_ - fp;
self.last_fp_ = self.recorded_current_fp_;
} else if fp == self.last_fp_ {
self.last_fp_size_ = 0;
}
self.recorded_current_fp_ = fp;

(state, pc)
}
}

fn init_context(args: ArgMatches, context: &mut Context) -> Result<Option<String>> {
Ok(Some(String::from("created machine")))
}

fn status(args: ArgMatches, context: &mut Context) -> Result<Option<String>> {
// construct machine status
let mut status = String::new();
status.push_str("FP: ");
status.push_str(&context.machine_.cpu().fp.to_string());
status.push_str(", PC: ");
status.push_str(&context.machine_.cpu().pc.to_string());
status.push_str(if context.stopped_ {
", Stopped"
} else {
", Running"
});
Ok(Some(status))
}

fn show_frame(args: ArgMatches, context: &mut Context) -> Result<Option<String>> {
let size: i32 = match args.contains_id("size") {
true => args
.get_one::<String>("size")
.unwrap()
.parse::<i32>()
.unwrap(),
false => 6,
};
let mut frame = String::new();
let fp = context.machine_.cpu().fp as i32;
frame.push_str(format!("FP: {:x}\n", fp).as_str());
for i in 0..size {
let offset = i * -4;
let read_addr = (fp + offset) as u32;
let string_val = context.machine_.mem().examine(read_addr);
let frameslot_addr = format!("{}(fp)", offset);
let frameslot = format!("{:>7}", frameslot_addr);
let frame_str = format!("\n{} : {}", frameslot, string_val);
frame += &frame_str;
}

Ok(Some(frame))
}

fn last_frame(_: ArgMatches, context: &mut Context) -> Result<Option<String>> {
let mut frame = String::new();

let lfp = context.last_fp_;
let fp = context.machine_.cpu().fp as i32;
let last_size = context.last_fp_size_ as i32;
frame += &format!("Last FP : 0x{:x}, Frame size: {}\n", lfp, last_size).as_str();
frame += &format!("Current FP: 0x{:x}\n", fp).as_str();

// print last frame
for i in (-5..(last_size / 4) + 1).rev() {
let offset = (i * 4) as i32;
let read_addr = (fp + offset) as u32;
let string_val = context.machine_.mem().examine(read_addr);
let frameslot_addr = format!("{}(fp)", offset);
let frameslot = format!("0x{:<7x} | {:>7}", read_addr, frameslot_addr);
let frame_str = format!("\n{} : {}", frameslot, string_val);
frame += &frame_str;
}
Ok(Some(frame))
}

fn list_instrs(_: ArgMatches, context: &mut Context) -> Result<Option<String>> {
let pc = context.machine_.cpu().pc;

let program_rom = &context.machine_.program().program_rom;
let total_size = program_rom.0.len();

let mut formatted = String::new();
for i in 0..5 {
let cur_pc = pc + i;
if cur_pc >= total_size as u32 {
break;
}
let instruction = program_rom.get_instruction(cur_pc);
formatted.push_str(format!("{:?} : {:?}\n", cur_pc, instruction).as_str());
}
Ok(Some(formatted))
}

fn set_bp(args: ArgMatches, context: &mut Context) -> Result<Option<String>> {
let pc = args
.get_one::<String>("pc")
.unwrap()
.parse::<u32>()
.unwrap();
context.breakpoints_.push(pc);
let message = format!("Breakpoint set at pc: {}", pc);
Ok(Some(message))
}

fn run_until(args: ArgMatches, context: &mut Context) -> Result<Option<String>> {
let mut message = String::new();
loop {
let (stop, pc) = context.step();
if stop {
message.push_str("Execution stopped");
break;
}
if context.breakpoints_.contains(&pc) {
let bp_index = context.breakpoints_.iter().position(|&x| x == pc).unwrap();
message = format!("Execution stopped at breakpoint {}, PC: {}", bp_index, pc);
break;
}
}
Ok(Some(message))
}

fn step(args: ArgMatches, context: &mut Context) -> Result<Option<String>> {
let (stop, _) = context.step();
if stop {
context.stopped_ = true;
Ok(Some(String::from("Execution stopped")))
} else {
Ok(None)
}
}

fn repl_run(args: &Args) {
// instantiate repl
let mut repl = Repl::new(Context::new(args))
.with_name("REPL")
.with_version("v0.1.0")
.with_description("Valida VM REPL")
.with_banner("Start by using keywords")
.with_command(Command::new("x").about("read machine state"), status)
.with_command(
Command::new("s")
.arg(Arg::new("num_steps").required(false))
.about("step assembly"),
step,
)
.with_command(
Command::new("f")
.arg(Arg::new("size").required(false))
.about("show frame"),
show_frame,
)
.with_command(
Command::new("lf").about("show last frame and current frame"),
last_frame,
)
.with_command(
Command::new("b")
.arg(Arg::new("pc").required(false))
.about("set break point at"),
set_bp,
)
.with_command(
Command::new("r").about("run until stop or breakpoint"),
run_until,
)
.with_command(
Command::new("l").about("list instruction at current PC"),
list_instrs,
)
.with_command(
Command::new("reset").about("reset machine state!"),
init_context,
);

let _ = repl.run();
}

fn main() {
let args = Args::parse();

if args.action == "interactive" {
repl_run(&args);
return;
}

let mut machine = BasicMachine::<BabyBear>::default();
let Program { code, data } = load_executable_file(
fs::read(&args.program)
Expand Down
1 change: 0 additions & 1 deletion basic/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![no_std]
#![allow(unused)]

extern crate alloc;
Expand Down
6 changes: 1 addition & 5 deletions basic/tests/test_static_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ extern crate core;

use p3_baby_bear::BabyBear;
use p3_fri::{TwoAdicFriPcs, TwoAdicFriPcsConfig};
use valida_alu_u32::add::{Add32Instruction, MachineWithAdd32Chip};
use valida_basic::BasicMachine;
use valida_cpu::{
BneInstruction, Imm32Instruction, Load32Instruction, MachineWithCpuChip, StopInstruction,
};
use valida_machine::{
FixedAdviceProvider, Instruction, InstructionWord, Machine, MachineProof, Operands, ProgramROM,
Word,
FixedAdviceProvider, Instruction, InstructionWord, Machine, Operands, ProgramROM, Word,
};

use valida_memory::MachineWithMemoryChip;
use valida_opcodes::BYTES_PER_INSTR;
use valida_program::MachineWithProgramChip;
use valida_static_data::MachineWithStaticDataChip;

Expand Down
Loading

0 comments on commit a3c35c8

Please sign in to comment.