solana_program_runtime/
memory_context.rs1use {
2 crate::invoke_context::BpfAllocator, solana_instruction::error::InstructionError,
3 solana_sbpf::memory_region::MemoryMapping,
4};
5
6enum MemoryContextType {
7 ABIv1(MemoryContext),
8 Placeholder,
9}
10
11pub struct MemoryContexts {
12 contexts: Vec<MemoryContextType>,
13}
14
15impl MemoryContexts {
16 pub(crate) fn new() -> Self {
17 Self {
18 contexts: Vec::new(),
19 }
20 }
21
22 pub fn set_memory_context_abi_v1(
24 &mut self,
25 memory_context: MemoryContext,
26 ) -> Result<(), InstructionError> {
27 *self
28 .contexts
29 .last_mut()
30 .ok_or(InstructionError::CallDepth)? = MemoryContextType::ABIv1(memory_context);
31 Ok(())
32 }
33
34 pub fn memory_context_abi_v1(&self) -> Result<&MemoryContext, InstructionError> {
36 match self.contexts.last().ok_or(InstructionError::CallDepth)? {
37 MemoryContextType::ABIv1(ctx) => Ok(ctx),
38 MemoryContextType::Placeholder => Err(InstructionError::ProgramEnvironmentSetupFailure),
39 }
40 }
41
42 pub fn memory_context_mut_abi_v1(&mut self) -> Result<&mut MemoryContext, InstructionError> {
44 let context = self
45 .contexts
46 .last_mut()
47 .ok_or(InstructionError::CallDepth)?;
48
49 match context {
50 MemoryContextType::ABIv1(ctx) => Ok(ctx),
51 MemoryContextType::Placeholder => Err(InstructionError::ProgramEnvironmentSetupFailure),
52 }
53 }
54
55 pub fn memory_mapping(&self) -> Result<&MemoryMapping, InstructionError> {
56 let mapping = match self.contexts.last().ok_or(InstructionError::CallDepth)? {
57 MemoryContextType::ABIv1(ctx) => &ctx.memory_mapping,
58 MemoryContextType::Placeholder => {
59 return Err(InstructionError::ProgramEnvironmentSetupFailure);
60 }
61 };
62
63 Ok(mapping)
64 }
65
66 pub fn memory_mapping_mut(&mut self) -> Result<&mut MemoryMapping, InstructionError> {
67 let mapping = match self
68 .contexts
69 .last_mut()
70 .ok_or(InstructionError::CallDepth)?
71 {
72 MemoryContextType::ABIv1(ctx) => &mut ctx.memory_mapping,
73 MemoryContextType::Placeholder => {
74 return Err(InstructionError::ProgramEnvironmentSetupFailure);
75 }
76 };
77
78 Ok(mapping)
79 }
80
81 #[cfg(feature = "dev-context-only-utils")]
82 pub fn mock_set_mapping_abi_v1(&mut self, memory_mapping: MemoryMapping) {
83 self.contexts = vec![MemoryContextType::ABIv1(MemoryContext {
84 allocator: BpfAllocator::new(0),
85 accounts_metadata: vec![],
86 memory_mapping: Box::new(memory_mapping),
87 })];
88 }
89
90 pub fn push_placeholder(&mut self) {
91 self.contexts.push(MemoryContextType::Placeholder);
93 }
94
95 pub fn pop(&mut self) {
96 self.contexts.pop();
97 }
98}
99
100pub struct MemoryContext {
103 pub allocator: BpfAllocator,
104 pub accounts_metadata: Vec<SerializedAccountMetadata>,
105 memory_mapping: Box<MemoryMapping>,
106}
107
108impl MemoryContext {
109 pub fn new(
111 allocator: BpfAllocator,
112 accounts_metadata: Vec<SerializedAccountMetadata>,
113 memory_mapping: MemoryMapping,
114 ) -> Self {
115 Self {
116 allocator,
117 accounts_metadata,
118 memory_mapping: Box::new(memory_mapping),
119 }
120 }
121}
122
123#[derive(Debug, Clone)]
124pub struct SerializedAccountMetadata {
125 pub vm_addr: u64,
128 pub original_data_len: usize,
129 pub vm_data_addr: u64,
130 pub vm_key_addr: u64,
131 pub vm_lamports_addr: u64,
132 pub vm_owner_addr: u64,
133}