@@ -115,6 +115,7 @@ struct CallableDecl {
115115 wrapper : Option < WrapperDecl > ,
116116 host_binding_kind : HostBindingKind ,
117117 host_execution : HostExecutionKind ,
118+ runtime_owned_pending : bool ,
118119}
119120
120121#[ derive( Clone , Debug ) ]
@@ -243,10 +244,21 @@ fn write_generated_file(path: &Path, contents: &str) {
243244fn builtin_source_specs ( namespaces : & [ NamespaceDecl ] ) -> Vec < SourceSpec > {
244245 namespaces
245246 . iter ( )
246- . map ( |namespace| SourceSpec {
247- path : format ! ( "src/builtins/runtime/{}.rs" , namespace. module) ,
248- module : namespace. module . clone ( ) ,
249- category : SourceCategory :: NamespacedBuiltin ,
247+ . map ( |namespace| {
248+ let path = if namespace. module == "io" {
249+ if cfg ! ( feature = "async" ) {
250+ "src/builtins/runtime/io/async_io.rs" . to_string ( )
251+ } else {
252+ "src/builtins/runtime/io/blocking.rs" . to_string ( )
253+ }
254+ } else {
255+ format ! ( "src/builtins/runtime/{}.rs" , namespace. module)
256+ } ;
257+ SourceSpec {
258+ path,
259+ module : namespace. module . clone ( ) ,
260+ category : SourceCategory :: NamespacedBuiltin ,
261+ }
250262 } )
251263 . collect ( )
252264}
@@ -268,6 +280,9 @@ fn parse_sources(
268280}
269281
270282pub ( crate ) fn classify_host_binding ( function : & ItemFn ) -> HostBindingKind {
283+ if function. sig . asyncness . is_some ( ) {
284+ return HostBindingKind :: StaticStack ;
285+ }
271286 if function. sig . inputs . iter ( ) . any ( |input| match input {
272287 FnArg :: Typed ( pat_type) => is_vm_context_type ( & pat_type. ty ) ,
273288 _ => false ,
@@ -293,6 +308,9 @@ pub(crate) fn classify_host_binding(function: &ItemFn) -> HostBindingKind {
293308}
294309
295310pub ( crate ) fn infer_host_execution ( function : & ItemFn ) -> HostExecutionKind {
311+ if function. sig . asyncness . is_some ( ) {
312+ return HostExecutionKind :: MaySuspend ;
313+ }
296314 let return_type = normalized_return_type ( & function. sig . output ) ;
297315 if contains_host_call_result ( & return_type) {
298316 HostExecutionKind :: MaySuspend
@@ -439,6 +457,8 @@ fn parse_source_file(path: &Path, spec: &SourceSpec, _order_offset: usize) -> Ve
439457 wrapper,
440458 host_binding_kind : classify_host_binding ( function) ,
441459 host_execution : infer_host_execution ( function) ,
460+ runtime_owned_pending : function. sig . asyncness . is_none ( )
461+ && contains_host_call_result ( & normalized_return_type ( & function. sig . output ) ) ,
442462 } ) ;
443463 }
444464 out
@@ -1090,12 +1110,14 @@ fn render_builtin_runtime_dispatch(
10901110 )
10911111 . unwrap ( ) ;
10921112 }
1093- writeln ! (
1094- & mut out,
1095- " registry.mark_runtime_owned_pending({:?});" ,
1096- callable. name
1097- )
1098- . unwrap ( ) ;
1113+ if callable. runtime_owned_pending {
1114+ writeln ! (
1115+ & mut out,
1116+ " registry.mark_runtime_owned_pending({:?});" ,
1117+ callable. name
1118+ )
1119+ . unwrap ( ) ;
1120+ }
10991121 }
11001122 writeln ! ( & mut out, "}}" ) . unwrap ( ) ;
11011123 writeln ! ( & mut out) . unwrap ( ) ;
@@ -1112,12 +1134,14 @@ fn render_builtin_runtime_dispatch(
11121134 . render_bind_static_call ( & callable. name , & host_wrapper_adapter_name ( callable) ) ;
11131135 writeln ! ( & mut out, " {:?} => {{" , callable. name) . unwrap ( ) ;
11141136 writeln ! ( & mut out, " {bind_call}" ) . unwrap ( ) ;
1115- writeln ! (
1116- & mut out,
1117- " vm.mark_runtime_owned_pending_binding({:?});" ,
1118- callable. name
1119- )
1120- . unwrap ( ) ;
1137+ if callable. runtime_owned_pending {
1138+ writeln ! (
1139+ & mut out,
1140+ " vm.mark_runtime_owned_pending_binding({:?});" ,
1141+ callable. name
1142+ )
1143+ . unwrap ( ) ;
1144+ }
11211145 writeln ! ( & mut out, " true" ) . unwrap ( ) ;
11221146 writeln ! ( & mut out, " }}" ) . unwrap ( ) ;
11231147 }
@@ -1886,6 +1910,9 @@ fn host_wrapper_adapter_name(callable: &CallableDecl) -> String {
18861910
18871911fn generated_wrapper_decl ( function : & ItemFn ) -> WrapperDecl {
18881912 let mut params = Vec :: new ( ) ;
1913+ if function. sig . asyncness . is_some ( ) {
1914+ params. push ( WrapperParamKind :: Vm ) ;
1915+ }
18891916 for input in & function. sig . inputs {
18901917 let FnArg :: Typed ( pat_type) = input else {
18911918 panic ! ( "methods are not supported in #[pd_host_function] declarations" ) ;
@@ -1912,6 +1939,13 @@ fn parse_callable_params(function: &ItemFn) -> Vec<CallableParamDecl> {
19121939 let FnArg :: Typed ( pat_type) = input else {
19131940 panic ! ( "methods are not supported in #[pd_host_function] declarations" ) ;
19141941 } ;
1942+ if pat_type
1943+ . attrs
1944+ . iter ( )
1945+ . any ( |attr| attr. path ( ) . is_ident ( "pd_host_context" ) )
1946+ {
1947+ return None ;
1948+ }
19151949 if is_vm_context_type ( & pat_type. ty ) {
19161950 return None ;
19171951 }
@@ -2078,7 +2112,7 @@ fn type_label(ty: &Type) -> String {
20782112 } ;
20792113 format ! ( "{} | null" , type_label( inner) )
20802114 }
2081- "VmResult" | "HostCallResult" => {
2115+ "VmResult" | "HostCallResult" | "HostFutureOutput" => {
20822116 let syn:: PathArguments :: AngleBracketed ( args) = & segment. arguments else {
20832117 panic ! ( "{ident}<T> requires one generic argument" ) ;
20842118 } ;
0 commit comments