1010
1111#![ no_std]
1212
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-
2113/// Generate bindings for an input WIT document.
2214///
2315/// 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};
301293/// // for generated types. This is a niche option that is only here to
302294/// // support the standard library itself depending on this crate one day.
303295/// 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,
304300/// });
305301/// ```
306302///
@@ -318,44 +314,8 @@ mod cabi_realloc;
318314
319315#[ doc( hidden) ]
320316pub 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- }
354317
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;
359319
360320 /// This function is called from generated bindings and will be deleted by
361321 /// the linker. The purpose of this function is to force a reference to the
@@ -405,6 +365,8 @@ pub mod rt {
405365 align : usize ,
406366 new_len : usize ,
407367 ) -> * mut u8 {
368+ use self :: alloc:: alloc:: { self , Layout } ;
369+
408370 let layout;
409371 let ptr = if old_len == 0 {
410372 if new_len == 0 {
@@ -432,249 +394,4 @@ pub mod rt {
432394 }
433395 return ptr;
434396 }
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- }
680397}
0 commit comments