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;
10
11#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
12pub struct New;
13
14impl BasicSnippet for New {
15 fn inputs(&self) -> Vec<(DataType, String)> {
16 vec![]
17 }
18
19 fn outputs(&self) -> Vec<(DataType, String)> {
20 vec![(DataType::VoidPointer, "*list".to_string())]
21 }
22
23 fn entrypoint(&self) -> String {
24 "tasmlib_list_new".to_string()
25 }
26
27 fn code(&self, library: &mut Library) -> Vec<LabelledInstruction> {
28 let dyn_malloc = library.import(Box::new(DynMalloc));
29
30 triton_asm!(
31 {self.entrypoint()}:
34 call {dyn_malloc}
35 push 0
39 pick 1
40 write_mem 1
41 addi -1
42 return
45 )
46 }
47}
48
49impl Function for New {
50 fn rust_shadow(
51 &self,
52 stack: &mut Vec<BFieldElement>,
53 memory: &mut HashMap<BFieldElement, BFieldElement>,
54 ) {
55 DynMalloc.rust_shadow(stack, memory);
56
57 let &list_pointer = stack.last().unwrap();
58 list_new(list_pointer, memory);
59 }
60
61 fn pseudorandom_initial_state(
62 &self,
63 _: [u8; 32],
64 _: Option<BenchmarkCase>,
65 ) -> FunctionInitialState {
66 FunctionInitialState {
67 stack: self.init_stack_for_isolated_run(),
68 ..Default::default()
69 }
70 }
71}
72
73#[cfg(test)]
74pub(crate) mod tests {
75 use super::*;
76 use crate::test_prelude::*;
77
78 #[test]
79 fn rust_shadow() {
80 ShadowedFunction::new(New).test();
81 }
82}
83
84#[cfg(test)]
85mod benches {
86 use super::*;
87 use crate::test_prelude::*;
88
89 #[test]
90 fn benchmark() {
91 ShadowedFunction::new(New).bench();
92 }
93}