Skip to content

Commit 667ce2e

Browse files
committed
Hack: Copy metadata module to avoid uniffi_core dependency
In m-c we're running into linking issues in `uniffi_macros`, where it's missing symbols coming from `uniffi_core`: /bin/ld: uniffi_foreign_executor_callback_set: undefined version: /bin/ld: failed to set dynamic section sizes: bad value That's most likely this issue on Rust: rust-lang/rust#111888 It's called out that this likely actually broke because of another PR: rust-lang/rust#99944 Despite this bug there's a bit of an issue in UniFFI to begin with: We're exporting `extern "C"` functions from a crate that is a dependency of some other crates, including `uniffi_macros`, and thus the symbols land in a part where they are not needed. However for `uniffi_meta` in particular we don't need much from `uniffi_core`, so for now we just copy the necessary bits to get it all working.
1 parent c0e64b8 commit 667ce2e

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

uniffi_meta/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,3 @@ bytes = "1.3"
1414
serde = { version = "1.0.136", features = ["derive"] }
1515
siphasher = "0.3"
1616
uniffi_checksum_derive = { version = "0.24.1", path = "../uniffi_checksum_derive" }
17-
uniffi_core = { path = "../uniffi_core", version = "=0.24.1" }

uniffi_meta/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub use group::{group_metadata, MetadataGroup};
1616
mod reader;
1717
pub use reader::{read_metadata, read_metadata_type};
1818

19+
mod metadata;
20+
1921
/// Similar to std::hash::Hash.
2022
///
2123
/// Implementations of this trait are expected to update the hasher state in

uniffi_meta/src/metadata.rs

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
// Copied from uniffi_core/src/metadata.rs
6+
// Due to a [Rust bug](https://github.com/rust-lang/rust/issues/113104) we don't want to pull in
7+
// `uniffi_core`.
8+
// This is the easy way out of that issue and is a temporary hacky solution.
9+
10+
/// Metadata constants, make sure to keep this in sync with copy in `uniffi_meta::reader`
11+
pub mod codes {
12+
// Top-level metadata item codes
13+
pub const FUNC: u8 = 0;
14+
pub const METHOD: u8 = 1;
15+
pub const RECORD: u8 = 2;
16+
pub const ENUM: u8 = 3;
17+
pub const INTERFACE: u8 = 4;
18+
pub const ERROR: u8 = 5;
19+
pub const NAMESPACE: u8 = 6;
20+
pub const CONSTRUCTOR: u8 = 7;
21+
pub const UDL_FILE: u8 = 8;
22+
pub const CALLBACK_INTERFACE: u8 = 9;
23+
pub const TRAIT_METHOD: u8 = 10;
24+
//pub const UNKNOWN: u8 = 255;
25+
26+
// Type codes
27+
pub const TYPE_U8: u8 = 0;
28+
pub const TYPE_U16: u8 = 1;
29+
pub const TYPE_U32: u8 = 2;
30+
pub const TYPE_U64: u8 = 3;
31+
pub const TYPE_I8: u8 = 4;
32+
pub const TYPE_I16: u8 = 5;
33+
pub const TYPE_I32: u8 = 6;
34+
pub const TYPE_I64: u8 = 7;
35+
pub const TYPE_F32: u8 = 8;
36+
pub const TYPE_F64: u8 = 9;
37+
pub const TYPE_BOOL: u8 = 10;
38+
pub const TYPE_STRING: u8 = 11;
39+
pub const TYPE_OPTION: u8 = 12;
40+
pub const TYPE_RECORD: u8 = 13;
41+
pub const TYPE_ENUM: u8 = 14;
42+
// 15 no longer used.
43+
pub const TYPE_INTERFACE: u8 = 16;
44+
pub const TYPE_VEC: u8 = 17;
45+
pub const TYPE_HASH_MAP: u8 = 18;
46+
pub const TYPE_SYSTEM_TIME: u8 = 19;
47+
pub const TYPE_DURATION: u8 = 20;
48+
pub const TYPE_CALLBACK_INTERFACE: u8 = 21;
49+
pub const TYPE_CUSTOM: u8 = 22;
50+
pub const TYPE_RESULT: u8 = 23;
51+
//pub const TYPE_FUTURE: u8 = 24;
52+
pub const TYPE_FOREIGN_EXECUTOR: u8 = 25;
53+
pub const TYPE_UNIT: u8 = 255;
54+
55+
// Literal codes
56+
pub const LIT_STR: u8 = 0;
57+
pub const LIT_INT: u8 = 1;
58+
pub const LIT_FLOAT: u8 = 2;
59+
pub const LIT_BOOL: u8 = 3;
60+
}
61+
62+
// Create a checksum for a MetadataBuffer
63+
//
64+
// This is used by the bindings code to verify that the library they link to is the same one
65+
// that the bindings were generated from.
66+
pub const fn checksum_metadata(buf: &[u8]) -> u16 {
67+
calc_checksum(buf, buf.len())
68+
}
69+
70+
const fn calc_checksum(bytes: &[u8], size: usize) -> u16 {
71+
// Taken from the fnv_hash() function from the FNV crate (https://github.com/servo/rust-fnv/blob/master/lib.rs).
72+
// fnv_hash() hasn't been released in a version yet.
73+
const INITIAL_STATE: u64 = 0xcbf29ce484222325;
74+
const PRIME: u64 = 0x100000001b3;
75+
76+
let mut hash = INITIAL_STATE;
77+
let mut i = 0;
78+
while i < size {
79+
hash ^= bytes[i] as u64;
80+
hash = hash.wrapping_mul(PRIME);
81+
i += 1;
82+
}
83+
// Convert the 64-bit hash to a 16-bit hash by XORing everything together
84+
(hash ^ (hash >> 16) ^ (hash >> 32) ^ (hash >> 48)) as u16
85+
}

uniffi_meta/src/reader.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5+
use crate::metadata::{checksum_metadata, codes};
56
use crate::*;
67
use anyhow::{bail, Context, Result};
7-
use uniffi_core::metadata::{checksum_metadata, codes};
88

99
pub fn read_metadata(data: &[u8]) -> Result<Metadata> {
1010
MetadataReader::new(data).read_metadata()

0 commit comments

Comments
 (0)