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_decode::DecodeAsType;
27use scale_encode::EncodeAsType;
28use scale_info::{
29    TypeInfo,
30    scale::{Decode, Encode},
31};
32
33/// Status of the instrumentation.
34#[derive(
35    Clone, Copy, Debug, Decode, DecodeAsType, Encode, EncodeAsType, TypeInfo, PartialEq, Eq, Hash,
36)]
37pub enum InstrumentationStatus {
38    /// Code is not instrumented yet.
39    NotInstrumented,
40    /// Code is instrumented on weights version.
41    Instrumented {
42        /// Version of the instruction weights used for instrumentation.
43        version: u32,
44        /// Instrumented code length.
45        code_len: u32,
46    },
47    /// Failed to instrument code on weights version.
48    InstrumentationFailed {
49        /// Version of the instruction weights used for instrumentation.
50        version: u32,
51    },
52}
53
54/// Metadata for the code.
55#[derive(
56    Clone, Debug, Decode, DecodeAsType, Encode, EncodeAsType, TypeInfo, PartialEq, Eq, Hash,
57)]
58pub struct CodeMetadata {
59    /// Original code length.
60    original_code_len: u32,
61    /// Exports of the wasm module.
62    exports: BTreeSet<DispatchKind>,
63    // Static pages count from memory import.
64    static_pages: WasmPagesAmount,
65    /// Stack end page.
66    stack_end: Option<WasmPage>,
67    /// Instrumentation status, contains version of the instructions in case of instrumentation.
68    instrumentation_status: InstrumentationStatus,
69}
70
71impl CodeMetadata {
72    /// Creates a new instance of the code metadata.
73    pub fn new(
74        original_code_len: u32,
75        exports: BTreeSet<DispatchKind>,
76        static_pages: WasmPagesAmount,
77        stack_end: Option<WasmPage>,
78        instrumentation_status: InstrumentationStatus,
79    ) -> Self {
80        Self {
81            original_code_len,
82            exports,
83            static_pages,
84            stack_end,
85            instrumentation_status,
86        }
87    }
88
89    /// Converts the metadata into the failed instrumentation state.
90    pub fn into_failed_instrumentation(self, instruction_weights_version: u32) -> Self {
91        Self {
92            instrumentation_status: InstrumentationStatus::InstrumentationFailed {
93                version: instruction_weights_version,
94            },
95            ..self
96        }
97    }
98
99    /// Returns the original code length.
100    pub fn original_code_len(&self) -> u32 {
101        self.original_code_len
102    }
103
104    /// Returns the instrumented code length.
105    pub fn instrumented_code_len(&self) -> Option<u32> {
106        match self.instrumentation_status {
107            InstrumentationStatus::NotInstrumented
108            | InstrumentationStatus::InstrumentationFailed { .. } => None,
109            InstrumentationStatus::Instrumented { code_len, .. } => Some(code_len),
110        }
111    }
112
113    /// Returns the code exports.
114    pub fn exports(&self) -> &BTreeSet<DispatchKind> {
115        &self.exports
116    }
117
118    /// Returns the static pages count from memory import.
119    pub fn static_pages(&self) -> WasmPagesAmount {
120        self.static_pages
121    }
122
123    /// Returns the stack end page.
124    pub fn stack_end(&self) -> Option<WasmPage> {
125        self.stack_end
126    }
127
128    /// Returns the instrumentation status.
129    pub fn instrumentation_status(&self) -> InstrumentationStatus {
130        self.instrumentation_status
131    }
132
133    /// Returns the version of the instructions.
134    pub fn instruction_weights_version(&self) -> Option<u32> {
135        match self.instrumentation_status {
136            InstrumentationStatus::NotInstrumented => None,
137            InstrumentationStatus::Instrumented { version, .. } => Some(version),
138            InstrumentationStatus::InstrumentationFailed { version } => Some(version),
139        }
140    }
141}