1use std::collections::HashMap;
2
3use triton_vm::prelude::*;
4
5use crate::prelude::*;
6use crate::rust_shadowing_helper_functions::list::list_new;
7use crate::snippet_bencher::BenchmarkCase;
8use crate::traits::function::Function;
9use crate::traits::function::FunctionInitialState;
10use crate::traits::rust_shadow::RustShadowError;
11
12#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
19pub struct New;
20
21impl BasicSnippet for New {
22 fn parameters(&self) -> Vec<(DataType, String)> {
23 vec![]
24 }
25
26 fn return_values(&self) -> Vec<(DataType, String)> {
27 vec![(DataType::VoidPointer, "*list".to_string())]
28 }
29
30 fn entrypoint(&self) -> String {
31 "tasmlib_list_new".to_string()
32 }
33
34 fn code(&self, library: &mut Library) -> Vec<LabelledInstruction> {
35 let dyn_malloc = library.import(Box::new(DynMalloc));
36
37 triton_asm!(
38 {self.entrypoint()}:
41 call {dyn_malloc}
42 push 0
46 pick 1
47 write_mem 1
48 addi -1
49 return
52 )
53 }
54}
55
56impl Function for New {
57 fn rust_shadow(
58 &self,
59 stack: &mut Vec<BFieldElement>,
60 memory: &mut HashMap<BFieldElement, BFieldElement>,
61 ) -> Result<(), RustShadowError> {
62 DynMalloc.rust_shadow(stack, memory)?;
63
64 let list_pointer = stack.last().copied();
65 let list_pointer = list_pointer.ok_or(RustShadowError::StackUnderflow)?;
66 list_new(list_pointer, memory);
67
68 Ok(())
69 }
70
71 fn pseudorandom_initial_state(
72 &self,
73 _: [u8; 32],
74 _: Option<BenchmarkCase>,
75 ) -> FunctionInitialState {
76 FunctionInitialState {
77 stack: self.init_stack_for_isolated_run(),
78 ..Default::default()
79 }
80 }
81}
82
83#[cfg(test)]
84pub(crate) mod tests {
85 use super::*;
86 use crate::test_prelude::*;
87
88 #[macro_rules_attr::apply(test)]
89 fn rust_shadow() {
90 ShadowedFunction::new(New).test();
91 }
92}
93
94#[cfg(test)]
95mod benches {
96 use super::*;
97 use crate::test_prelude::*;
98
99 #[macro_rules_attr::apply(test)]
100 fn benchmark() {
101 ShadowedFunction::new(New).bench();
102 }
103}