Skip to content
This repository was archived by the owner on Mar 24, 2022. It is now read-only.

Commit 62ad436

Browse files
author
Pat Hickey
authored
Revert "Merge pull request #626 from benaubin/custom-run-async-future" (#643)
This reverts commit bf24022, reversing changes made to ddaf91e.
1 parent 2a02670 commit 62ad436

File tree

10 files changed

+231
-562
lines changed

10 files changed

+231
-562
lines changed

lucet-runtime/lucet-runtime-internals/src/future.rs

Lines changed: 182 additions & 300 deletions
Large diffs are not rendered by default.

lucet-runtime/lucet-runtime-internals/src/instance.rs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub use crate::instance::execution::{KillError, KillState, KillSuccess, KillSwit
77
pub use crate::instance::signals::{signal_handler_none, SignalBehavior, SignalHandler};
88
pub use crate::instance::state::State;
99

10+
use crate::alloc::Alloc;
1011
use crate::context::Context;
1112
use crate::embed_ctx::CtxMap;
1213
use crate::error::Error;
@@ -17,13 +18,13 @@ use crate::region::RegionInternal;
1718
use crate::sysdeps::HOST_PAGE_SIZE_EXPECTED;
1819
use crate::val::{UntypedRetVal, Val};
1920
use crate::WASM_PAGE_SIZE;
20-
use crate::{alloc::Alloc, future::AsyncContext};
2121
use libc::{c_void, pthread_self, siginfo_t, uintptr_t};
2222
use lucet_module::InstanceRuntimeData;
2323
use memoffset::offset_of;
2424
use std::any::Any;
2525
use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut, UnsafeCell};
2626
use std::convert::TryFrom;
27+
use std::marker::PhantomData;
2728
use std::mem;
2829
use std::ops::{Deref, DerefMut};
2930
use std::ptr::{self, NonNull};
@@ -514,7 +515,7 @@ impl Instance {
514515
/// in the future.
515516
pub fn run(&mut self, entrypoint: &str, args: &[Val]) -> Result<RunResult, Error> {
516517
let func = self.module.get_export_func(entrypoint)?;
517-
Ok(self.run_func(func, &args, None, None)?.unwrap())
518+
Ok(self.run_func(func, &args, false, None)?.unwrap())
518519
}
519520

520521
/// Run a function with arguments in the guest context from the [WebAssembly function
@@ -530,7 +531,7 @@ impl Instance {
530531
args: &[Val],
531532
) -> Result<RunResult, Error> {
532533
let func = self.module.get_func_from_idx(table_idx, func_idx)?;
533-
Ok(self.run_func(func, &args, None, None)?.unwrap())
534+
Ok(self.run_func(func, &args, false, None)?.unwrap())
534535
}
535536

536537
/// Resume execution of an instance that has yielded without providing a value to the guest.
@@ -561,21 +562,19 @@ impl Instance {
561562
/// The foreign code safety caveat of [`Instance::run()`](struct.Instance.html#method.run)
562563
/// applies.
563564
pub fn resume_with_val<A: Any + 'static>(&mut self, val: A) -> Result<RunResult, Error> {
564-
Ok(self
565-
.resume_with_val_impl(Box::new(val), None, None)?
566-
.unwrap())
565+
Ok(self.resume_with_val_impl(val, false, None)?.unwrap())
567566
}
568567

569-
pub(crate) fn resume_with_val_impl(
568+
pub(crate) fn resume_with_val_impl<A: Any + 'static>(
570569
&mut self,
571-
val: Box<dyn Any + 'static>,
572-
async_context: Option<AsyncContext>,
570+
val: A,
571+
async_context: bool,
573572
max_insn_count: Option<u64>,
574573
) -> Result<InternalRunResult, Error> {
575574
match &self.state {
576575
State::Yielded { expecting, .. } => {
577576
// make sure the resumed value is of the right type
578-
if &(*val).type_id() != expecting {
577+
if !expecting.is::<PhantomData<A>>() {
579578
return Err(Error::InvalidArgument(
580579
"type mismatch between yielded instance expected value and resumed value",
581580
));
@@ -584,7 +583,7 @@ impl Instance {
584583
_ => return Err(Error::InvalidArgument("can only resume a yielded instance")),
585584
}
586585

587-
self.resumed_val = Some(val);
586+
self.resumed_val = Some(Box::new(val) as Box<dyn Any + 'static>);
588587

589588
self.set_instruction_bound_delta(max_insn_count);
590589
self.swap_and_return(async_context)
@@ -603,7 +602,6 @@ impl Instance {
603602
/// applies.
604603
pub(crate) fn resume_bounded(
605604
&mut self,
606-
async_context: AsyncContext,
607605
max_insn_count: u64,
608606
) -> Result<InternalRunResult, Error> {
609607
if !self.state.is_bound_expired() {
@@ -612,7 +610,7 @@ impl Instance {
612610
));
613611
}
614612
self.set_instruction_bound_delta(Some(max_insn_count));
615-
self.swap_and_return(Some(async_context))
613+
self.swap_and_return(true)
616614
}
617615

618616
/// Run the module's [start function][start], if one exists.
@@ -650,7 +648,7 @@ impl Instance {
650648
if !self.is_not_started() {
651649
return Err(Error::StartAlreadyRun);
652650
}
653-
self.run_func(start, &[], None, None)?;
651+
self.run_func(start, &[], false, None)?;
654652
}
655653
Ok(())
656654
}
@@ -1092,7 +1090,7 @@ impl Instance {
10921090
&mut self,
10931091
func: FunctionHandle,
10941092
args: &[Val],
1095-
async_context: Option<AsyncContext>,
1093+
async_context: bool,
10961094
inst_count_bound: Option<u64>,
10971095
) -> Result<InternalRunResult, Error> {
10981096
let needs_start = self.state.is_not_started() && !func.is_start_func;
@@ -1193,10 +1191,7 @@ impl Instance {
11931191
/// This must only be called for an instance in a ready, non-fatally faulted, or yielded state,
11941192
/// or in the not-started state on the start function. The public wrappers around this function
11951193
/// should make sure the state is appropriate.
1196-
fn swap_and_return<'a>(
1197-
&mut self,
1198-
async_context: Option<AsyncContext>,
1199-
) -> Result<InternalRunResult, Error> {
1194+
fn swap_and_return(&mut self, async_context: bool) -> Result<InternalRunResult, Error> {
12001195
let is_start_func = self
12011196
.entrypoint
12021197
.expect("we always have an entrypoint by now")
@@ -1208,10 +1203,7 @@ impl Instance {
12081203
|| self.state.is_yielded()
12091204
|| self.state.is_bound_expired()
12101205
);
1211-
1212-
self.state = State::Running {
1213-
async_context: async_context.map(|cx| Arc::new(cx)),
1214-
};
1206+
self.state = State::Running { async_context };
12151207

12161208
let res = self.with_current_instance(|i| {
12171209
i.with_signals_on(|i| {

lucet-runtime/lucet-runtime-internals/src/instance/state.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use crate::instance::siginfo_ext::SiginfoExt;
12
use crate::instance::{FaultDetails, TerminationDetails, YieldedVal};
23
use crate::sysdeps::UContext;
3-
use crate::{future::AsyncContext, instance::siginfo_ext::SiginfoExt};
44
use libc::{SIGBUS, SIGSEGV};
5-
use std::any::TypeId;
5+
use std::any::Any;
66
use std::ffi::{CStr, CString};
77

88
/// The representation of a Lucet instance's state machine.
@@ -25,7 +25,7 @@ pub enum State {
2525
Running {
2626
/// Indicates whether the instance is running in an async context (`Instance::run_async`)
2727
/// or not. Needed by `Vmctx::block_on`.
28-
async_context: Option<std::sync::Arc<AsyncContext>>,
28+
async_context: bool,
2929
},
3030

3131
/// The instance has faulted, potentially fatally.
@@ -56,8 +56,11 @@ pub enum State {
5656
/// `RunResult` before anything else happens to the instance.
5757
Yielding {
5858
val: YieldedVal,
59-
/// The type of the expected resumption value
60-
expecting: TypeId,
59+
/// A phantom value carrying the type of the expected resumption value.
60+
///
61+
/// Concretely, this should only ever be `Box<PhantomData<R>>` where `R` is the type
62+
/// the guest expects upon resumption.
63+
expecting: Box<dyn Any>,
6164
},
6265

6366
/// The instance has yielded.
@@ -66,7 +69,10 @@ pub enum State {
6669
/// instance is reset.
6770
Yielded {
6871
/// A phantom value carrying the type of the expected resumption value.
69-
expecting: TypeId,
72+
///
73+
/// Concretely, this should only ever be `Box<PhantomData<R>>` where `R` is the type
74+
/// the guest expects upon resumption.
75+
expecting: Box<dyn Any>,
7076
},
7177

7278
/// The instance has reached an instruction-count bound.
@@ -91,10 +97,10 @@ impl std::fmt::Display for State {
9197
State::NotStarted => write!(f, "not started"),
9298
State::Ready => write!(f, "ready"),
9399
State::Running {
94-
async_context: None,
100+
async_context: false,
95101
} => write!(f, "running"),
96102
State::Running {
97-
async_context: Some(_),
103+
async_context: true,
98104
} => write!(f, "running (in async context)"),
99105
State::Faulted {
100106
details, siginfo, ..
@@ -157,11 +163,8 @@ impl State {
157163
}
158164

159165
pub fn is_running_async(&self) -> bool {
160-
if let State::Running {
161-
async_context: Some(_),
162-
} = self
163-
{
164-
true
166+
if let State::Running { async_context } = self {
167+
*async_context
165168
} else {
166169
false
167170
}

lucet-runtime/lucet-runtime-internals/src/vmctx.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ use crate::instance::{
1313
CURRENT_INSTANCE, HOST_CTX,
1414
};
1515
use lucet_module::{FunctionHandle, GlobalValue};
16-
use std::any::{Any, TypeId};
16+
use std::any::Any;
1717
use std::borrow::{Borrow, BorrowMut};
1818
use std::cell::{Ref, RefCell, RefMut};
19+
use std::marker::PhantomData;
1920

2021
/// An opaque handle to a running instance's context.
2122
#[derive(Debug)]
@@ -435,9 +436,10 @@ impl Vmctx {
435436
if is_bound_expiration {
436437
inst.state = State::BoundExpired;
437438
} else {
439+
let expecting: Box<PhantomData<R>> = Box::new(PhantomData);
438440
inst.state = State::Yielding {
439441
val: YieldedVal::new(val),
440-
expecting: TypeId::of::<R>(),
442+
expecting: expecting as Box<dyn Any>,
441443
};
442444
}
443445

lucet-runtime/lucet-runtime-macros/src/lib.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,6 @@ pub fn lucet_hostcall(_attr: TokenStream, item: TokenStream) -> TokenStream {
101101
quote! { lucet_runtime::TerminationDetails }
102102
};
103103

104-
let res_ident = quote::format_ident!("res");
105-
106-
let block_if_async = match raw_sig.asyncness.take() {
107-
Some(_) => {
108-
quote! { let #res_ident = vmctx.block_on(#res_ident); }
109-
}
110-
None => {
111-
quote! {}
112-
}
113-
};
114-
115104
let raw_hostcall = quote! {
116105
#(#attrs)*
117106
#vis
@@ -122,13 +111,7 @@ pub fn lucet_hostcall(_attr: TokenStream, item: TokenStream) -> TokenStream {
122111
let vmctx = #vmctx_mod::Vmctx::from_raw(vmctx_raw);
123112
#vmctx_mod::VmctxInternal::instance_mut(&vmctx).uninterruptable(|| {
124113
let res = std::panic::catch_unwind(move || {
125-
let vmctx = #vmctx_mod::Vmctx::from_raw(vmctx_raw);
126-
127-
let #res_ident = #hostcall_ident(&vmctx, #(#impl_args),*);
128-
129-
#block_if_async
130-
131-
#res_ident
114+
#hostcall_ident(&#vmctx_mod::Vmctx::from_raw(vmctx_raw), #(#impl_args),*)
132115
});
133116
match res {
134117
Ok(res) => res,
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
{
22
"env": {
3-
"hostcall_containing_block_on": "hostcall_containing_block_on",
4-
"hostcall_containing_yielding_block_on": "hostcall_containing_yielding_block_on",
5-
"hostcall_async_containing_yielding_block_on": "hostcall_async_containing_yielding_block_on",
6-
"await_manual_future": "await_manual_future"
3+
"hostcall_containing_block_on": "hostcall_containing_block_on"
74
}
85
}
Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,9 @@
11
#include <stddef.h>
22

33
extern void hostcall_containing_block_on(int);
4-
extern void hostcall_containing_yielding_block_on(int);
5-
extern int hostcall_async_containing_yielding_block_on(int, int);
64

75
int main(void)
86
{
97
hostcall_containing_block_on(1312);
108
return 0;
119
}
12-
13-
int yielding()
14-
{
15-
hostcall_containing_yielding_block_on(0);
16-
hostcall_containing_yielding_block_on(1);
17-
hostcall_containing_yielding_block_on(2);
18-
hostcall_containing_yielding_block_on(3);
19-
20-
int six = hostcall_async_containing_yielding_block_on(3, 6);
21-
hostcall_async_containing_yielding_block_on(3, six);
22-
23-
return 0;
24-
}
25-
26-
int manual_future()
27-
{
28-
await_manual_future();
29-
return 0;
30-
}

0 commit comments

Comments
 (0)