Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
816 changes: 705 additions & 111 deletions crates/cranelift/src/compiler/component.rs

Large diffs are not rendered by default.

61 changes: 61 additions & 0 deletions crates/environ/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,69 @@ macro_rules! foreach_builtin_component_function {
resource_enter_call(vmctx: vmctx);
resource_exit_call(vmctx: vmctx) -> bool;

#[cfg(feature = "component-model-async")]
task_backpressure(vmctx: vmctx, caller_instance: u32, enabled: u32) -> bool;
#[cfg(feature = "component-model-async")]
task_return(vmctx: vmctx, ty: u32, storage: ptr_u8, storage_len: size) -> bool;
#[cfg(feature = "component-model-async")]
task_wait(vmctx: vmctx, caller_instance: u32, async_: u8, memory: ptr_u8, payload: u32) -> u64;
#[cfg(feature = "component-model-async")]
task_poll(vmctx: vmctx, caller_instance: u32, async_: u8, memory: ptr_u8, payload: u32) -> u64;
#[cfg(feature = "component-model-async")]
task_yield(vmctx: vmctx, async_: u8) -> bool;
#[cfg(feature = "component-model-async")]
subtask_drop(vmctx: vmctx, caller_instance: u32, task_id: u32) -> bool;
#[cfg(feature = "component-model-async")]
sync_enter(vmctx: vmctx, start: ptr_u8, return_: ptr_u8, caller_instance: u32, task_return_type: u32, result_count: u32, storage: ptr_u8, storage_len: size) -> bool;
#[cfg(feature = "component-model-async")]
sync_exit(vmctx: vmctx, callback: ptr_u8, caller_instance: u32, callee: ptr_u8, callee_instance: u32, param_count: u32, storage: ptr_u8, storage_len: size) -> bool;
#[cfg(feature = "component-model-async")]
async_enter(vmctx: vmctx, start: ptr_u8, return_: ptr_u8, caller_instance: u32, task_return_type: u32, params: u32, results: u32) -> bool;
#[cfg(feature = "component-model-async")]
async_exit(vmctx: vmctx, callback: ptr_u8, post_return: ptr_u8, caller_instance: u32, callee: ptr_u8, callee_instance: u32, param_count: u32, result_count: u32, flags: u32) -> u64;
#[cfg(feature = "component-model-async")]
future_new(vmctx: vmctx, ty: u32) -> u64;
#[cfg(feature = "component-model-async")]
future_write(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, future: u32, address: u32) -> u64;
#[cfg(feature = "component-model-async")]
future_read(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, err_ctx_ty: u32, future: u32, address: u32) -> u64;
#[cfg(feature = "component-model-async")]
future_cancel_write(vmctx: vmctx, ty: u32, async_: u8, writer: u32) -> u64;
#[cfg(feature = "component-model-async")]
future_cancel_read(vmctx: vmctx, ty: u32, async_: u8, reader: u32) -> u64;
#[cfg(feature = "component-model-async")]
future_close_writable(vmctx: vmctx, ty: u32, err_ctx_ty: u32, writer: u32, error: u32) -> bool;
#[cfg(feature = "component-model-async")]
future_close_readable(vmctx: vmctx, ty: u32, reader: u32) -> bool;
#[cfg(feature = "component-model-async")]
stream_new(vmctx: vmctx, ty: u32) -> u64;
#[cfg(feature = "component-model-async")]
stream_write(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, stream: u32, address: u32, count: u32) -> u64;
#[cfg(feature = "component-model-async")]
stream_read(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, err_ctx_ty: u32, stream: u32, address: u32, count: u32) -> u64;
#[cfg(feature = "component-model-async")]
stream_cancel_write(vmctx: vmctx, ty: u32, async_: u8, writer: u32) -> u64;
#[cfg(feature = "component-model-async")]
stream_cancel_read(vmctx: vmctx, ty: u32, async_: u8, reader: u32) -> u64;
#[cfg(feature = "component-model-async")]
stream_close_writable(vmctx: vmctx, ty: u32, err_ctx_ty: u32, writer: u32, error: u32) -> bool;
#[cfg(feature = "component-model-async")]
stream_close_readable(vmctx: vmctx, ty: u32, reader: u32) -> bool;
#[cfg(feature = "component-model-async")]
flat_stream_write(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, ty: u32, payload_size: u32, payload_align: u32, stream: u32, address: u32, count: u32) -> u64;
#[cfg(feature = "component-model-async")]
flat_stream_read(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, ty: u32, err_ctx_ty: u32, payload_size: u32, payload_align: u32, stream: u32, address: u32, count: u32) -> u64;
#[cfg(feature = "component-model-async")]
error_context_new(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, debug_msg_address: u32, debug_msg_len: u32) -> u64;
#[cfg(feature = "component-model-async")]
error_context_debug_message(vmctx: vmctx, memory: ptr_u8, realloc: ptr_u8, string_encoding: u8, ty: u32, err_ctx_handle: u32, debug_msg_address: u32) -> bool;
#[cfg(feature = "component-model-async")]
error_context_drop(vmctx: vmctx, ty: u32, err_ctx_handle: u32) -> bool;
#[cfg(feature = "component-model-async")]
future_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;
#[cfg(feature = "component-model-async")]
stream_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;
#[cfg(feature = "component-model-async")]
error_context_transfer(vmctx: vmctx, src_idx: u32, src_table: u32, dst_table: u32) -> u64;

trap(vmctx: vmctx, code: u8);
Expand Down
48 changes: 40 additions & 8 deletions crates/environ/src/component/dfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,9 @@ pub enum Trampoline {
TaskBackpressure {
instance: RuntimeComponentInstanceIndex,
},
TaskReturn,
TaskReturn {
results: TypeTupleIndex,
},
TaskWait {
instance: RuntimeComponentInstanceIndex,
async_: bool,
Expand All @@ -308,6 +310,7 @@ pub enum Trampoline {
},
StreamRead {
ty: TypeStreamTableIndex,
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
options: CanonicalOptions,
},
StreamWrite {
Expand All @@ -327,12 +330,14 @@ pub enum Trampoline {
},
StreamCloseWritable {
ty: TypeStreamTableIndex,
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
},
FutureNew {
ty: TypeFutureTableIndex,
},
FutureRead {
ty: TypeFutureTableIndex,
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
options: CanonicalOptions,
},
FutureWrite {
Expand All @@ -352,6 +357,7 @@ pub enum Trampoline {
},
FutureCloseWritable {
ty: TypeFutureTableIndex,
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
},
ErrorContextNew {
ty: TypeComponentLocalErrorContextTableIndex,
Expand All @@ -368,6 +374,10 @@ pub enum Trampoline {
ResourceTransferBorrow,
ResourceEnterCall,
ResourceExitCall,
SyncEnterCall,
SyncExitCall {
callback: Option<CallbackId>,
},
AsyncEnterCall,
AsyncExitCall {
callback: Option<CallbackId>,
Expand Down Expand Up @@ -765,7 +775,9 @@ impl LinearizeDfg<'_> {
Trampoline::TaskBackpressure { instance } => info::Trampoline::TaskBackpressure {
instance: *instance,
},
Trampoline::TaskReturn => info::Trampoline::TaskReturn,
Trampoline::TaskReturn { results } => {
info::Trampoline::TaskReturn { results: *results }
}
Trampoline::TaskWait {
instance,
async_,
Expand All @@ -789,8 +801,13 @@ impl LinearizeDfg<'_> {
instance: *instance,
},
Trampoline::StreamNew { ty } => info::Trampoline::StreamNew { ty: *ty },
Trampoline::StreamRead { ty, options } => info::Trampoline::StreamRead {
Trampoline::StreamRead {
ty,
err_ctx_ty,
options,
} => info::Trampoline::StreamRead {
ty: *ty,
err_ctx_ty: *err_ctx_ty,
options: self.options(options),
},
Trampoline::StreamWrite { ty, options } => info::Trampoline::StreamWrite {
Expand All @@ -808,12 +825,20 @@ impl LinearizeDfg<'_> {
Trampoline::StreamCloseReadable { ty } => {
info::Trampoline::StreamCloseReadable { ty: *ty }
}
Trampoline::StreamCloseWritable { ty } => {
info::Trampoline::StreamCloseWritable { ty: *ty }
Trampoline::StreamCloseWritable { ty, err_ctx_ty } => {
info::Trampoline::StreamCloseWritable {
ty: *ty,
err_ctx_ty: *err_ctx_ty,
}
}
Trampoline::FutureNew { ty } => info::Trampoline::FutureNew { ty: *ty },
Trampoline::FutureRead { ty, options } => info::Trampoline::FutureRead {
Trampoline::FutureRead {
ty,
err_ctx_ty,
options,
} => info::Trampoline::FutureRead {
ty: *ty,
err_ctx_ty: *err_ctx_ty,
options: self.options(options),
},
Trampoline::FutureWrite { ty, options } => info::Trampoline::FutureWrite {
Expand All @@ -831,8 +856,11 @@ impl LinearizeDfg<'_> {
Trampoline::FutureCloseReadable { ty } => {
info::Trampoline::FutureCloseReadable { ty: *ty }
}
Trampoline::FutureCloseWritable { ty } => {
info::Trampoline::FutureCloseWritable { ty: *ty }
Trampoline::FutureCloseWritable { ty, err_ctx_ty } => {
info::Trampoline::FutureCloseWritable {
ty: *ty,
err_ctx_ty: *err_ctx_ty,
}
}
Trampoline::ErrorContextNew { ty, options } => info::Trampoline::ErrorContextNew {
ty: *ty,
Expand All @@ -849,6 +877,10 @@ impl LinearizeDfg<'_> {
Trampoline::ResourceTransferBorrow => info::Trampoline::ResourceTransferBorrow,
Trampoline::ResourceEnterCall => info::Trampoline::ResourceEnterCall,
Trampoline::ResourceExitCall => info::Trampoline::ResourceExitCall,
Trampoline::SyncEnterCall => info::Trampoline::SyncEnterCall,
Trampoline::SyncExitCall { callback } => info::Trampoline::SyncExitCall {
callback: callback.map(|v| self.runtime_callback(v)),
},
Trampoline::AsyncEnterCall => info::Trampoline::AsyncEnterCall,
Trampoline::AsyncExitCall {
callback,
Expand Down
40 changes: 35 additions & 5 deletions crates/environ/src/component/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,10 @@ pub enum Trampoline {
/// A `task.return` intrinsic, which returns a result to the caller of a
/// lifted export function. This allows the callee to continue executing
/// after returning a result.
TaskReturn,
TaskReturn {
/// Tuple representing the result types this intrinsic accepts.
results: TypeTupleIndex,
},

/// A `task.wait` intrinsic, which waits for at least one outstanding async
/// task/stream/future to make progress, returning the first such event.
Expand Down Expand Up @@ -738,6 +741,10 @@ pub enum Trampoline {
StreamRead {
/// The table index for the specific `stream` type and caller instance.
ty: TypeStreamTableIndex,

/// The table index for the `error-context` type in the caller instance.
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,

/// Any options (e.g. string encoding) to use when storing values to
/// memory.
options: CanonicalOptions,
Expand Down Expand Up @@ -784,6 +791,9 @@ pub enum Trampoline {
StreamCloseWritable {
/// The table index for the specific `stream` type and caller instance.
ty: TypeStreamTableIndex,

/// The table index for the `error-context` type in the caller instance.
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
},

/// A `future.new` intrinsic to create a new `future` handle of the
Expand All @@ -797,6 +807,10 @@ pub enum Trampoline {
FutureRead {
/// The table index for the specific `future` type and caller instance.
ty: TypeFutureTableIndex,

/// The table index for the `error-context` type in the caller instance.
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,

/// Any options (e.g. string encoding) to use when storing values to
/// memory.
options: CanonicalOptions,
Expand Down Expand Up @@ -843,6 +857,9 @@ pub enum Trampoline {
FutureCloseWritable {
/// The table index for the specific `future` type and caller instance.
ty: TypeFutureTableIndex,

/// The table index for the `error-context` type in the caller instance.
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
},

/// A `error-context.new` intrinsic to create a new `error-context` with a
Expand Down Expand Up @@ -890,12 +907,23 @@ pub enum Trampoline {
/// Same as `ResourceEnterCall` except for when exiting a call.
ResourceExitCall,

/// An intrinsic used by FACT-generated modules to begin a call to an
/// An intrinsic used by FACT-generated modules to begin a call involving a
/// sync-lowered import and async-lifted export.
SyncEnterCall,

/// An intrinsic used by FACT-generated modules to complete a call involving
/// a sync-lowered import and async-lifted export.
SyncExitCall {
/// The callee's callback function, if any.
callback: Option<RuntimeCallbackIndex>,
},

/// An intrinsic used by FACT-generated modules to begin a call involving an
/// async-lowered import function.
AsyncEnterCall,

/// An intrinsic used by FACT-generated modules to complete a call to an
/// async-lowered import function.
/// An intrinsic used by FACT-generated modules to complete a call involving
/// an async-lowered import function.
///
/// Note that `AsyncEnterCall` and `AsyncExitCall` could theoretically be
/// combined into a single `AsyncCall` intrinsic, but we separate them to
Expand Down Expand Up @@ -956,7 +984,7 @@ impl Trampoline {
ResourceRep(i) => format!("component-resource-rep[{}]", i.as_u32()),
ResourceDrop(i) => format!("component-resource-drop[{}]", i.as_u32()),
TaskBackpressure { .. } => format!("task-backpressure"),
TaskReturn => format!("task-return"),
TaskReturn { .. } => format!("task-return"),
TaskWait { .. } => format!("task-wait"),
TaskPoll { .. } => format!("task-poll"),
TaskYield { .. } => format!("task-yield"),
Expand All @@ -982,6 +1010,8 @@ impl Trampoline {
ResourceTransferBorrow => format!("component-resource-transfer-borrow"),
ResourceEnterCall => format!("component-resource-enter-call"),
ResourceExitCall => format!("component-resource-exit-call"),
SyncEnterCall => format!("component-sync-enter-call"),
SyncExitCall { .. } => format!("component-sync-exit-call"),
AsyncEnterCall => format!("component-async-enter-call"),
AsyncExitCall { .. } => format!("component-async-exit-call"),
FutureTransfer => format!("future-transfer"),
Expand Down
17 changes: 13 additions & 4 deletions crates/environ/src/component/translate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::collections::HashMap;
use std::mem;
use wasmparser::component_types::{
AliasableResourceId, ComponentCoreModuleTypeId, ComponentDefinedTypeId, ComponentEntityType,
ComponentFuncTypeId, ComponentInstanceTypeId,
ComponentFuncTypeId, ComponentInstanceTypeId, ComponentValType,
};
use wasmparser::types::Types;
use wasmparser::{Chunk, ComponentImportName, Encoding, Parser, Payload, Validator};
Expand Down Expand Up @@ -193,6 +193,7 @@ enum LocalInitializer<'data> {
},
TaskReturn {
func: ModuleInternedTypeIndex,
result: Option<ComponentValType>,
},
TaskWait {
func: ModuleInternedTypeIndex,
Expand Down Expand Up @@ -632,10 +633,18 @@ impl<'a, 'data> Translator<'a, 'data> {
core_func_index += 1;
LocalInitializer::TaskBackpressure { func: core_type }
}
wasmparser::CanonicalFunction::TaskReturn { .. } => {
let core_type = self.core_func_signature(core_func_index)?;
wasmparser::CanonicalFunction::TaskReturn { result } => {
let result = result.map(|ty| match ty {
wasmparser::ComponentValType::Primitive(ty) => {
ComponentValType::Primitive(ty)
}
wasmparser::ComponentValType::Type(ty) => {
ComponentValType::Type(types.component_defined_type_at(ty))
}
});
let func = self.core_func_signature(core_func_index)?;
core_func_index += 1;
LocalInitializer::TaskReturn { func: core_type }
LocalInitializer::TaskReturn { func, result }
}
wasmparser::CanonicalFunction::TaskWait { async_, memory } => {
let func = self.core_func_signature(core_func_index)?;
Expand Down
6 changes: 6 additions & 0 deletions crates/environ/src/component/translate/adapt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,12 @@ fn fact_import_to_core_def(
}
fact::Import::ResourceEnterCall => simple_intrinsic(dfg::Trampoline::ResourceEnterCall),
fact::Import::ResourceExitCall => simple_intrinsic(dfg::Trampoline::ResourceExitCall),
fact::Import::SyncEnterCall => simple_intrinsic(dfg::Trampoline::SyncEnterCall),
fact::Import::SyncExitCall { callback } => {
simple_intrinsic(dfg::Trampoline::SyncExitCall {
callback: callback.clone().map(|v| dfg.callbacks.push(v)),
})
}
fact::Import::AsyncEnterCall => simple_intrinsic(dfg::Trampoline::AsyncEnterCall),
fact::Import::AsyncExitCall {
callback,
Expand Down
Loading