Skip to content

Commit 1c43154

Browse files
authored
chore: General Sys phantom (#1867)
1 parent e027992 commit 1c43154

File tree

4 files changed

+102
-58
lines changed

4 files changed

+102
-58
lines changed

crates/vm/src/arch/extensions.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use openvm_circuit_primitives::{
1717
};
1818
use openvm_circuit_primitives_derive::{Chip, ChipUsageGetter};
1919
use openvm_instructions::{
20-
program::Program, LocalOpcode, PhantomDiscriminant, PublishOpcode, SystemOpcode, VmOpcode,
20+
program::Program, LocalOpcode, PhantomDiscriminant, PublishOpcode, SysPhantom, SysPhantom::Nop,
21+
SystemOpcode, VmOpcode,
2122
};
2223
use openvm_stark_backend::{
2324
config::{Domain, StarkGenericConfig},
@@ -49,7 +50,9 @@ use crate::{
4950
MemoryController, MemoryImage, BOUNDARY_AIR_OFFSET, MERKLE_AIR_OFFSET,
5051
},
5152
native_adapter::{NativeAdapterAir, NativeAdapterStep},
52-
phantom::PhantomChip,
53+
phantom::{
54+
CycleEndPhantomExecutor, CycleStartPhantomExecutor, NopPhantomExecutor, PhantomChip,
55+
},
5356
poseidon2::Poseidon2PeripheryChip,
5457
program::{ProgramBus, ProgramChip},
5558
public_values::{
@@ -640,7 +643,22 @@ impl<F: PrimeField32> SystemComplex<F> {
640643
inventory.add_periphery_chip(chip);
641644
}
642645
let phantom_opcode = SystemOpcode::PHANTOM.global_opcode();
643-
let phantom_chip = PhantomChip::new(execution_bus, program_bus, SystemOpcode::CLASS_OFFSET);
646+
let mut phantom_chip =
647+
PhantomChip::new(execution_bus, program_bus, SystemOpcode::CLASS_OFFSET);
648+
// Use NopPhantomExecutor so the discriminant is set but `DebugPanic` is handled specially.
649+
phantom_chip.add_sub_executor(
650+
NopPhantomExecutor,
651+
PhantomDiscriminant(SysPhantom::DebugPanic as u16),
652+
);
653+
phantom_chip.add_sub_executor(NopPhantomExecutor, PhantomDiscriminant(Nop as u16));
654+
phantom_chip.add_sub_executor(
655+
CycleStartPhantomExecutor,
656+
PhantomDiscriminant(SysPhantom::CtStart as u16),
657+
);
658+
phantom_chip.add_sub_executor(
659+
CycleEndPhantomExecutor,
660+
PhantomDiscriminant(SysPhantom::CtEnd as u16),
661+
);
644662
inventory
645663
.add_executor(RefCell::new(phantom_chip), [phantom_opcode])
646664
.unwrap();

crates/vm/src/arch/interpreter.rs

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ use std::{
77
use itertools::Itertools;
88
use openvm_circuit_primitives_derive::AlignedBytesBorrow;
99
use openvm_instructions::{
10-
exe::VmExe,
11-
instruction::Instruction,
12-
program::{Program, DEFAULT_PC_STEP},
13-
LocalOpcode, SysPhantom, SystemOpcode,
10+
exe::VmExe, instruction::Instruction, program::Program, LocalOpcode, SystemOpcode,
1411
};
1512
use openvm_stark_backend::p3_field::{Field, PrimeField32};
1613
use rand::{rngs::StdRng, SeedableRng};
@@ -291,21 +288,6 @@ unsafe fn terminate_execute_e12_impl<F: PrimeField32, CTX: E1ExecutionCtx>(
291288
vm_state.exit_code = Ok(Some(pre_compute.exit_code));
292289
}
293290

294-
unsafe fn debug_panic_execute_e12_impl<F: PrimeField32, CTX: E1ExecutionCtx>(
295-
_pre_compute: &[u8],
296-
vm_state: &mut VmSegmentState<F, CTX>,
297-
) {
298-
vm_state.exit_code = Err(ExecutionError::Fail { pc: vm_state.pc });
299-
}
300-
301-
unsafe fn nop_execute_e12_impl<F: PrimeField32, CTX: E1ExecutionCtx>(
302-
_pre_compute: &[u8],
303-
vm_state: &mut VmSegmentState<F, CTX>,
304-
) {
305-
vm_state.pc += DEFAULT_PC_STEP;
306-
vm_state.instret += 1;
307-
}
308-
309291
fn get_pre_compute_max_size<F: PrimeField32, E: InsExecutorE1<F>, P>(
310292
program: &Program<F>,
311293
chip_complex: &VmChipComplex<F, E, P>,
@@ -361,15 +343,8 @@ fn get_e2_pre_compute_max_size<F: PrimeField32, E: InsExecutorE2<F>, P>(
361343
}
362344

363345
fn system_opcode_pre_compute_size<F: PrimeField32>(inst: &Instruction<F>) -> Option<usize> {
364-
let discriminant = SysPhantom::from_repr(inst.c.as_canonical_u32() as u16);
365346
if inst.opcode == SystemOpcode::TERMINATE.global_opcode() {
366347
return Some(size_of::<TerminatePreCompute>());
367-
} else if inst.opcode == SystemOpcode::PHANTOM.global_opcode() && discriminant.is_some() {
368-
let discriminant = discriminant.unwrap();
369-
let ret = match discriminant {
370-
SysPhantom::DebugPanic | SysPhantom::Nop | SysPhantom::CtStart | SysPhantom::CtEnd => 0,
371-
};
372-
return Some(ret);
373348
}
374349
None
375350
}
@@ -482,16 +457,7 @@ fn get_system_opcode_handler<F: PrimeField32, Ctx: E1ExecutionCtx>(
482457
inst: &Instruction<F>,
483458
buf: &mut [u8],
484459
) -> Option<ExecuteFunc<F, Ctx>> {
485-
let discriminant = SysPhantom::from_repr(inst.c.as_canonical_u32() as u16);
486-
if inst.opcode == SystemOpcode::PHANTOM.global_opcode() && discriminant.is_some() {
487-
let discriminant = discriminant.unwrap();
488-
return Some(match discriminant {
489-
SysPhantom::Nop => nop_execute_e12_impl,
490-
SysPhantom::DebugPanic => debug_panic_execute_e12_impl,
491-
SysPhantom::CtStart => nop_execute_e12_impl,
492-
SysPhantom::CtEnd => nop_execute_e12_impl,
493-
});
494-
} else if inst.opcode == SystemOpcode::TERMINATE.global_opcode() {
460+
if inst.opcode == SystemOpcode::TERMINATE.global_opcode() {
495461
let pre_compute: &mut TerminatePreCompute = buf.borrow_mut();
496462
pre_compute.exit_code = inst.c.as_canonical_u32();
497463
return Some(terminate_execute_e12_impl);

crates/vm/src/system/phantom/execution.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ unsafe fn execute_e12_impl<F: PrimeField32, CTX: E1ExecutionCtx>(
7070
vm_state: &mut VmSegmentState<F, CTX>,
7171
) {
7272
let sub_executor = &*pre_compute.sub_executor;
73-
execute_impl(
73+
if let Err(e) = execute_impl(
7474
PhantomStateMut {
7575
pc: &mut vm_state.pc,
7676
memory: &mut vm_state.memory,
@@ -79,8 +79,10 @@ unsafe fn execute_e12_impl<F: PrimeField32, CTX: E1ExecutionCtx>(
7979
},
8080
&pre_compute.operands,
8181
sub_executor.as_ref(),
82-
)
83-
.unwrap();
82+
) {
83+
vm_state.exit_code = Err(e);
84+
return;
85+
}
8486
vm_state.pc += DEFAULT_PC_STEP;
8587
vm_state.instret += 1;
8688
}
@@ -120,23 +122,26 @@ where
120122
let discriminant = PhantomDiscriminant(c as u16);
121123
// If not a system phantom sub-instruction (which is handled in
122124
// ExecutionSegment), look for a phantom sub-executor to handle it.
123-
if SysPhantom::from_repr(discriminant.0).is_none() {
124-
sub_executor
125-
.phantom_execute(
126-
state.memory,
127-
state.streams,
128-
state.rng,
129-
discriminant,
130-
a,
131-
b,
132-
(c >> 16) as u16,
133-
)
134-
.map_err(|e| ExecutionError::Phantom {
135-
pc: *state.pc,
136-
discriminant,
137-
inner: e,
138-
})?;
125+
if let Some(discr) = SysPhantom::from_repr(discriminant.0) {
126+
if discr == SysPhantom::DebugPanic {
127+
return Err(ExecutionError::Fail { pc: *state.pc });
128+
}
139129
}
130+
sub_executor
131+
.phantom_execute(
132+
state.memory,
133+
state.streams,
134+
state.rng,
135+
discriminant,
136+
a,
137+
b,
138+
(c >> 16) as u16,
139+
)
140+
.map_err(|e| ExecutionError::Phantom {
141+
pc: *state.pc,
142+
discriminant,
143+
inner: e,
144+
})?;
140145

141146
Ok(())
142147
}

crates/vm/src/system/phantom/mod.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::{
3131
PcIncOrSet, PhantomSubExecutor, Streams,
3232
},
3333
system::{
34+
memory::online::GuestMemory,
3435
phantom::execution::{execute_impl, PhantomOperands, PhantomStateMut},
3536
program::ProgramBus,
3637
},
@@ -211,3 +212,57 @@ where
211212
AirProofInput::simple(trace, vec![])
212213
}
213214
}
215+
216+
pub struct NopPhantomExecutor;
217+
pub struct CycleStartPhantomExecutor;
218+
pub struct CycleEndPhantomExecutor;
219+
220+
impl<F> PhantomSubExecutor<F> for NopPhantomExecutor {
221+
#[inline(always)]
222+
fn phantom_execute(
223+
&self,
224+
_memory: &GuestMemory,
225+
_streams: &mut Streams<F>,
226+
_rng: &mut StdRng,
227+
_discriminant: PhantomDiscriminant,
228+
_a: u32,
229+
_b: u32,
230+
_c_upper: u16,
231+
) -> eyre::Result<()> {
232+
Ok(())
233+
}
234+
}
235+
236+
impl<F> PhantomSubExecutor<F> for CycleStartPhantomExecutor {
237+
#[inline(always)]
238+
fn phantom_execute(
239+
&self,
240+
_memory: &GuestMemory,
241+
_streams: &mut Streams<F>,
242+
_rng: &mut StdRng,
243+
_discriminant: PhantomDiscriminant,
244+
_a: u32,
245+
_b: u32,
246+
_c_upper: u16,
247+
) -> eyre::Result<()> {
248+
// TODO: implement cycle tracker for E1/E2
249+
Ok(())
250+
}
251+
}
252+
253+
impl<F> PhantomSubExecutor<F> for CycleEndPhantomExecutor {
254+
#[inline(always)]
255+
fn phantom_execute(
256+
&self,
257+
_memory: &GuestMemory,
258+
_streams: &mut Streams<F>,
259+
_rng: &mut StdRng,
260+
_discriminant: PhantomDiscriminant,
261+
_a: u32,
262+
_b: u32,
263+
_c_upper: u16,
264+
) -> eyre::Result<()> {
265+
// TODO: implement cycle tracker for E1/E2
266+
Ok(())
267+
}
268+
}

0 commit comments

Comments
 (0)