snarkvm_synthesizer/vm/helpers/
macros.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Copyright 2024 Aleo Network Foundation
// This file is part of the snarkVM library.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// A helper macro to downcast a `$variable` to `$object<$network>`.
#[macro_export]
macro_rules! cast_ref {
    // Example: cast_ref!((foo.bar()) as Bar<MainnetV0>)
    (($variable:expr) as $object:ident<$($traits:path),+>) => {{
        (&$variable as &dyn std::any::Any)
            .downcast_ref::<$object<$($traits),+>>()
            .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($variable)))?
    }};
    // Example: cast_ref!(bar as Bar<MainnetV0>)
    ($variable:ident as $object:ident<$($traits:path),+>) => {{
        (&$variable as &dyn std::any::Any)
            .downcast_ref::<$object<$($traits),+>>()
            .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($variable)))?
    }};
    // Example: cast_ref!(&bar as Bar<MainnetV0>)
    (&$variable:ident as $object:ident<$($traits:path),+>) => {{
        ($variable as &dyn std::any::Any)
            .downcast_ref::<$object<$($traits),+>>()
            .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($variable)))?
    }};
}

/// A helper macro to downcast a `$variable` to `&mut $object<$network>`.
#[macro_export]
macro_rules! cast_mut_ref {
    // Example: cast_mut_ref!((foo.bar()) as Bar<MainnetV0>)
    (($variable:expr) as $object:ident<$($traits:path),+>) => {{
        (&mut $variable as &mut dyn std::any::Any)
            .downcast_mut::<$object<$($traits),+>>()
            .ok_or_else(|| anyhow!("Failed to downcast mut {}", stringify!($variable)))?
    }};
    // Example: cast_mut_ref!(bar as Bar<MainnetV0>)
    ($variable:ident as $object:ident<$($traits:path),+>) => {{
        (&mut $variable as &mut dyn std::any::Any)
            .downcast_mut::<$object<$($traits),+>>()
            .ok_or_else(|| anyhow!("Failed to downcast mut {}", stringify!($variable)))?
    }};
}

/// A helper macro to dedup the `Network` trait and `Aleo` trait and process its given logic.
#[macro_export]
macro_rules! convert {
    // Example: convert!(logic)
    ($logic:ident) => {{
        match N::ID {
            console::network::MainnetV0::ID => {
                // Process the logic.
                $logic!(console::network::MainnetV0, circuit::AleoV0)
            }
            console::network::TestnetV0::ID => {
                // Process the logic.
                $logic!(console::network::TestnetV0, circuit::AleoTestnetV0)
            }
            console::network::CanaryV0::ID => {
                // Process the logic.
                $logic!(console::network::CanaryV0, circuit::AleoCanaryV0)
            }
            _ => bail!("Unsupported VM configuration for network: {}", N::ID),
        }
    }};
}

/// A helper macro to dedup the `Network` trait and `Aleo` trait and process its given logic.
#[macro_export]
macro_rules! process {
    // Example: process!(self, logic)
    ($self:ident, $logic:ident) => {{
        match N::ID {
            console::network::MainnetV0::ID => {
                // Cast the process.
                let process = (&$self.process as &dyn std::any::Any)
                    .downcast_ref::<Arc<RwLock<Process<console::network::MainnetV0>>>>()
                    .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($self.process)))?;
                // Process the logic.
                $logic!(process.read(), console::network::MainnetV0, circuit::AleoV0)
            }
            console::network::TestnetV0::ID => {
                // Cast the process.
                let process = (&$self.process as &dyn std::any::Any)
                    .downcast_ref::<Arc<RwLock<Process<console::network::TestnetV0>>>>()
                    .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($self.process)))?;
                // Process the logic.
                $logic!(process.read(), console::network::TestnetV0, circuit::AleoTestnetV0)
            }
            console::network::CanaryV0::ID => {
                // Cast the process.
                let process = (&$self.process as &dyn std::any::Any)
                    .downcast_ref::<Arc<RwLock<Process<console::network::CanaryV0>>>>()
                    .ok_or_else(|| anyhow!("Failed to downcast {}", stringify!($self.process)))?;
                // Process the logic.
                $logic!(process.read(), console::network::CanaryV0, circuit::AleoCanaryV0)
            }
            _ => bail!("Unsupported VM configuration for network: {}", N::ID),
        }
    }};
}