fluence_sdk_main/
module_manifest.rs

1/*
2 * Copyright 2020 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// TODO: avoid duplication with the link_section when key-value attributes become stable
18pub const MANIFEST_SECTION_NAME: &str = "__fluence_wasm_module_manifest";
19
20#[macro_export]
21macro_rules! module_manifest {
22    ($authors:expr, $version:expr, $description:expr, $repository:expr) => {
23        fluence::internal::build_timestamp!();
24
25        const __M_SDK_AUTHORS_SIZE: usize = $authors.as_bytes().len();
26        const __M_SDK_VERSION_SIZE: usize = $version.as_bytes().len();
27        const __M_SDK_DESCRIPTION_SIZE: usize = $description.as_bytes().len();
28        const __M_SDK_REPOSITORY_SIZE: usize = $repository.as_bytes().len();
29        const __M_SDK_BUILD_TIME_SIZE: usize = __M_SDK_BUILD_TIME.as_bytes().len();
30        const __M_SDK_FIELD_PREFIX_SIZE: usize = std::mem::size_of::<u64>();
31
32        const __M_MANIFEST_SIZE: usize = __M_SDK_AUTHORS_SIZE
33            + __M_SDK_VERSION_SIZE
34            + __M_SDK_DESCRIPTION_SIZE
35            + __M_SDK_REPOSITORY_SIZE
36            + __M_SDK_BUILD_TIME_SIZE
37            + __M_SDK_FIELD_PREFIX_SIZE * 5;
38
39        const fn __m_sdk_append_data(
40            mut manifest: [u8; __M_MANIFEST_SIZE],
41            data: &'static str,
42            offset: usize,
43        ) -> ([u8; __M_MANIFEST_SIZE], usize) {
44            let data_as_bytes = data.as_bytes();
45            let data_len = data_as_bytes.len();
46
47            // write data prefix with data size in LE
48            let data_len_u64 = data_len as u64;
49            let data_len_le_bytes = data_len_u64.to_le_bytes();
50            let mut byte_idx = 0;
51            while byte_idx < __M_SDK_FIELD_PREFIX_SIZE {
52                manifest[offset + byte_idx] = data_len_le_bytes[byte_idx];
53                byte_idx += 1;
54            }
55
56            // write data
57            let mut byte_idx = 0;
58            while byte_idx < data_len {
59                manifest[__M_SDK_FIELD_PREFIX_SIZE + offset + byte_idx] = data_as_bytes[byte_idx];
60                byte_idx += 1;
61            }
62
63            (manifest, offset + __M_SDK_FIELD_PREFIX_SIZE + data_len)
64        }
65
66        const fn generate_manifest() -> [u8; __M_MANIFEST_SIZE] {
67            let manifest: [u8; __M_MANIFEST_SIZE] = [0; __M_MANIFEST_SIZE];
68
69            let offset = 0;
70            let (manifest, offset) = __m_sdk_append_data(manifest, $authors, offset);
71            let (manifest, offset) = __m_sdk_append_data(manifest, $version, offset);
72            let (manifest, offset) = __m_sdk_append_data(manifest, $description, offset);
73            let (manifest, offset) = __m_sdk_append_data(manifest, $repository, offset);
74            let (manifest, _) = __m_sdk_append_data(manifest, __M_SDK_BUILD_TIME, offset);
75
76            manifest
77        }
78
79        #[cfg(target_arch = "wasm32")]
80        #[link_section = "__fluence_wasm_module_manifest"]
81        #[doc(hidden)]
82        pub static __M_WASM_MODULE_MANIFEST: [u8; __M_MANIFEST_SIZE] = generate_manifest();
83    };
84
85    () => {
86        module_manifest!(
87            env!("CARGO_PKG_AUTHORS"),
88            env!("CARGO_PKG_VERSION"),
89            env!("CARGO_PKG_DESCRIPTION"),
90            env!("CARGO_PKG_REPOSITORY")
91        );
92    };
93}