Skip to content

Commit 9ccf91e

Browse files
committed
feat: Add new DefaultMachineRunner trait for initialization work
Previously, all different machines in ckb-vm might use slightly different initialization process. This commit introduces a new DefaultMachineRunner trait, so the same initialization & usage workflow can be used for all types implementing this trait.
1 parent 5e6ef8a commit 9ccf91e

21 files changed

+340
-186
lines changed

definitions/src/asm.rs

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use crate::{
2-
instructions::Instruction, MEMORY_FRAMES, MEMORY_FRAMESIZE, MEMORY_FRAME_SHIFTS,
3-
RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY, RISCV_PAGES, RISCV_PAGESIZE,
2+
instructions::Instruction, MEMORY_FRAMES, RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY,
3+
RISCV_PAGES,
44
};
5-
use std::alloc::{alloc, Layout};
65

76
// The number of trace items to keep
87
pub const TRACE_SIZE: usize = 8192;
@@ -67,59 +66,3 @@ pub struct AsmCoreMachine {
6766

6867
pub memory: [u8; RISCV_MAX_MEMORY],
6968
}
70-
71-
impl AsmCoreMachine {
72-
pub fn new(isa: u8, version: u32, max_cycles: u64) -> Box<AsmCoreMachine> {
73-
Self::new_with_memory(isa, version, max_cycles, RISCV_MAX_MEMORY)
74-
}
75-
76-
pub fn new_with_memory(
77-
isa: u8,
78-
version: u32,
79-
max_cycles: u64,
80-
memory_size: usize,
81-
) -> Box<AsmCoreMachine> {
82-
assert_ne!(memory_size, 0);
83-
assert_eq!(memory_size % RISCV_PAGESIZE, 0);
84-
assert_eq!(memory_size % (1 << MEMORY_FRAME_SHIFTS), 0);
85-
86-
let mut machine = unsafe {
87-
let machine_size =
88-
std::mem::size_of::<AsmCoreMachine>() - RISCV_MAX_MEMORY + memory_size;
89-
90-
let layout = Layout::array::<u8>(machine_size).unwrap();
91-
let raw_allocation = alloc(layout) as *mut AsmCoreMachine;
92-
Box::from_raw(raw_allocation)
93-
};
94-
machine.registers = [0; RISCV_GENERAL_REGISTER_NUMBER];
95-
machine.pc = 0;
96-
machine.next_pc = 0;
97-
machine.running = 0;
98-
machine.cycles = 0;
99-
machine.max_cycles = max_cycles;
100-
if cfg!(feature = "enable-chaos-mode-by-default") {
101-
machine.chaos_mode = 1;
102-
} else {
103-
machine.chaos_mode = 0;
104-
}
105-
machine.chaos_seed = 0;
106-
machine.load_reservation_address = u64::MAX;
107-
machine.reset_signal = 0;
108-
machine.version = version;
109-
machine.isa = isa;
110-
machine.flags = [0; RISCV_PAGES];
111-
for i in 0..TRACE_SIZE {
112-
machine.traces[i] = Trace::default();
113-
}
114-
machine.frames = [0; MEMORY_FRAMES];
115-
116-
machine.memory_size = memory_size as u64;
117-
machine.frames_size = (memory_size / MEMORY_FRAMESIZE) as u64;
118-
machine.flags_size = (memory_size / RISCV_PAGESIZE) as u64;
119-
120-
machine.last_read_frame = u64::MAX;
121-
machine.last_write_page = u64::MAX;
122-
123-
machine
124-
}
125-
}

definitions/src/generate_asm_constants.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use ckb_vm_definitions::{
1111
MEMORY_FRAMES, MEMORY_FRAMESIZE, MEMORY_FRAME_PAGE_SHIFTS, MEMORY_FRAME_SHIFTS,
1212
RISCV_MAX_MEMORY, RISCV_PAGES, RISCV_PAGESIZE, RISCV_PAGE_SHIFTS,
1313
};
14+
use std::alloc::{alloc, Layout};
1415
use std::mem::{size_of, zeroed};
1516

