Support std::io::Read natively by mapping it to and u8slice
[ldk-c-bindings] / lightning-c-bindings / src / c_types / mod.rs
1 //! This module contains standard C-mapped types for types not in the original crate.
2
3 /// Auto-generated C-mapped types for templated containers
4 pub mod derived;
5
6 use bitcoin::Transaction as BitcoinTransaction;
7 use bitcoin::hashes::Hash;
8 use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;
9 use bitcoin::secp256k1::key::SecretKey as SecpSecretKey;
10 use bitcoin::secp256k1::Signature as SecpSignature;
11 use bitcoin::secp256k1::Error as SecpError;
12 use bitcoin::secp256k1::recovery::RecoveryId;
13 use bitcoin::secp256k1::recovery::RecoverableSignature as SecpRecoverableSignature;
14 use bitcoin::bech32;
15
16 use std::convert::TryInto; // Bindings need at least rustc 1.34
17
18 use std::io::{Cursor, Read}; // TODO: We should use core2 here when we support no_std
19
20 /// Integer in the range `0..32`
21 #[derive(PartialEq, Eq, Copy, Clone)]
22 #[allow(non_camel_case_types)]
23 #[repr(C)]
24 pub struct u5(u8);
25
26 impl From<bech32::u5> for u5 {
27         fn from(o: bech32::u5) -> Self { Self(o.to_u8()) }
28 }
29 impl Into<bech32::u5> for u5 {
30         fn into(self) -> bech32::u5 { bech32::u5::try_from_u8(self.0).expect("u5 objects must be in the range 0..32") }
31 }
32
33 #[derive(Clone)]
34 #[repr(C)]
35 /// Represents a valid secp256k1 public key serialized in "compressed form" as a 33 byte array.
36 pub struct PublicKey {
37         /// The bytes of the public key
38         pub compressed_form: [u8; 33],
39 }
40 impl PublicKey {
41         pub(crate) fn from_rust(pk: &SecpPublicKey) -> Self {
42                 Self {
43                         compressed_form: pk.serialize(),
44                 }
45         }
46         pub(crate) fn into_rust(&self) -> SecpPublicKey {
47                 SecpPublicKey::from_slice(&self.compressed_form).unwrap()
48         }
49         pub(crate) fn is_null(&self) -> bool { self.compressed_form[..] == [0; 33][..] }
50         pub(crate) fn null() -> Self { Self { compressed_form: [0; 33] } }
51 }
52
53 #[repr(C)]
54 /// Represents a valid secp256k1 secret key serialized as a 32 byte array.
55 pub struct SecretKey {
56         /// The bytes of the secret key
57         pub bytes: [u8; 32],
58 }
59 impl SecretKey {
60         // from_rust isn't implemented for a ref since we just return byte array refs directly
61         pub(crate) fn from_rust(sk: SecpSecretKey) -> Self {
62                 let mut bytes = [0; 32];
63                 bytes.copy_from_slice(&sk[..]);
64                 Self { bytes }
65         }
66         pub(crate) fn into_rust(&self) -> SecpSecretKey {
67                 SecpSecretKey::from_slice(&self.bytes).unwrap()
68         }
69 }
70
71 #[repr(C)]
72 #[derive(Clone)]
73 /// Represents a secp256k1 signature serialized as two 32-byte numbers
74 pub struct Signature {
75         /// The bytes of the signature in "compact" form
76         pub compact_form: [u8; 64],
77 }
78 impl Signature {
79         pub(crate) fn from_rust(pk: &SecpSignature) -> Self {
80                 Self {
81                         compact_form: pk.serialize_compact(),
82                 }
83         }
84         pub(crate) fn into_rust(&self) -> SecpSignature {
85                 SecpSignature::from_compact(&self.compact_form).unwrap()
86         }
87         // The following are used for Option<Signature> which we support, but don't use anymore
88         #[allow(unused)] pub(crate) fn is_null(&self) -> bool { self.compact_form[..] == [0; 64][..] }
89         #[allow(unused)] pub(crate) fn null() -> Self { Self { compact_form: [0; 64] } }
90 }
91
92 #[repr(C)]
93 #[derive(Clone)]
94 /// Represents a secp256k1 signature serialized as two 32-byte numbers as well as a tag which
95 /// allows recovering the exact public key which created the signature given the message.
96 pub struct RecoverableSignature {
97         /// The bytes of the signature in "compact" form plus a "Recovery ID" which allows for
98         /// recovery.
99         pub serialized_form: [u8; 68],
100 }
101 impl RecoverableSignature {
102         pub(crate) fn from_rust(pk: &SecpRecoverableSignature) -> Self {
103                 let (id, compact_form) = pk.serialize_compact();
104                 let mut serialized_form = [0; 68];
105                 serialized_form[0..64].copy_from_slice(&compact_form[..]);
106                 serialized_form[64..].copy_from_slice(&id.to_i32().to_le_bytes());
107                 Self { serialized_form }
108         }
109         pub(crate) fn into_rust(&self) -> SecpRecoverableSignature {
110                 let mut id = [0; 4];
111                 id.copy_from_slice(&self.serialized_form[64..]);
112                 SecpRecoverableSignature::from_compact(&self.serialized_form[0..64],
113                                 RecoveryId::from_i32(i32::from_le_bytes(id)).expect("Invalid Recovery ID"))
114                         .unwrap()
115         }
116 }
117
118 #[repr(C)]
119 #[derive(Copy, Clone)]
120 /// Represents an error returned from libsecp256k1 during validation of some secp256k1 data
121 pub enum Secp256k1Error {
122         /// Signature failed verification
123         IncorrectSignature,
124         /// Badly sized message ("messages" are actually fixed-sized digests; see the MESSAGE_SIZE constant)
125         InvalidMessage,
126         /// Bad public key
127         InvalidPublicKey,
128         /// Bad signature
129         InvalidSignature,
130         /// Bad secret key
131         InvalidSecretKey,
132         /// Bad recovery id
133         InvalidRecoveryId,
134         /// Invalid tweak for add_assign or mul_assign
135         InvalidTweak,
136         /// tweak_add_check failed on an xonly public key
137         TweakCheckFailed,
138         /// Didn't pass enough memory to context creation with preallocated memory
139         NotEnoughMemory,
140 }
141 impl Secp256k1Error {
142         pub(crate) fn from_rust(err: SecpError) -> Self {
143                 match err {
144                         SecpError::IncorrectSignature => Secp256k1Error::IncorrectSignature,
145                         SecpError::InvalidMessage => Secp256k1Error::InvalidMessage,
146                         SecpError::InvalidPublicKey => Secp256k1Error::InvalidPublicKey,
147                         SecpError::InvalidSignature => Secp256k1Error::InvalidSignature,
148                         SecpError::InvalidSecretKey => Secp256k1Error::InvalidSecretKey,
149                         SecpError::InvalidRecoveryId => Secp256k1Error::InvalidRecoveryId,
150                         SecpError::InvalidTweak => Secp256k1Error::InvalidTweak,
151                         SecpError::TweakCheckFailed => Secp256k1Error::TweakCheckFailed,
152                         SecpError::NotEnoughMemory => Secp256k1Error::NotEnoughMemory,
153                 }
154         }
155 }
156
157 #[repr(C)]
158 #[allow(missing_docs)] // If there's no docs upstream, that's good enough for us
159 #[derive(Clone, Copy, PartialEq)]
160 /// Represents an IO Error. Note that some information is lost in the conversion from Rust.
161 pub enum IOError {
162         NotFound,
163         PermissionDenied,
164         ConnectionRefused,
165         ConnectionReset,
166         ConnectionAborted,
167         NotConnected,
168         AddrInUse,
169         AddrNotAvailable,
170         BrokenPipe,
171         AlreadyExists,
172         WouldBlock,
173         InvalidInput,
174         InvalidData,
175         TimedOut,
176         WriteZero,
177         Interrupted,
178         Other,
179         UnexpectedEof,
180 }
181 impl IOError {
182         pub(crate) fn from_rust(err: std::io::Error) -> Self {
183                 match err.kind() {
184                         std::io::ErrorKind::NotFound => IOError::NotFound,
185                         std::io::ErrorKind::PermissionDenied => IOError::PermissionDenied,
186                         std::io::ErrorKind::ConnectionRefused => IOError::ConnectionRefused,
187                         std::io::ErrorKind::ConnectionReset => IOError::ConnectionReset,
188                         std::io::ErrorKind::ConnectionAborted => IOError::ConnectionAborted,
189                         std::io::ErrorKind::NotConnected => IOError::NotConnected,
190                         std::io::ErrorKind::AddrInUse => IOError::AddrInUse,
191                         std::io::ErrorKind::AddrNotAvailable => IOError::AddrNotAvailable,
192                         std::io::ErrorKind::BrokenPipe => IOError::BrokenPipe,
193                         std::io::ErrorKind::AlreadyExists => IOError::AlreadyExists,
194                         std::io::ErrorKind::WouldBlock => IOError::WouldBlock,
195                         std::io::ErrorKind::InvalidInput => IOError::InvalidInput,
196                         std::io::ErrorKind::InvalidData => IOError::InvalidData,
197                         std::io::ErrorKind::TimedOut => IOError::TimedOut,
198                         std::io::ErrorKind::WriteZero => IOError::WriteZero,
199                         std::io::ErrorKind::Interrupted => IOError::Interrupted,
200                         std::io::ErrorKind::Other => IOError::Other,
201                         std::io::ErrorKind::UnexpectedEof => IOError::UnexpectedEof,
202                         _ => IOError::Other,
203                 }
204         }
205         pub(crate) fn to_rust(&self) -> std::io::Error {
206                 std::io::Error::new(match self {
207                         IOError::NotFound => std::io::ErrorKind::NotFound,
208                         IOError::PermissionDenied => std::io::ErrorKind::PermissionDenied,
209                         IOError::ConnectionRefused => std::io::ErrorKind::ConnectionRefused,
210                         IOError::ConnectionReset => std::io::ErrorKind::ConnectionReset,
211                         IOError::ConnectionAborted => std::io::ErrorKind::ConnectionAborted,
212                         IOError::NotConnected => std::io::ErrorKind::NotConnected,
213                         IOError::AddrInUse => std::io::ErrorKind::AddrInUse,
214                         IOError::AddrNotAvailable => std::io::ErrorKind::AddrNotAvailable,
215                         IOError::BrokenPipe => std::io::ErrorKind::BrokenPipe,
216                         IOError::AlreadyExists => std::io::ErrorKind::AlreadyExists,
217                         IOError::WouldBlock => std::io::ErrorKind::WouldBlock,
218                         IOError::InvalidInput => std::io::ErrorKind::InvalidInput,
219                         IOError::InvalidData => std::io::ErrorKind::InvalidData,
220                         IOError::TimedOut => std::io::ErrorKind::TimedOut,
221                         IOError::WriteZero => std::io::ErrorKind::WriteZero,
222                         IOError::Interrupted => std::io::ErrorKind::Interrupted,
223                         IOError::Other => std::io::ErrorKind::Other,
224                         IOError::UnexpectedEof => std::io::ErrorKind::UnexpectedEof,
225                 }, "")
226         }
227 }
228
229 #[repr(C)]
230 /// A serialized transaction, in (pointer, length) form.
231 ///
232 /// This type optionally owns its own memory, and thus the semantics around access change based on
233 /// the `data_is_owned` flag. If `data_is_owned` is set, you must call `Transaction_free` to free
234 /// the underlying buffer before the object goes out of scope. If `data_is_owned` is not set, any
235 /// access to the buffer after the scope in which the object was provided to you is invalid. eg,
236 /// access after you return from the call in which a `!data_is_owned` `Transaction` is provided to
237 /// you would be invalid.
238 ///
239 /// Note that, while it may change in the future, because transactions on the Rust side are stored
240 /// in a deserialized form, all `Transaction`s generated on the Rust side will have `data_is_owned`
241 /// set. Similarly, while it may change in the future, all `Transaction`s you pass to Rust may have
242 /// `data_is_owned` either set or unset at your discretion.
243 pub struct Transaction {
244         /// The serialized transaction data.
245         ///
246         /// This is non-const for your convenience, an object passed to Rust is never written to.
247         pub data: *mut u8,
248         /// The length of the serialized transaction
249         pub datalen: usize,
250         /// Whether the data pointed to by `data` should be freed or not.
251         pub data_is_owned: bool,
252 }
253 impl Transaction {
254         fn from_vec(vec: Vec<u8>) -> Self {
255                 let datalen = vec.len();
256                 let data = Box::into_raw(vec.into_boxed_slice());
257                 Self {
258                         data: unsafe { (*data).as_mut_ptr() },
259                         datalen,
260                         data_is_owned: true,
261                 }
262         }
263         pub(crate) fn into_bitcoin(&self) -> BitcoinTransaction {
264                 if self.datalen == 0 { panic!("0-length buffer can never represent a valid Transaction"); }
265                 ::bitcoin::consensus::encode::deserialize(unsafe { std::slice::from_raw_parts(self.data, self.datalen) }).unwrap()
266         }
267         pub(crate) fn from_bitcoin(btc: &BitcoinTransaction) -> Self {
268                 let vec = ::bitcoin::consensus::encode::serialize(btc);
269                 Self::from_vec(vec)
270         }
271 }
272 impl Drop for Transaction {
273         fn drop(&mut self) {
274                 if self.data_is_owned && self.datalen != 0 {
275                         let _ = derived::CVec_u8Z { data: self.data as *mut u8, datalen: self.datalen };
276                 }
277         }
278 }
279 impl Clone for Transaction {
280         fn clone(&self) -> Self {
281                 let sl = unsafe { std::slice::from_raw_parts(self.data, self.datalen) };
282                 let mut v = Vec::new();
283                 v.extend_from_slice(&sl);
284                 Self::from_vec(v)
285         }
286 }
287 #[no_mangle]
288 /// Frees the data buffer, if data_is_owned is set and datalen > 0.
289 pub extern "C" fn Transaction_free(_res: Transaction) { }
290
291 pub(crate) fn bitcoin_to_C_outpoint(outpoint: ::bitcoin::blockdata::transaction::OutPoint) -> crate::lightning::chain::transaction::OutPoint {
292         crate::lightning::chain::transaction::OutPoint_new(ThirtyTwoBytes { data: outpoint.txid.into_inner() }, outpoint.vout.try_into().unwrap())
293 }
294 pub(crate) fn C_to_bitcoin_outpoint(outpoint: crate::lightning::chain::transaction::OutPoint) -> ::bitcoin::blockdata::transaction::OutPoint {
295         unsafe {
296                 ::bitcoin::blockdata::transaction::OutPoint {
297                         txid: (*outpoint.inner).txid, vout: (*outpoint.inner).index as u32
298                 }
299         }
300 }
301
302 #[repr(C)]
303 #[derive(Clone)]
304 /// A transaction output including a scriptPubKey and value.
305 /// This type *does* own its own memory, so must be free'd appropriately.
306 pub struct TxOut {
307         /// The script_pubkey in this output
308         pub script_pubkey: derived::CVec_u8Z,
309         /// The value, in satoshis, of this output
310         pub value: u64,
311 }
312
313 impl TxOut {
314         pub(crate) fn into_rust(mut self) -> ::bitcoin::blockdata::transaction::TxOut {
315                 ::bitcoin::blockdata::transaction::TxOut {
316                         script_pubkey: self.script_pubkey.into_rust().into(),
317                         value: self.value,
318                 }
319         }
320         pub(crate) fn from_rust(txout: ::bitcoin::blockdata::transaction::TxOut) -> Self {
321                 Self {
322                         script_pubkey: derived::CVec_u8Z::from(txout.script_pubkey.into_bytes()),
323                         value: txout.value
324                 }
325         }
326 }
327
328 #[no_mangle]
329 /// Convenience function for constructing a new TxOut
330 pub extern "C" fn TxOut_new(script_pubkey: derived::CVec_u8Z, value: u64) -> TxOut {
331         TxOut { script_pubkey, value }
332 }
333 #[no_mangle]
334 /// Frees the data pointed to by script_pubkey.
335 pub extern "C" fn TxOut_free(_res: TxOut) { }
336 #[no_mangle]
337 /// Creates a new TxOut which has the same data as `orig` but with a new script buffer.
338 pub extern "C" fn TxOut_clone(orig: &TxOut) -> TxOut { orig.clone() }
339
340 #[repr(C)]
341 /// A "slice" referencing some byte array. This is simply a length-tagged pointer which does not
342 /// own the memory pointed to by data.
343 pub struct u8slice {
344         /// A pointer to the byte buffer
345         pub data: *const u8,
346         /// The number of bytes pointed to by `data`.
347         pub datalen: usize
348 }
349 impl u8slice {
350         pub(crate) fn from_slice(s: &[u8]) -> Self {
351                 Self {
352                         data: s.as_ptr(),
353                         datalen: s.len(),
354                 }
355         }
356         pub(crate) fn to_slice(&self) -> &[u8] {
357                 if self.datalen == 0 { return &[]; }
358                 unsafe { std::slice::from_raw_parts(self.data, self.datalen) }
359         }
360         pub(crate) fn to_reader<'a>(&'a self) -> Cursor<&'a [u8]> {
361                 let sl = self.to_slice();
362                 Cursor::new(sl)
363         }
364         pub(crate) fn from_vec(v: &derived::CVec_u8Z) -> u8slice {
365                 Self::from_slice(v.as_slice())
366         }
367 }
368 pub(crate) fn reader_to_vec<R: Read>(r: &mut R) -> derived::CVec_u8Z {
369         let mut res = Vec::new();
370         r.read_to_end(&mut res).unwrap();
371         derived::CVec_u8Z::from(res)
372 }
373
374 #[repr(C)]
375 #[derive(Copy, Clone)]
376 /// Arbitrary 32 bytes, which could represent one of a few different things. You probably want to
377 /// look up the corresponding function in rust-lightning's docs.
378 pub struct ThirtyTwoBytes {
379         /// The thirty-two bytes
380         pub data: [u8; 32],
381 }
382 impl ThirtyTwoBytes {
383         pub(crate) fn null() -> Self {
384                 Self { data: [0; 32] }
385         }
386 }
387
388 #[repr(C)]
389 /// A 3-byte byte array.
390 pub struct ThreeBytes { /** The three bytes */ pub data: [u8; 3], }
391 #[derive(Clone)]
392 #[repr(C)]
393 /// A 4-byte byte array.
394 pub struct FourBytes { /** The four bytes */ pub data: [u8; 4], }
395 #[derive(Clone)]
396 #[repr(C)]
397 /// A 10-byte byte array.
398 pub struct TenBytes { /** The ten bytes */ pub data: [u8; 10], }
399 #[derive(Clone)]
400 #[repr(C)]
401 /// A 16-byte byte array.
402 pub struct SixteenBytes { /** The sixteen bytes */ pub data: [u8; 16], }
403 #[derive(Clone)]
404 #[repr(C)]
405 /// A 20-byte byte array.
406 pub struct TwentyBytes { /** The twenty bytes */ pub data: [u8; 20], }
407
408 pub(crate) struct VecWriter(pub Vec<u8>);
409 impl lightning::util::ser::Writer for VecWriter {
410         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
411                 self.0.extend_from_slice(buf);
412                 Ok(())
413         }
414 }
415 pub(crate) fn serialize_obj<I: lightning::util::ser::Writeable>(i: &I) -> derived::CVec_u8Z {
416         let mut out = VecWriter(Vec::new());
417         i.write(&mut out).unwrap();
418         derived::CVec_u8Z::from(out.0)
419 }
420 pub(crate) fn deserialize_obj<I: lightning::util::ser::Readable>(s: u8slice) -> Result<I, lightning::ln::msgs::DecodeError> {
421         I::read(&mut s.to_slice())
422 }
423 pub(crate) fn deserialize_obj_arg<A, I: lightning::util::ser::ReadableArgs<A>>(s: u8slice, args: A) -> Result<I, lightning::ln::msgs::DecodeError> {
424         I::read(&mut s.to_slice(), args)
425 }
426
427 #[repr(C)]
428 #[derive(Clone)]
429 /// A Rust str object, ie a reference to a UTF8-valid string.
430 /// This is *not* null-terminated so cannot be used directly as a C string!
431 pub struct Str {
432         /// A pointer to the string's bytes, in UTF8 encoding
433         pub chars: *const u8,
434         /// The number of bytes (not characters!) pointed to by `chars`
435         pub len: usize,
436         /// Whether the data pointed to by `chars` should be freed or not.
437         pub chars_is_owned: bool,
438 }
439 impl Into<Str> for &'static str {
440         fn into(self) -> Str {
441                 Str { chars: self.as_ptr(), len: self.len(), chars_is_owned: false }
442         }
443 }
444 impl Str {
445         pub(crate) fn into_str(&self) -> &'static str {
446                 if self.len == 0 { return ""; }
447                 std::str::from_utf8(unsafe { std::slice::from_raw_parts(self.chars, self.len) }).unwrap()
448         }
449         pub(crate) fn into_string(mut self) -> String {
450                 let bytes = if self.len == 0 {
451                         Vec::new()
452                 } else if self.chars_is_owned {
453                         let ret = unsafe {
454                                 Box::from_raw(std::slice::from_raw_parts_mut(unsafe { self.chars as *mut u8 }, self.len))
455                         }.into();
456                         self.chars_is_owned = false;
457                         ret
458                 } else {
459                         let mut ret = Vec::with_capacity(self.len);
460                         ret.extend_from_slice(unsafe { std::slice::from_raw_parts(self.chars, self.len) });
461                         ret
462                 };
463                 String::from_utf8(bytes).unwrap()
464         }
465 }
466 impl Into<Str> for String {
467         fn into(self) -> Str {
468                 let s = Box::leak(self.into_boxed_str());
469                 Str { chars: s.as_ptr(), len: s.len(), chars_is_owned: true }
470         }
471 }
472
473 impl Drop for Str {
474         fn drop(&mut self) {
475                 if self.chars_is_owned && self.len != 0 {
476                         let _ = derived::CVec_u8Z { data: self.chars as *mut u8, datalen: self.len };
477                 }
478         }
479 }
480 #[no_mangle]
481 /// Frees the data buffer, if chars_is_owned is set and len > 0.
482 pub extern "C" fn Str_free(_res: Str) { }
483
484 // Note that the C++ headers memset(0) all the Templ types to avoid deallocation!
485 // Thus, they must gracefully handle being completely null in _free.
486
487 // TODO: Integer/bool primitives should avoid the pointer indirection for underlying types
488 // everywhere in the containers.
489
490 #[repr(C)]
491 pub(crate) union CResultPtr<O, E> {
492         pub(crate) result: *mut O,
493         pub(crate) err: *mut E,
494 }
495 #[repr(C)]
496 pub(crate) struct CResultTempl<O, E> {
497         pub(crate) contents: CResultPtr<O, E>,
498         pub(crate) result_ok: bool,
499 }
500 impl<O, E> CResultTempl<O, E> {
501         pub(crate) extern "C" fn ok(o: O) -> Self {
502                 CResultTempl {
503                         contents: CResultPtr {
504                                 result: Box::into_raw(Box::new(o)),
505                         },
506                         result_ok: true,
507                 }
508         }
509         pub(crate) extern "C" fn err(e: E) -> Self {
510                 CResultTempl {
511                         contents: CResultPtr {
512                                 err: Box::into_raw(Box::new(e)),
513                         },
514                         result_ok: false,
515                 }
516         }
517 }
518 impl<O, E> Drop for CResultTempl<O, E> {
519         fn drop(&mut self) {
520                 if self.result_ok {
521                         if unsafe { !self.contents.result.is_null() } {
522                                 unsafe { Box::from_raw(self.contents.result) };
523                         }
524                 } else if unsafe { !self.contents.err.is_null() } {
525                         unsafe { Box::from_raw(self.contents.err) };
526                 }
527         }
528 }
529
530 /// Utility to make it easy to set a pointer to null and get its original value in line.
531 pub(crate) trait TakePointer<T> {
532         fn take_ptr(&mut self) -> T;
533 }
534 impl<T> TakePointer<*const T> for *const T {
535         fn take_ptr(&mut self) -> *const T {
536                 let ret = *self;
537                 *self = std::ptr::null();
538                 ret
539         }
540 }
541 impl<T> TakePointer<*mut T> for *mut T {
542         fn take_ptr(&mut self) -> *mut T {
543                 let ret = *self;
544                 *self = std::ptr::null_mut();
545                 ret
546         }
547 }
548
549
550 pub(crate) mod ObjOps {
551         #[inline]
552         #[must_use = "returns new dangling pointer"]
553         pub(crate) fn heap_alloc<T>(obj: T) -> *mut T {
554                 let ptr = Box::into_raw(Box::new(obj));
555                 nonnull_ptr_to_inner(ptr)
556         }
557         #[inline]
558         pub(crate) fn nonnull_ptr_to_inner<T>(ptr: *const T) -> *mut T {
559                 if core::mem::size_of::<T>() == 0 {
560                         // We map `None::<T>` as `T { inner: null, .. }` which works great for all
561                         // non-Zero-Sized-Types `T`.
562                         // For ZSTs, we need to differentiate between null implying `None` and null implying
563                         // `Some` with no allocation.
564                         // Thus, for ZSTs, we add one (usually) page here, which should always be aligned.
565                         // Note that this relies on undefined behavior! A pointer to NULL may be valid, but a
566                         // pointer to NULL + 4096 is almost certainly not. That said, Rust's existing use of
567                         // `(*mut T)1` for the pointer we're adding to is also not defined, so we should be
568                         // fine.
569                         // Note that we add 4095 here as at least the Java client assumes that the low bit on
570                         // any heap pointer is 0, which is generally provided by malloc, but which is not true
571                         // for ZSTs "allocated" by `Box::new`.
572                         debug_assert_eq!(ptr as usize, 1);
573                         unsafe { (ptr as *mut T).cast::<u8>().add(4096 - 1).cast::<T>() }
574                 } else {
575                         // In order to get better test coverage, also increment non-ZST pointers with
576                         // --cfg=test_mod_pointers, which is set in genbindings.sh for debug builds.
577                         #[cfg(test_mod_pointers)]
578                         unsafe { (ptr as *mut T).cast::<u8>().add(4096).cast::<T>() }
579                         #[cfg(not(test_mod_pointers))]
580                         unsafe { ptr as *mut T }
581                 }
582         }
583         #[inline]
584         /// Invert nonnull_ptr_to_inner
585         pub(crate) fn untweak_ptr<T>(ptr: *mut T) -> *mut T {
586                 if core::mem::size_of::<T>() == 0 {
587                         unsafe { ptr.cast::<u8>().sub(4096 - 1).cast::<T>() }
588                 } else {
589                         #[cfg(test_mod_pointers)]
590                         unsafe { ptr.cast::<u8>().sub(4096).cast::<T>() }
591                         #[cfg(not(test_mod_pointers))]
592                         ptr
593                 }
594         }
595 }