@@ -5,8 +5,8 @@ use std::ptr::NonNull;
5
5
use std:: marker:: PhantomData ;
6
6
use std:: sync:: atomic:: { self , AtomicPtr , AtomicUsize , Ordering } ;
7
7
8
- use zerogc:: { Trace , GcSafe , GcBindHandle , GcBrand , GcVisitor , NullTrace , TraceImmutable } ;
9
- use crate :: { DynTrace , GcType , Gc , SimpleCollectorContext , SimpleCollector , MarkVisitor , GcHeader , MarkState , WeakCollectorRef } ;
8
+ use zerogc:: { Trace , GcSafe , GcBrand , GcVisitor , NullTrace , TraceImmutable , GcHandleSystem , GcBindHandle } ;
9
+ use crate :: { DynTrace , GcType , Gc , SimpleCollector , MarkVisitor , GcHeader , MarkState , WeakCollectorRef , CollectorId , SimpleCollectorContext , RawSimpleCollector } ;
10
10
11
11
const INITIAL_HANDLE_CAPACITY : usize = 128 ;
12
12
@@ -370,7 +370,9 @@ impl<T: GcSafe> GcHandle<T> {
370
370
}
371
371
}
372
372
unsafe impl < T : GcSafe > :: zerogc:: GcHandle < T > for GcHandle < T > {
373
- type Context = SimpleCollectorContext ;
373
+ type System = SimpleCollector ;
374
+ type Id = CollectorId ;
375
+
374
376
#[ cfg( feature = "sync" ) ]
375
377
fn use_critical < R > ( & self , func : impl FnOnce ( & T ) -> R ) -> R {
376
378
self . collector . ensure_valid ( |collector| unsafe {
@@ -396,12 +398,10 @@ unsafe impl<T: GcSafe> ::zerogc::GcHandle<T> for GcHandle<T> {
396
398
}
397
399
}
398
400
unsafe impl < ' new_gc , T > GcBindHandle < ' new_gc , T > for GcHandle < T >
399
- where T : GcSafe , T : GcBrand < ' new_gc , SimpleCollector > ,
401
+ where T : GcSafe , T : GcBrand < ' new_gc , CollectorId > ,
400
402
T :: Branded : GcSafe {
401
- type System = SimpleCollector ;
402
- type Bound = Gc < ' new_gc , T :: Branded > ;
403
403
#[ inline]
404
- fn bind_to ( & self , _context : & ' new_gc Self :: Context ) -> Self :: Bound {
404
+ fn bind_to ( & self , context : & ' new_gc SimpleCollectorContext ) -> Gc < ' new_gc , T :: Branded > {
405
405
/*
406
406
* We can safely assume the object will
407
407
* be as valid as long as the context.
@@ -417,6 +417,11 @@ unsafe impl<'new_gc, T> GcBindHandle<'new_gc, T> for GcHandle<T>
417
417
*/
418
418
unsafe {
419
419
let collector = self . collector . assume_valid ( ) ;
420
+ assert_eq ! (
421
+ collector. as_ref( ) as * const RawSimpleCollector ,
422
+ context. collector( ) as * const RawSimpleCollector ,
423
+ "Collectors mismatch"
424
+ ) ;
420
425
let inner = self . inner . as_ref ( ) ;
421
426
let value = inner. value . load ( Ordering :: Acquire )
422
427
as * mut T as * mut T :: Branded ;
@@ -529,4 +534,38 @@ unsafe impl<T: GcSafe + Sync> Send for GcHandle<T> {}
529
534
/// it's safe to share garbage collected references between threads.
530
535
///
531
536
/// The collector itself is always safe
532
- unsafe impl < T : GcSafe + Sync > Sync for GcHandle < T > { }
537
+ unsafe impl < T : GcSafe + Sync > Sync for GcHandle < T > { }
538
+
539
+ /// We support handles
540
+ unsafe impl < ' gc , T > GcHandleSystem < ' gc , T > for SimpleCollector
541
+ where T : GcSafe + ' gc ,
542
+ T : GcBrand < ' static , CollectorId > ,
543
+ T :: Branded : GcSafe {
544
+ type Handle = GcHandle < T :: Branded > ;
545
+ #[ inline]
546
+ fn create_handle ( gc : Gc < ' gc , T > ) -> Self :: Handle {
547
+ use crate :: StaticGcType ;
548
+ unsafe {
549
+ let collector = gc. collector_id ( ) ;
550
+ let value = gc. as_raw_ptr ( ) ;
551
+ let raw = collector. as_ref ( ) . handle_list
552
+ . alloc_raw_handle ( value as * mut ( ) ) ;
553
+ /*
554
+ * WARN: Undefined Behavior
555
+ * if we don't finish initializing
556
+ * the handle!!!
557
+ *
558
+ * TODO: Encapsulate
559
+ */
560
+ raw. type_info . store (
561
+ <T as StaticGcType >:: STATIC_TYPE
562
+ as * const GcType
563
+ as * mut GcType ,
564
+ Ordering :: Release
565
+ ) ;
566
+ raw. refcnt . store ( 1 , Ordering :: Release ) ;
567
+ let weak_collector = collector. weak_ref ( ) ;
568
+ GcHandle :: new ( NonNull :: from ( raw) , weak_collector)
569
+ }
570
+ }
571
+ }
0 commit comments