pub struct Component { }
Available on crate features runtime
and component-model
only.
A compiled WebAssembly Component.
This structure represents a compiled component that is ready to be instantiated. This owns a region of virtual memory which contains executable code compiled from a WebAssembly binary originally. This is the analog of Module
in the component embedding API.
A Component
can be turned into an Instance
through a Linker
. Component
s are safe to share across threads. The compilation model of a component is the same as that of a module which is to say:
Component::new
.Component::serialize
.Component::deserialize
.Component::new
returns.Clone
Using clone
on a Component
is a cheap operation. It will not create an entirely new component, but rather just a new reference to the existing component. In other words it’s a shallow copy, not a deep copy.
For example usage see the documentation of Module
as Component
has the same high-level API.
Available on crate features cranelift
or winch
only.
Compiles a new WebAssembly component from the in-memory list of bytes provided.
The bytes
provided can either be the binary or text format of a WebAssembly component. Note that the text format requires the wat
feature of this crate to be enabled. This API does not support streaming compilation.
This function will synchronously validate the entire component, including all core modules, and then compile all components, modules, etc., found within the provided bytes.
§ErrorsThis function may fail and return an error. Errors may include situations such as:
engine
wat
feature is enabled and the input is text, then it may be rejected if it fails to parse.The error returned should contain full information about why compilation failed.
§ExamplesThe new
function can be invoked with a in-memory array of bytes:
let component = Component::new(&engine, &wasm_bytes)?;
Or you can also pass in a string to be parsed as the wasm text format:
let component = Component::new(&engine, "(component (core module))")?;
Source
Available on crate feature std
and (crate features cranelift
or winch
) only.
Compiles a new WebAssembly component from a wasm file on disk pointed to by file
.
This is a convenience function for reading the contents of file
on disk and then calling Component::new
.
Available on crate features cranelift
or winch
only.
Compiles a new WebAssembly component from the in-memory wasm image provided.
This function is the same as Component::new
except that it does not accept the text format of WebAssembly. Even if the wat
feature is enabled an error will be returned here if binary
is the text format.
For more information on semantics and errors see Component::new
.
Same as Module::deserialize_raw
, but for components.
See Component::deserialize
for additional information; this method works identically except that it will not create a copy of the provided memory but will use it directly.
All of the safety notes from Component::deserialize
apply here as well with the additional constraint that the code memory provide by memory
lives for as long as the module and is nevery externally modified for the lifetime of the deserialized module.
Available on crate feature std
only.
Returns the type of this component as a types::Component
.
This method enables runtime introspection of the type of a component before instantiation, if necessary.
§Component types and ResourcesAn important point to note here is that the precise type of imports and exports of a component change when it is instantiated with respect to resources. For example a Component
represents an un-instantiated component meaning that its imported resources are represented as abstract resource types. These abstract types are not equal to any other component’s types.
For example:
let a = Component::new(&engine, r#"
(component (import "x" (type (sub resource))))
"#)?;
let b = Component::new(&engine, r#"
(component (import "x" (type (sub resource))))
"#)?;
let (_, a_ty) = a.component_type().imports(&engine).next().unwrap();
let (_, b_ty) = b.component_type().imports(&engine).next().unwrap();
let a_ty = match a_ty {
ComponentItem::Resource(ty) => ty,
_ => unreachable!(),
};
let b_ty = match b_ty {
ComponentItem::Resource(ty) => ty,
_ => unreachable!(),
};
assert!(a_ty != b_ty);
Additionally, however, these abstract types are “substituted” during instantiation meaning that a component type will appear to have changed once it is instantiated.
let a = Component::new(&engine, r#"
(component
(import "x" (type $x (sub resource)))
(export "x" (type $x))
)
"#)?;
let (_, import) = a.component_type().imports(&engine).next().unwrap();
let (_, export) = a.component_type().exports(&engine).next().unwrap();
let import = match import {
ComponentItem::Resource(ty) => ty,
_ => unreachable!(),
};
let export = match export {
ComponentItem::Resource(ty) => ty,
_ => unreachable!(),
};
assert_eq!(import, export);
let mut store = Store::new(&engine, ());
let mut linker = Linker::new(&engine);
linker.root().resource("x", ResourceType::host::<()>(), |_, _| Ok(()))?;
let instance = linker.instantiate(&mut store, &a)?;
let instance_ty = instance.get_resource(&mut store, "x").unwrap();
assert!(instance_ty != import);
assert!(instance_ty != export);
assert!(instance_ty == ResourceType::host::<()>());
Finally, each instantiation of an exported resource from a component is considered “fresh” for all instantiations meaning that different instantiations will have different exported resource types:
let a = Component::new(&engine, r#"
(component
(type $x (resource (rep i32)))
(export "x" (type $x))
)
"#)?;
let mut store = Store::new(&engine, ());
let linker = Linker::new(&engine);
let instance1 = linker.instantiate(&mut store, &a)?;
let instance2 = linker.instantiate(&mut store, &a)?;
let x1 = instance1.get_resource(&mut store, "x").unwrap();
let x2 = instance2.get_resource(&mut store, "x").unwrap();
assert!(x1 != x2);
Source Source
Returns a summary of the resources required to instantiate this Component
.
Note that when a component imports and instantiates another component or core module, we cannot determine ahead of time how many resources instantiating this component will require, and therefore this method will return None
in these scenarios.
Potential uses of the returned information:
Determining whether your pooling allocator configuration supports instantiating this component.
Deciding how many of which Component
you want to instantiate within a fixed amount of resources, e.g. determining whether to create 5 instances of component X or 10 instances of component Y.
use wasmtime::{Config, Engine, component::Component};
let mut config = Config::new();
config.wasm_multi_memory(true);
config.wasm_component_model(true);
let engine = Engine::new(&config)?;
let component = Component::new(&engine, &r#"
(component
;; Define a core module that uses two memories.
(core module $m
(memory 1)
(memory 6)
)
;; Instantiate that core module three times.
(core instance $i1 (instantiate (module $m)))
(core instance $i2 (instantiate (module $m)))
(core instance $i3 (instantiate (module $m)))
)
"#)?;
let resources = component.resources_required()
.expect("this component does not import any core modules or instances");
assert_eq!(resources.num_memories, 6);
assert_eq!(resources.max_initial_memory_size, Some(6));
assert_eq!(resources.num_tables, 0);
assert_eq!(resources.max_initial_table_size, None);
Source
Returns the range, in the host’s address space, that this module’s compiled code resides at.
For more information see Module::image_range
.
Force initialization of copy-on-write images to happen here-and-now instead of when they’re requested during first instantiation.
When copy-on-write memory initialization is enabled then Wasmtime will lazily create the initialization image for a component. This method can be used to explicitly dictate when this initialization happens.
Note that this largely only matters on Linux when memfd is used. Otherwise the copy-on-write image typically comes from disk and in that situation the creation of the image is trivial as the image is always sourced from disk. On Linux, though, when memfd is used a memfd is created and the initialization image is written to it.
Also note that this method is not required to be called, it’s available as a performance optimization if required but is otherwise handled automatically.
Source SourceLooks up a specific export of this component by name
optionally nested within the instance
provided.
This method is primarily used to acquire a ComponentExportIndex
which can be used with Instance
when looking up exports. Export lookup with ComponentExportIndex
can skip string lookups at runtime and instead use a more efficient index-based lookup.
This method takes a few arguments:
engine
- the engine that was used to compile this component.instance
- an optional “parent instance” for the export being looked up. If this is None
then the export is looked up on the root of the component itself, and otherwise the export is looked up on the instance
specified. Note that instance
must have come from a previous invocation of this method.name
- the name of the export that’s being looked up.If the export is located then two values are returned: a types::ComponentItem
which enables introspection about the type of the export and a ComponentExportIndex
. The index returned notably implements the InstanceExportLookup
trait which enables using it with Instance::get_func
for example.
The returned types::ComponentItem
is more expensive to calculate than the ComponentExportIndex
. If you only consume the ComponentExportIndex
, use the related method Self::get_export_index
instead.
Instance
has a corresponding method Instance::get_export
.
use wasmtime::{Engine, Store};
use wasmtime::component::{Component, Linker};
use wasmtime::component::types::ComponentItem;
let engine = Engine::default();
let component = Component::new(
&engine,
r#"
(component
(core module $m
(func (export "f"))
)
(core instance $i (instantiate $m))
(func (export "f")
(canon lift (core func $i "f")))
)
"#,
)?;
let (ty, export) = component.get_export(None, "f").unwrap();
assert!(matches!(ty, ComponentItem::ComponentFunc(_)));
let mut store = Store::new(&engine, ());
let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
let func = instance.get_typed_func::<(), ()>(&mut store, &export)?;
Source
Returns the Engine
that this Component
was compiled by.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4