10
10
11
11
#![ no_std]
12
12
13
- extern crate alloc;
14
-
15
- use alloc:: boxed:: Box ;
16
- use core:: fmt;
17
- use core:: marker;
18
- use core:: ops:: { Deref , DerefMut } ;
19
- use core:: sync:: atomic:: { AtomicU32 , Ordering :: Relaxed } ;
20
-
21
13
/// Generate bindings for an input WIT document.
22
14
///
23
15
/// This macro is the bread-and-butter of the `wit-bindgen` crate. The macro
@@ -301,6 +293,10 @@ use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
301
293
/// // for generated types. This is a niche option that is only here to
302
294
/// // support the standard library itself depending on this crate one day.
303
295
/// std_feature,
296
+ ///
297
+ /// // Force a workaround to be emitted for pre-Rust-1.69.0 modules to
298
+ /// // ensure that libc ctors run only once.
299
+ /// run_ctors_once_workaround: true,
304
300
/// });
305
301
/// ```
306
302
///
@@ -318,44 +314,8 @@ mod cabi_realloc;
318
314
319
315
#[ doc( hidden) ]
320
316
pub mod rt {
321
- use crate :: alloc:: string:: String ;
322
- use crate :: alloc:: vec:: Vec ;
323
-
324
- pub use crate :: { Resource , RustResource , WasmResource } ;
325
-
326
- /// Provide a hook for generated export functions to run static
327
- /// constructors at most once. wit-bindgen-rust generates a call to this
328
- /// function at the start of all component export functions. Importantly,
329
- /// it is not called as part of `cabi_realloc`, which is a *core* export
330
- /// func, but may not execute ctors, because the environment ctor in
331
- /// wasi-libc (before rust 1.69.0) calls an import func, which is not
332
- /// permitted by the Component Model when inside realloc.
333
- ///
334
- /// We intend to remove this once rust 1.69.0 stabilizes.
335
- #[ cfg( target_arch = "wasm32" ) ]
336
- pub fn run_ctors_once ( ) {
337
- static mut RUN : bool = false ;
338
- unsafe {
339
- if !RUN {
340
- // This function is synthesized by `wasm-ld` to run all static
341
- // constructors. wasm-ld will either provide an implementation
342
- // of this symbol, or synthesize a wrapper around each
343
- // exported function to (unconditionally) run ctors. By using
344
- // this function, the linked module is opting into "manually"
345
- // running ctors.
346
- extern "C" {
347
- fn __wasm_call_ctors ( ) ;
348
- }
349
- __wasm_call_ctors ( ) ;
350
- RUN = true ;
351
- }
352
- }
353
- }
354
317
355
- use super :: alloc:: alloc:: Layout ;
356
-
357
- // Re-export things from liballoc for convenient use.
358
- pub use super :: alloc:: { alloc, boxed, string, vec} ;
318
+ extern crate alloc;
359
319
360
320
/// This function is called from generated bindings and will be deleted by
361
321
/// the linker. The purpose of this function is to force a reference to the
@@ -405,6 +365,8 @@ pub mod rt {
405
365
align : usize ,
406
366
new_len : usize ,
407
367
) -> * mut u8 {
368
+ use self :: alloc:: alloc:: { self , Layout } ;
369
+
408
370
let layout;
409
371
let ptr = if old_len == 0 {
410
372
if new_len == 0 {
@@ -432,249 +394,4 @@ pub mod rt {
432
394
}
433
395
return ptr;
434
396
}
435
-
436
- pub unsafe fn dealloc ( ptr : i32 , size : usize , align : usize ) {
437
- if size == 0 {
438
- return ;
439
- }
440
- let layout = Layout :: from_size_align_unchecked ( size, align) ;
441
- alloc:: dealloc ( ptr as * mut u8 , layout) ;
442
- }
443
-
444
- macro_rules! as_traits {
445
- ( $( ( $trait_: ident $func: ident $ty: ident <=> $( $tys: ident) * ) ) * ) => ( $(
446
- pub fn $func<T : $trait_>( t: T ) -> $ty {
447
- t. $func( )
448
- }
449
-
450
- pub trait $trait_ {
451
- fn $func( self ) -> $ty;
452
- }
453
-
454
- impl <' a, T : Copy + $trait_> $trait_ for & ' a T {
455
- fn $func( self ) -> $ty{
456
- ( * self ) . $func( )
457
- }
458
- }
459
-
460
- $(
461
- impl $trait_ for $tys {
462
- #[ inline]
463
- fn $func( self ) -> $ty {
464
- self as $ty
465
- }
466
- }
467
- ) *
468
-
469
- ) * )
470
- }
471
-
472
- as_traits ! {
473
- ( AsI64 as_i64 i64 <=> i64 u64 )
474
- ( AsI32 as_i32 i32 <=> i32 u32 i16 u16 i8 u8 char usize )
475
- ( AsF32 as_f32 f32 <=> f32 )
476
- ( AsF64 as_f64 f64 <=> f64 )
477
- }
478
-
479
- pub unsafe fn string_lift ( bytes : Vec < u8 > ) -> String {
480
- if cfg ! ( debug_assertions) {
481
- String :: from_utf8 ( bytes) . unwrap ( )
482
- } else {
483
- String :: from_utf8_unchecked ( bytes)
484
- }
485
- }
486
-
487
- pub unsafe fn invalid_enum_discriminant < T > ( ) -> T {
488
- if cfg ! ( debug_assertions) {
489
- panic ! ( "invalid enum discriminant" )
490
- } else {
491
- core:: hint:: unreachable_unchecked ( )
492
- }
493
- }
494
-
495
- pub unsafe fn char_lift ( val : u32 ) -> char {
496
- if cfg ! ( debug_assertions) {
497
- core:: char:: from_u32 ( val) . unwrap ( )
498
- } else {
499
- core:: char:: from_u32_unchecked ( val)
500
- }
501
- }
502
-
503
- pub unsafe fn bool_lift ( val : u8 ) -> bool {
504
- if cfg ! ( debug_assertions) {
505
- match val {
506
- 0 => false ,
507
- 1 => true ,
508
- _ => panic ! ( "invalid bool discriminant" ) ,
509
- }
510
- } else {
511
- core:: mem:: transmute :: < u8 , bool > ( val)
512
- }
513
- }
514
- }
515
-
516
- type RawRep < T > = Option < T > ;
517
-
518
- /// A type which represents a component model resource, either imported or
519
- /// exported into this component.
520
- ///
521
- /// This is a low-level wrapper which handles the lifetime of the resource
522
- /// (namely this has a destructor). The `T` provided defines the component model
523
- /// intrinsics that this wrapper uses.
524
- ///
525
- /// One of the chief purposes of this type is to provide `Deref` implementations
526
- /// to access the underlying data when it is owned.
527
- ///
528
- /// This type is primarily used in generated code for exported and imported
529
- /// resources.
530
- #[ repr( transparent) ]
531
- pub struct Resource < T : WasmResource > {
532
- // NB: This would ideally be `u32` but it is not. The fact that this has
533
- // interior mutability is not exposed in the API of this type except for the
534
- // `take_handle` method which is supposed to in theory be private.
535
- //
536
- // This represents, almost all the time, a valid handle value. When it's
537
- // invalid it's stored as `u32::MAX`.
538
- handle : AtomicU32 ,
539
- _marker : marker:: PhantomData < Box < T > > ,
540
- }
541
-
542
- /// A trait which all wasm resources implement, namely providing the ability to
543
- /// drop a resource.
544
- ///
545
- /// This generally is implemented by generated code, not user-facing code.
546
- pub unsafe trait WasmResource {
547
- /// Invokes the `[resource-drop]...` intrinsic.
548
- unsafe fn drop ( handle : u32 ) ;
549
- }
550
-
551
- /// A trait which extends [`WasmResource`] used for Rust-defined resources, or
552
- /// those exported from this component.
553
- ///
554
- /// This generally is implemented by generated code, not user-facing code.
555
- pub unsafe trait RustResource : WasmResource {
556
- /// Invokes the `[resource-new]...` intrinsic.
557
- unsafe fn new ( rep : usize ) -> u32 ;
558
- /// Invokes the `[resource-rep]...` intrinsic.
559
- unsafe fn rep ( handle : u32 ) -> usize ;
560
- }
561
-
562
- impl < T : WasmResource > Resource < T > {
563
- #[ doc( hidden) ]
564
- pub unsafe fn from_handle ( handle : u32 ) -> Self {
565
- debug_assert ! ( handle != u32 :: MAX ) ;
566
- Self {
567
- handle : AtomicU32 :: new ( handle) ,
568
- _marker : marker:: PhantomData ,
569
- }
570
- }
571
-
572
- /// Takes ownership of the handle owned by `resource`.
573
- ///
574
- /// Note that this ideally would be `into_handle` taking `Resource<T>` by
575
- /// ownership. The code generator does not enable that in all situations,
576
- /// unfortunately, so this is provided instead.
577
- ///
578
- /// Also note that `take_handle` is in theory only ever called on values
579
- /// owned by a generated function. For example a generated function might
580
- /// take `Resource<T>` as an argument but then call `take_handle` on a
581
- /// reference to that argument. In that sense the dynamic nature of
582
- /// `take_handle` should only be exposed internally to generated code, not
583
- /// to user code.
584
- #[ doc( hidden) ]
585
- pub fn take_handle ( resource : & Resource < T > ) -> u32 {
586
- resource. handle . swap ( u32:: MAX , Relaxed )
587
- }
588
-
589
- #[ doc( hidden) ]
590
- pub fn handle ( resource : & Resource < T > ) -> u32 {
591
- resource. handle . load ( Relaxed )
592
- }
593
-
594
- /// Creates a new Rust-defined resource from the underlying representation
595
- /// `T`.
596
- ///
597
- /// This will move `T` onto the heap to create a single pointer to represent
598
- /// it which is then wrapped up in a component model resource.
599
- pub fn new ( val : T ) -> Resource < T >
600
- where
601
- T : RustResource ,
602
- {
603
- let rep = Box :: into_raw ( Box :: new ( Some ( val) ) ) as usize ;
604
- unsafe {
605
- let handle = T :: new ( rep) ;
606
- Resource :: from_handle ( handle)
607
- }
608
- }
609
-
610
- #[ doc( hidden) ]
611
- pub unsafe fn dtor ( rep : usize )
612
- where
613
- T : RustResource ,
614
- {
615
- let _ = Box :: from_raw ( rep as * mut RawRep < T > ) ;
616
- }
617
-
618
- /// Takes back ownership of the object, dropping the resource handle.
619
- pub fn into_inner ( resource : Self ) -> T
620
- where
621
- T : RustResource ,
622
- {
623
- unsafe {
624
- let rep = T :: rep ( resource. handle . load ( Relaxed ) ) ;
625
- RawRep :: take ( & mut * ( rep as * mut RawRep < T > ) ) . unwrap ( )
626
- }
627
- }
628
-
629
- #[ doc( hidden) ]
630
- pub unsafe fn lift_borrow < ' a > ( rep : usize ) -> & ' a T
631
- where
632
- T : RustResource ,
633
- {
634
- RawRep :: as_ref ( & * ( rep as * const RawRep < T > ) ) . unwrap ( )
635
- }
636
- }
637
-
638
- impl < T : RustResource > Deref for Resource < T > {
639
- type Target = T ;
640
-
641
- fn deref ( & self ) -> & T {
642
- unsafe {
643
- let rep = T :: rep ( self . handle . load ( Relaxed ) ) ;
644
- RawRep :: as_ref ( & * ( rep as * const RawRep < T > ) ) . unwrap ( )
645
- }
646
- }
647
- }
648
-
649
- impl < T : RustResource > DerefMut for Resource < T > {
650
- fn deref_mut ( & mut self ) -> & mut T {
651
- unsafe {
652
- let rep = T :: rep ( self . handle . load ( Relaxed ) ) ;
653
- RawRep :: as_mut ( & mut * ( rep as * mut RawRep < T > ) ) . unwrap ( )
654
- }
655
- }
656
- }
657
-
658
- impl < T : WasmResource > fmt:: Debug for Resource < T > {
659
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
660
- f. debug_struct ( "Resource" )
661
- . field ( "handle" , & self . handle )
662
- . finish ( )
663
- }
664
- }
665
-
666
- impl < T : WasmResource > Drop for Resource < T > {
667
- fn drop ( & mut self ) {
668
- unsafe {
669
- match self . handle . load ( Relaxed ) {
670
- // If this handle was "taken" then don't do anything in the
671
- // destructor.
672
- u32:: MAX => { }
673
-
674
- // ... but otherwise do actually destroy it with the imported
675
- // component model intrinsic as defined through `T`.
676
- other => T :: drop ( other) ,
677
- }
678
- }
679
- }
680
397
}
0 commit comments