@@ -8,6 +8,7 @@ use inkwell::{builder::Builder, context::Context, module::Module};
88use owned_chars:: OwnedCharsExt ;
99use serde:: de:: DeserializeSeed ;
1010use std:: cell:: { Cell , RefCell } ;
11+ use std:: fmt:: { self , Debug , Formatter } ;
1112use std:: io:: { Read , Write } ;
1213use std:: mem:: MaybeUninit ;
1314use std:: pin:: Pin ;
@@ -286,11 +287,11 @@ impl<'src, 'ctx> CompCtx<'src, 'ctx> {
286287 }
287288 Some ( v)
288289 }
289- pub fn save < W : Write > ( & self , out : & mut W ) -> serde_cbor :: Result < ( ) > {
290- serde_cbor :: to_writer ( out , self )
290+ pub fn save < W : Write > ( & self , buf : & mut W ) -> serde_json :: Result < ( ) > {
291+ serde_json :: to_writer ( buf , self )
291292 }
292- pub fn load < R : Read > ( & self , buf : & mut R ) -> serde_cbor :: Result < Vec < String > > {
293- self . deserialize ( & mut serde_cbor :: Deserializer :: from_reader ( buf) )
293+ pub fn load < R : Read > ( & self , buf : & mut R ) -> serde_json :: Result < Vec < String > > {
294+ self . deserialize ( & mut serde_json :: Deserializer :: from_reader ( buf) )
294295 }
295296}
296297impl Drop for CompCtx < ' _ , ' _ > {
@@ -319,7 +320,9 @@ impl<'de, T, F: FnOnce(&mut dyn erased_serde::Deserializer) -> Result<T, erased_
319320 . map_err ( de:: Error :: custom)
320321 }
321322}
322-
323+ #[ derive( Debug , Clone , Copy , Serialize , Deserialize ) ]
324+ #[ serde( transparent) ]
325+ struct HexArray ( #[ serde( with = "hex::serde" ) ] [ u8 ; 8 ] ) ;
323326struct CtxTypeSerde < ' a , ' s , ' c > ( & ' a CompCtx < ' s , ' c > ) ;
324327impl Serialize for CtxTypeSerde < ' _ , ' _ , ' _ > {
325328 fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
@@ -330,7 +333,7 @@ impl Serialize for CtxTypeSerde<'_, '_, '_> {
330333 let tsr = TYPE_SERIAL_REGISTRY . pin ( ) ;
331334 let mut map = serializer. serialize_map ( Some ( tsr. len ( ) ) ) ?;
332335 for ( id, info) in & tsr {
333- map. serialize_entry ( id , & ( info. erased_header ) ( ) ) ?;
336+ map. serialize_entry ( & HexArray ( id . to_le_bytes ( ) ) , & ( info. erased_header ) ( ) ) ?;
334337 }
335338 map. end ( )
336339 }
@@ -345,8 +348,8 @@ impl<'de> de::Visitor<'de> for CtxTypeSerde<'_, '_, '_> {
345348 A : de:: MapAccess < ' de > ,
346349 {
347350 let tsr = TYPE_SERIAL_REGISTRY . pin ( ) ;
348- while let Some ( id) = map. next_key :: < u64 > ( ) ? {
349- let Some ( loader) = tsr. get ( & id ) else {
351+ while let Some ( id) = map. next_key :: < HexArray > ( ) ? {
352+ let Some ( loader) = tsr. get ( & u64 :: from_le_bytes ( id . 0 ) ) else {
350353 return Err ( de:: Error :: custom ( "unknown type ID {:0>16x}" ) ) ;
351354 } ;
352355 map. next_value_seed ( FnDeserializer ( loader. load_header ) ) ?;
@@ -371,10 +374,12 @@ impl Serialize for CompCtx<'_, '_> {
371374 use ser:: * ;
372375 #[ allow( clippy:: unnecessary_cast) ]
373376 SERIALIZATION_CONTEXT . with ( |c| {
374- if let Some ( ptr) = c. replace ( Some (
377+ if let Some ( ptr) = c. replace ( Some ( ContextPointer :: new (
375378 self as * const CompCtx < ' _ , ' _ > as * const CompCtx < ' static , ' static > , // this intermediate cast is necessary
376- ) ) {
377- panic ! ( "serialization context is already in use with an address of {ptr:p}" ) ;
379+ ) ) ) {
380+ if * ptr != ( self as * const CompCtx < ' _ , ' _ > as * const CompCtx < ' static , ' static > ) {
381+ panic ! ( "serialization context is already in use with an address of {ptr:#?}" ) ;
382+ }
378383 }
379384 } ) ;
380385 let mut map = serializer. serialize_struct ( "Context" , 3 ) ?;
@@ -406,10 +411,12 @@ impl<'de> DeserializeSeed<'de> for &CompCtx<'_, '_> {
406411 use de:: * ;
407412 #[ allow( clippy:: unnecessary_cast) ]
408413 SERIALIZATION_CONTEXT . with ( |c| {
409- if let Some ( ptr) = c. replace ( Some (
414+ if let Some ( ptr) = c. replace ( Some ( ContextPointer :: new (
410415 self as * const CompCtx < ' _ , ' _ > as * const CompCtx < ' static , ' static > , // this intermediate cast is necessary
411- ) ) {
412- panic ! ( "serialization context is already in use with an address of {ptr:p}" ) ;
416+ ) ) ) {
417+ if * ptr != ( self as * const CompCtx < ' _ , ' _ > as * const CompCtx < ' static , ' static > ) {
418+ panic ! ( "serialization context is already in use with an address of {ptr:#?}" ) ;
419+ }
413420 }
414421 } ) ;
415422 let proxy = ContextDeProxy :: deserialize ( deserializer) ?;
@@ -429,7 +436,57 @@ impl<'de> DeserializeSeed<'de> for &CompCtx<'_, '_> {
429436 Ok ( self . with_vars ( |v| varmap:: merge ( & mut v. symbols , vars. symbols ) ) )
430437 }
431438}
439+
440+ /// Wrapper around a context pointer, maybe with a backtace
441+ pub struct ContextPointer {
442+ ptr : * const CompCtx < ' static , ' static > ,
443+ #[ cfg( debug_assertions) ]
444+ trace : std:: backtrace:: Backtrace ,
445+ }
446+ impl ContextPointer {
447+ pub fn new ( ptr : * const CompCtx < ' static , ' static > ) -> Self {
448+ Self {
449+ trace : std:: backtrace:: Backtrace :: capture ( ) ,
450+ ptr,
451+ }
452+ }
453+ }
454+ impl std:: ops:: Deref for ContextPointer {
455+ type Target = * const CompCtx < ' static , ' static > ;
456+ fn deref ( & self ) -> & Self :: Target {
457+ & self . ptr
458+ }
459+ }
460+ impl Debug for ContextPointer {
461+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
462+ write ! ( f, "{:p}" , self . ptr) ?;
463+ #[ cfg( debug_assertions) ]
464+ {
465+ if f. alternate ( ) {
466+ if self . trace . status ( ) == std:: backtrace:: BacktraceStatus :: Captured {
467+ write ! ( f, "at: \n {}" , self . trace) ?;
468+ } else {
469+ f. write_str ( "without backtrace" ) ?;
470+ }
471+ }
472+ }
473+ Ok ( ( ) )
474+ }
475+ }
476+ /// Get the context pointer from a cell
477+ /// Super unsafe lmao
478+ ///
479+ /// # Safety
480+ /// `SERIALIZATION_CONTEXT`` must be valid
481+ pub unsafe fn get_ctx_ptr < ' a , ' s , ' c > ( cell : & Cell < Option < ContextPointer > > ) -> & ' a CompCtx < ' s , ' c > {
482+ let opt = cell. replace ( None ) ;
483+ let cp = opt. expect ( "expected pointer in serialization context" ) ;
484+ let ptr = cp. ptr ;
485+ cell. set ( Some ( cp) ) ;
486+ #[ allow( clippy:: unnecessary_cast) ]
487+ & * ( ptr as * const CompCtx < ' s , ' c > )
488+ }
432489thread_local ! {
433- /// CompCtx, should only have a value during deserialization
434- pub static SERIALIZATION_CONTEXT : Cell <Option <* const CompCtx < ' static , ' static > >> = const { Cell :: new( None ) } ;
490+ /// CompCtx, should only have a value during de/serialization
491+ pub static SERIALIZATION_CONTEXT : Cell <Option <ContextPointer >> = const { Cell :: new( None ) } ;
435492}
0 commit comments