gear_core/code/
metadata.rs

1// This file is part of Gear.
2
3// Copyright (C) 2021-2025 Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Module code metadata
20
21use crate::{
22    message::DispatchKind,
23    pages::{WasmPage, WasmPagesAmount},
24};
25use alloc::collections::BTreeSet;
26use scale_info::{
27    TypeInfo,
28    scale::{Decode, Encode},
29};
30
31/// Status of the instrumentation.
32#[derive(Clone, Copy, Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Hash)]
33pub enum InstrumentationStatus {
34    /// Code is not instrumented yet.
35    NotInstrumented,
36    /// Code is instrumented on weights version.
37    Instrumented {
38        /// Version of the instruction weights used for instrumentation.
39        version: u32,
40        /// Instrumented code length.
41        code_len: u32,
42    },
43    /// Failed to instrument code on weights version.
44    InstrumentationFailed {
45        /// Version of the instruction weights used for instrumentation.
46        version: u32,
47    },
48}
49
50/// Metadata for the code.
51#[derive(Clone, Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Hash)]
52pub struct CodeMetadata {
53    /// Original code length.
54    original_code_len: u32,
55    /// Exports of the wasm module.
56    exports: BTreeSet<DispatchKind>,
57    // Static pages count from memory import.
58    static_pages: WasmPagesAmount,
59    /// Stack end page.
60    stack_end: Option<WasmPage>,
61    /// Instrumentation status, contains version of the instructions in case of instrumentation.
62    instrumentation_status: InstrumentationStatus,
63}
64
65impl CodeMetadata {
66    /// Creates a new instance of the code metadata.
67    pub fn new(
68        original_code_len: u32,
69        exports: BTreeSet<DispatchKind>,
70        static_pages: WasmPagesAmount,
71        stack_end: Option<WasmPage>,
72        instrumentation_status: InstrumentationStatus,
73    ) -> Self {
74        Self {
75            original_code_len,
76            exports,
77            static_pages,
78            stack_end,
79            instrumentation_status,
80        }
81    }
82
83    /// Converts the metadata into the failed instrumentation state.
84    pub fn into_failed_instrumentation(self, instruction_weights_version: u32) -> Self {
85        Self {
86            instrumentation_status: InstrumentationStatus::InstrumentationFailed {
87                version: instruction_weights_version,
88            },
89            ..self
90        }
91    }
92
93    /// Returns the original code length.
94    pub fn original_code_len(&self) -> u32 {
95        self.original_code_len
96    }
97
98    /// Returns the instrumented code length.
99    pub fn instrumented_code_len(&self) -> Option<u32> {
100        match self.instrumentation_status {
101            InstrumentationStatus::NotInstrumented
102            | InstrumentationStatus::InstrumentationFailed { .. } => None,
103            InstrumentationStatus::Instrumented { code_len, .. } => Some(code_len),
104        }
105    }
106
107    /// Returns the code exports.
108    pub fn exports(&self) -> &BTreeSet<DispatchKind> {
109        &self.exports
110    }
111
112    /// Returns the static pages count from memory import.
113    pub fn static_pages(&self) -> WasmPagesAmount {
114        self.static_pages
115    }
116
117    /// Returns the stack end page.
118    pub fn stack_end(&self) -> Option<WasmPage> {
119        self.stack_end
120    }
121
122    /// Returns the instrumentation status.
123    pub fn instrumentation_status(&self) -> InstrumentationStatus {
124        self.instrumentation_status
125    }
126
127    /// Returns the version of the instructions.
128    pub fn instruction_weights_version(&self) -> Option<u32> {
129        match self.instrumentation_status {
130            InstrumentationStatus::NotInstrumented => None,
131            InstrumentationStatus::Instrumented { version, .. } => Some(version),
132            InstrumentationStatus::InstrumentationFailed { version } => Some(version),
133        }
134    }
135}