@@ -1906,8 +1906,7 @@ fn wasm_type(ty: WasmType) -> &'static str {
19061906
19071907/// Declares the core import `wasm_import_module`/`wasm_import_name` as a
19081908/// function named `rust_name`. On `wasm32` this is a plain linker-resolved
1909- /// import; natively it's a shim that asks the host's resolver for the
1910- /// implementation on first call (see `rt::resolve_import`) and caches it.
1909+ /// import; natively it's the shim from [`native_import_shim`].
19111910fn declare_import (
19121911 wasm_import_module : & str ,
19131912 wasm_import_name : & str ,
@@ -1929,20 +1928,19 @@ fn declare_import(
19291928 sig. push_str ( wasm_type ( * result) ) ;
19301929 }
19311930
1932- let named_params: Vec < String > = params
1931+ let named_params: Vec < ( String , & str ) > = params
19331932 . iter ( )
19341933 . enumerate ( )
1935- . map ( |( i, ty) | format ! ( "arg{i}: {}" , wasm_type( * ty) ) )
1934+ . map ( |( i, ty) | ( format ! ( "arg{i}" ) , wasm_type ( * ty) ) )
19361935 . collect ( ) ;
1937- let ret_sig = results
1938- . first ( )
1939- . map ( |r| format ! ( " -> {}" , wasm_type( * r) ) )
1940- . unwrap_or_default ( ) ;
1941- let call_args = ( 0 ..params. len ( ) )
1942- . map ( |i| format ! ( "arg{i}" ) )
1943- . collect :: < Vec < _ > > ( )
1944- . join ( ", " ) ;
1945- let named_params_str = named_params. join ( ", " ) ;
1936+ let native = native_import_shim (
1937+ wasm_import_module,
1938+ wasm_import_name,
1939+ rust_name,
1940+ & named_params,
1941+ results. first ( ) . map ( |r| wasm_type ( * r) ) ,
1942+ rt,
1943+ ) ;
19461944
19471945 format ! (
19481946 r#"
@@ -1952,18 +1950,54 @@ fn declare_import(
19521950 #[link_name = "{wasm_import_name}"]
19531951 fn {rust_name}{sig};
19541952 }}
1953+ {native}
1954+ "# ,
1955+ )
1956+ }
1957+
1958+ /// Emits the native (non-`wasm32`) definition of the core import
1959+ /// `module`/`name`: an `unsafe extern "C" fn` named `rust_name` that asks the
1960+ /// host's import resolver for the implementation on first call (see
1961+ /// `rt::resolve_import`) and caches it. `params` are `(name, type)` pairs.
1962+ fn native_import_shim (
1963+ module : & str ,
1964+ name : & str ,
1965+ rust_name : & str ,
1966+ params : & [ ( String , & str ) ] ,
1967+ result : Option < & str > ,
1968+ rt : & str ,
1969+ ) -> String {
1970+ let named_params = params
1971+ . iter ( )
1972+ . map ( |( arg, ty) | format ! ( "{arg}: {ty}" ) )
1973+ . collect :: < Vec < _ > > ( )
1974+ . join ( ", " ) ;
1975+ let param_types = params
1976+ . iter ( )
1977+ . map ( |( _, ty) | * ty)
1978+ . collect :: < Vec < _ > > ( )
1979+ . join ( ", " ) ;
1980+ let call_args = params
1981+ . iter ( )
1982+ . map ( |( arg, _) | arg. as_str ( ) )
1983+ . collect :: < Vec < _ > > ( )
1984+ . join ( ", " ) ;
1985+ let ret_sig = result. map ( |r| format ! ( " -> {r}" ) ) . unwrap_or_default ( ) ;
19551986
1987+ format ! (
1988+ r#"
19561989 #[cfg(not(target_arch = "wasm32"))]
1957- unsafe extern "C" fn {rust_name}({named_params_str }){ret_sig} {{
1990+ unsafe extern "C" fn {rust_name}({named_params }){ret_sig} {{
19581991 static CACHE: ::core::sync::atomic::AtomicPtr<()> =
19591992 ::core::sync::atomic::AtomicPtr::new(::core::ptr::null_mut());
1960- let mut ptr = CACHE.load(::core::sync::atomic::Ordering::Acquire);
1961- if ptr.is_null() {{
1962- ptr = {rt}::resolve_import(c"{wasm_import_module}", c"{wasm_import_name}");
1963- CACHE.store(ptr, ::core::sync::atomic::Ordering::Release);
1993+ // Named so as not to shadow any parameter.
1994+ let mut __impl = CACHE.load(::core::sync::atomic::Ordering::Acquire);
1995+ if __impl.is_null() {{
1996+ __impl = {rt}::resolve_import(c"{module}", c"{name}");
1997+ CACHE.store(__impl, ::core::sync::atomic::Ordering::Release);
19641998 }}
1965- let f : unsafe extern "C" fn{sig} = unsafe {{ ::core::mem::transmute(ptr ) }};
1966- unsafe {{ f ({call_args}) }}
1999+ let __func : unsafe extern "C" fn({param_types}){ret_sig} = unsafe {{ ::core::mem::transmute(__impl ) }};
2000+ unsafe {{ __func ({call_args}) }}
19672001 }}
19682002 "# ,
19692003 )
0 commit comments