diff --git a/script/src/lib.rs b/script/src/lib.rs index d77f75b8ca..c50468a7c5 100644 --- a/script/src/lib.rs +++ b/script/src/lib.rs @@ -13,7 +13,7 @@ pub use crate::scheduler::{Scheduler, ROOT_VM_ID}; pub use crate::syscalls::generator::generate_ckb_syscalls; pub use crate::types::{ ChunkCommand, CoreMachine, DataLocation, DataPieceId, RunMode, ScriptGroup, ScriptGroupType, - ScriptVersion, TransactionState, TxData, VerifyResult, VmIsa, VmState, VmVersion, + ScriptVersion, TransactionState, TxData, VerifyResult, VmArgs, VmIsa, VmState, VmVersion, }; pub use crate::verify::TransactionScriptsVerifier; pub use crate::verify_env::TxVerifyEnv; diff --git a/script/src/scheduler.rs b/script/src/scheduler.rs index 348b5caeaa..807b7ce5b2 100644 --- a/script/src/scheduler.rs +++ b/script/src/scheduler.rs @@ -6,7 +6,7 @@ use crate::syscalls::{ use crate::types::{ CoreMachineType, DataLocation, DataPieceId, DebugContext, Fd, FdArgs, FullSuspendedState, - Machine, Message, ReadState, RunMode, SgData, VmContext, VmId, VmState, WriteState, + Machine, Message, ReadState, RunMode, SgData, VmArgs, VmContext, VmId, VmState, WriteState, FIRST_FD_SLOT, FIRST_VM_ID, }; use ckb_traits::{CellDataProvider, ExtensionProvider, HeaderProvider}; @@ -240,7 +240,7 @@ where offset: 0, length: u64::MAX, }, - None + VmArgs::Vector(vec![]), )?, ROOT_VM_ID ); @@ -401,7 +401,11 @@ where &mut new_machine, &args.location, program, - Some((vm_id, args.argc, args.argv)), + VmArgs::Reader { + vm_id, + argc: args.argc, + argv: args.argv, + }, )?; // The insert operation removes the old vm instance and adds the new vm instance. debug_assert!(self.instantiated.contains_key(&vm_id)); @@ -419,8 +423,14 @@ where machine.machine.set_register(A0, MAX_VMS_SPAWNED as u64); continue; } - let spawned_vm_id = - self.boot_vm(&args.location, Some((vm_id, args.argc, args.argv)))?; + let spawned_vm_id = self.boot_vm( + &args.location, + VmArgs::Reader { + vm_id, + argc: args.argc, + argv: args.argv, + }, + )?; // Move passed fds from spawner to spawnee for fd in &args.fds { self.fds.insert(*fd, spawned_vm_id); @@ -811,11 +821,7 @@ where } /// Boot a vm by given program and args. - pub fn boot_vm( - &mut self, - location: &DataLocation, - args: Option<(u64, u64, u64)>, - ) -> Result { + pub fn boot_vm(&mut self, location: &DataLocation, args: VmArgs) -> Result { let id = self.next_vm_id; self.next_vm_id += 1; let (context, mut machine) = self.create_dummy_vm(&id)?; @@ -848,16 +854,18 @@ where machine: &mut Machine, location: &DataLocation, program: Bytes, - args: Option<(u64, u64, u64)>, + args: VmArgs, ) -> Result { let metadata = parse_elf::(&program, machine.machine.version())?; let bytes = match args { - Some((vm_id, argc, argv)) => { + VmArgs::Reader { vm_id, argc, argv } => { let (_, machine_from) = self.ensure_get_instantiated(&vm_id)?; let argv = FlattenedArgsReader::new(machine_from.machine.memory_mut(), argc, argv); machine.load_program_with_metadata(&program, &metadata, argv)? } - None => machine.load_program_with_metadata(&program, &metadata, vec![].into_iter())?, + VmArgs::Vector(data) => { + machine.load_program_with_metadata(&program, &metadata, data.into_iter().map(Ok))? + } }; let mut sc = context.snapshot2_context.lock().expect("lock"); sc.mark_program( diff --git a/script/src/types.rs b/script/src/types.rs index 127919f786..812da09850 100644 --- a/script/src/types.rs +++ b/script/src/types.rs @@ -1012,6 +1012,23 @@ where } } +/// When the vm is initialized, arguments are loaded onto the stack. +/// This enum specifies how to locate these arguments. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub enum VmArgs { + /// Represents reading arguments from other vm. + Reader { + /// An identifier for the virtual machine/process. + vm_id: u64, + /// The number of arguments provided. + argc: u64, + /// The pointer of the actual arguments. + argv: u64, + }, + /// Represents reading arguments from a vector. + Vector(Vec), +} + /// Mutable data at virtual machine level #[derive(Clone)] pub struct VmContext