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