1617
macro_rules! print_inst_label {
@@ -120,7 +121,15 @@ fn main() {
120121
);
121122
println!();
122123

123-
let m: Box<AsmCoreMachine> = AsmCoreMachine::new(0, 0, 0);
124+
// We don't need a fully initialized AsmCoreMachine, only a dummy
125+
// structure here will do.
126+
let m: Box<AsmCoreMachine> = unsafe {
127+
let machine_size = std::mem::size_of::<AsmCoreMachine>();
128+
129+
let layout = Layout::array::<u8>(machine_size).unwrap();
130+
let raw_allocation = alloc(layout) as *mut AsmCoreMachine;
131+
Box::from_raw(raw_allocation)
132+
};
124133
let m_address = &*m as *const AsmCoreMachine as usize;
125134
println!(
126135
"#define CKB_VM_ASM_ASM_CORE_MACHINE_OFFSET_REGISTERS {}",

examples/check_real_memory.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::process::{id, Command};
99
use ckb_vm::{
1010
machine::{
1111
asm::{AsmCoreMachine, AsmMachine},
12-
DefaultMachineBuilder, VERSION0,
12+
DefaultMachineBuilder, DefaultMachineRunner, SupportMachine, VERSION0,
1313
},
1414
ISA_IMC,
1515
};
@@ -168,7 +168,12 @@ fn check_asm(memory_size: usize) -> Result<(), ()> {
168168
);
169169
println!("Base memory: {}", get_current_memory());
170170
for _ in 0..G_CHECK_LOOP {
171-
let asm_core = AsmCoreMachine::new_with_memory(ISA_IMC, VERSION0, u64::MAX, memory_size);
171+
let asm_core = <Box<AsmCoreMachine> as SupportMachine>::new_with_memory(
172+
ISA_IMC,
173+
VERSION0,
174+
u64::MAX,
175+
memory_size,
176+
);
172177
let core = DefaultMachineBuilder::new(asm_core).build();
173178
let mut machine = AsmMachine::new(core);
174179
machine
@@ -192,7 +197,12 @@ fn check_asm_in_thread(memory_size: usize) -> Result<(), ()> {
192197
);
193198
println!("Base memory: {}", get_current_memory());
194199
for _ in 0..G_CHECK_LOOP {
195-
let asm_core = AsmCoreMachine::new_with_memory(ISA_IMC, VERSION0, u64::MAX, memory_size);
200+
let asm_core = <Box<AsmCoreMachine> as SupportMachine>::new_with_memory(
201+
ISA_IMC,
202+
VERSION0,
203+
u64::MAX,
204+
memory_size,
205+
);
196206
let core = DefaultMachineBuilder::new(asm_core).build();
197207
let mut machine = AsmMachine::new(core);
198208
machine

examples/ckb-vm-runner.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ impl<Mac: SupportMachine> Syscalls<Mac> for DebugSyscall {
3939

4040
#[cfg(has_asm)]
4141
fn main_asm(code: Bytes, args: Vec<Bytes>) -> Result<(), Box<dyn std::error::Error>> {
42-
let asm_core = ckb_vm::machine::asm::AsmCoreMachine::new(
42+
use ckb_vm::DefaultMachineRunner;
43+
44+
let asm_core = <Box<ckb_vm::machine::asm::AsmCoreMachine> as SupportMachine>::new(
4345
ckb_vm::ISA_IMC | ckb_vm::ISA_B | ckb_vm::ISA_MOP | ckb_vm::ISA_A,
4446
ckb_vm::machine::VERSION2,
4547
u64::MAX,

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ pub use crate::{
2222
instructions::{Instruction, Register},
2323
machine::{
2424
trace::TraceMachine, CoreMachine, DefaultCoreMachine, DefaultMachine,
25-
DefaultMachineBuilder, FlattenedArgsReader, InstructionCycleFunc, Machine, SupportMachine,
25+
DefaultMachineBuilder, DefaultMachineRunner, FlattenedArgsReader, InstructionCycleFunc,
26+
Machine, SupportMachine,
2627
},
2728
memory::{flat::FlatMemory, sparse::SparseMemory, wxorx::WXorXMemory, Memory},
2829
syscalls::Syscalls,

src/machine/asm/mod.rs

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ use ckb_vm_definitions::{
88
RET_SLOWPATH, TRACE_ITEM_LENGTH, TRACE_SIZE,
99
},
1010
instructions::OP_CUSTOM_TRACE_END,
11-
ISA_MOP, MEMORY_FRAMES, MEMORY_FRAME_PAGE_SHIFTS, RISCV_GENERAL_REGISTER_NUMBER,
12-
RISCV_PAGE_SHIFTS,
11+
ISA_MOP, MEMORY_FRAMES, MEMORY_FRAMESIZE, MEMORY_FRAME_PAGE_SHIFTS,
12+
RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY, RISCV_PAGE_SHIFTS,
1313
};
1414
use rand::{prelude::RngCore, SeedableRng};
15+
use std::alloc::{alloc, Layout};
1516
use std::os::raw::c_uchar;
1617

1718
use crate::{
@@ -26,8 +27,8 @@ use crate::{
2627
fill_page_data, get_page_indices, memset, round_page_down, round_page_up, FLAG_DIRTY,
2728
FLAG_EXECUTABLE, FLAG_FREEZED, FLAG_WRITABLE, FLAG_WXORX_BIT,
2829
},
29-
CoreMachine, DefaultMachine, Error, Machine, Memory, SupportMachine, MEMORY_FRAME_SHIFTS,
30-
RISCV_PAGES, RISCV_PAGESIZE,
30+
CoreMachine, DefaultMachine, DefaultMachineRunner, Error, Machine, Memory, SupportMachine,
31+
MEMORY_FRAME_SHIFTS, RISCV_PAGES, RISCV_PAGESIZE,
3132
};
3233

3334
impl CoreMachine for Box<AsmCoreMachine> {
@@ -412,6 +413,56 @@ impl Memory for Box<AsmCoreMachine> {
412413
}
413414

414415
impl SupportMachine for Box<AsmCoreMachine> {
416+
fn new_with_memory(
417+
isa: u8,
418+
version: u32,
419+
max_cycles: u64,
420+
memory_size: usize,
421+
) -> Box<AsmCoreMachine> {
422+
assert_ne!(memory_size, 0);
423+
assert_eq!(memory_size % RISCV_PAGESIZE, 0);
424+
assert_eq!(memory_size % (1 << MEMORY_FRAME_SHIFTS), 0);
425+
426+
let mut machine = unsafe {
427+
let machine_size =
428+
std::mem::size_of::<AsmCoreMachine>() - RISCV_MAX_MEMORY + memory_size;
429+
430+
let layout = Layout::array::<u8>(machine_size).unwrap();
431+
let raw_allocation = alloc(layout) as *mut AsmCoreMachine;
432+
Box::from_raw(raw_allocation)
433+
};
434+
machine.registers = [0; RISCV_GENERAL_REGISTER_NUMBER];
435+
machine.pc = 0;
436+
machine.next_pc = 0;
437+
machine.running = 0;
438+
machine.cycles = 0;
439+
machine.max_cycles = max_cycles;
440+
if cfg!(feature = "enable-chaos-mode-by-default") {
441+
machine.chaos_mode = 1;
442+
} else {
443+
machine.chaos_mode = 0;
444+
}
445+
machine.chaos_seed = 0;
446+
machine.load_reservation_address = u64::MAX;
447+
machine.reset_signal = 0;
448+
machine.version = version;
449+
machine.isa = isa;
450+
machine.flags = [0; RISCV_PAGES];
451+
for i in 0..TRACE_SIZE {
452+
machine.traces[i] = Trace::default();
453+
}
454+
machine.frames = [0; MEMORY_FRAMES];
455+
456+
machine.memory_size = memory_size as u64;
457+
machine.frames_size = (memory_size / MEMORY_FRAMESIZE) as u64;
458+
machine.flags_size = (memory_size / RISCV_PAGESIZE) as u64;
459+
460+
machine.last_read_frame = u64::MAX;
461+
machine.last_write_page = u64::MAX;
462+
463+
machine
464+
}
465+
415466
fn cycles(&self) -> u64 {
416467
self.cycles
417468
}
@@ -473,34 +524,22 @@ pub struct AsmMachine {
473524
pub machine: DefaultMachine<Box<AsmCoreMachine>>,
474525
}
475526

476-
impl AsmMachine {
477-
pub fn new(machine: DefaultMachine<Box<AsmCoreMachine>>) -> Self {
478-
Self { machine }
479-
}
527+
impl DefaultMachineRunner for AsmMachine {
528+
type Inner = Box<AsmCoreMachine>;
480529

481-
pub fn set_max_cycles(&mut self, cycles: u64) {
482-
self.machine.inner.max_cycles = cycles;
530+
fn new(machine: DefaultMachine<Box<AsmCoreMachine>>) -> Self {
531+
Self { machine }
483532
}
484533

485-
pub fn load_program(
486-
&mut self,
487-
program: &Bytes,
488-
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
489-
) -> Result<u64, Error> {
490-
self.machine.load_program(program, args)
534+
fn machine(&self) -> &DefaultMachine<Box<AsmCoreMachine>> {
535+
&self.machine
491536
}
492537

493-
pub fn load_program_with_metadata(
494-
&mut self,
495-
program: &Bytes,
496-
metadata: &ProgramMetadata,
497-
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
498-
) -> Result<u64, Error> {
499-
self.machine
500-
.load_program_with_metadata(program, metadata, args)
538+
fn machine_mut(&mut self) -> &mut DefaultMachine<Box<AsmCoreMachine>> {
539+
&mut self.machine
501540
}
502541

503-
pub fn run(&mut self) -> Result<i8, Error> {
542+
fn run(&mut self) -> Result<i8, Error> {
504543
if self.machine.isa() & ISA_MOP != 0 && self.machine.version() == VERSION0 {
505544
return Err(Error::InvalidVersion);
506545
}
@@ -573,6 +612,30 @@ impl AsmMachine {
573612
}
574613
Ok(self.machine.exit_code())
575614
}
615+
}
616+
617+
impl AsmMachine {
618+
pub fn set_max_cycles(&mut self, cycles: u64) {
619+
self.machine.inner.max_cycles = cycles;
620+
}
621+
622+
pub fn load_program(
623+
&mut self,
624+
program: &Bytes,
625+
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
626+
) -> Result<u64, Error> {
627+
self.machine.load_program(program, args)
628+
}
629+
630+
pub fn load_program_with_metadata(
631+
&mut self,
632+
program: &Bytes,
633+
metadata: &ProgramMetadata,
634+
args: impl ExactSizeIterator<Item = Result<Bytes, Error>>,
635+
) -> Result<u64, Error> {
636+
self.machine
637+
.load_program_with_metadata(program, metadata, args)
638+
}
576639

577640
pub fn step(&mut self, decoder: &mut Decoder) -> Result<(), Error> {
578641
// Decode only one instruction into a trace

0 commit comments

Comments
 (0)