Skip to content

Commit a4b41c6

Browse files
authored
Synchronize some component model intrinsics with the spec (bytecodealliance#2065)
* Synchronize some component model intrinsics with the spec This commit goes through a few component model intrinsics and synchronizes them with the current specification, mainly centered around async intrinsics. This doesn't synchronize all of them but is at least a start. Changes here include: * Support for `resource.drop async` intrinsics. * Renaming `task.backpressure` to `backpressure.set`. * Adding canonical ABI options to `task.return`. * A number of refactorings to simplify some constructs, reduce duplication, etc. The validation of `task.return` has been updated to take WebAssembly/component-model#453 into account with the new set of options that are allowed on it. Additionally `wit-component` was updated to set options for `task.return` in the same manner as the `canon lift`'d function on the other end. * Review comments
1 parent fc75d9b commit a4b41c6

File tree

35 files changed

+641
-348
lines changed

35 files changed

+641
-348
lines changed

crates/wasm-encoder/src/component/builder.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,12 @@ impl ComponentBuilder {
361361
inc(&mut self.core_funcs)
362362
}
363363

364+
/// Declares a new `resource.drop` intrinsic.
365+
pub fn resource_drop_async(&mut self, ty: u32) -> u32 {
366+
self.canonical_functions().resource_drop_async(ty);
367+
inc(&mut self.core_funcs)
368+
}
369+
364370
/// Declares a new `resource.new` intrinsic.
365371
pub fn resource_new(&mut self, ty: u32) -> u32 {
366372
self.canonical_functions().resource_new(ty);
@@ -385,15 +391,19 @@ impl ComponentBuilder {
385391
inc(&mut self.core_funcs)
386392
}
387393

388-
/// Declares a new `task.backpressure` intrinsic.
389-
pub fn task_backpressure(&mut self) -> u32 {
390-
self.canonical_functions().task_backpressure();
394+
/// Declares a new `backpressure.set` intrinsic.
395+
pub fn backpressure_set(&mut self) -> u32 {
396+
self.canonical_functions().backpressure_set();
391397
inc(&mut self.core_funcs)
392398
}
393399

394400
/// Declares a new `task.return` intrinsic.
395-
pub fn task_return(&mut self, ty: Option<impl Into<ComponentValType>>) -> u32 {
396-
self.canonical_functions().task_return(ty);
401+
pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> u32
402+
where
403+
O: IntoIterator<Item = CanonicalOption>,
404+
O::IntoIter: ExactSizeIterator,
405+
{
406+
self.canonical_functions().task_return(ty, options);
397407
inc(&mut self.core_funcs)
398408
}
399409

crates/wasm-encoder/src/component/canonicals.rs

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,10 @@ impl CanonicalFunctionSection {
101101
O: IntoIterator<Item = CanonicalOption>,
102102
O::IntoIter: ExactSizeIterator,
103103
{
104-
let options = options.into_iter();
105104
self.bytes.push(0x00);
106105
self.bytes.push(0x00);
107106
core_func_index.encode(&mut self.bytes);
108-
options.len().encode(&mut self.bytes);
109-
for option in options {
110-
option.encode(&mut self.bytes);
111-
}
107+
self.encode_options(options);
112108
type_index.encode(&mut self.bytes);
113109
self.num_added += 1;
114110
self
@@ -120,14 +116,10 @@ impl CanonicalFunctionSection {
120116
O: IntoIterator<Item = CanonicalOption>,
121117
O::IntoIter: ExactSizeIterator,
122118
{
123-
let options = options.into_iter();
124119
self.bytes.push(0x01);
125120
self.bytes.push(0x00);
126121
func_index.encode(&mut self.bytes);
127-
options.len().encode(&mut self.bytes);
128-
for option in options {
129-
option.encode(&mut self.bytes);
130-
}
122+
self.encode_options(options);
131123
self.num_added += 1;
132124
self
133125
}
@@ -149,6 +141,14 @@ impl CanonicalFunctionSection {
149141
self
150142
}
151143

144+
/// Defines a function which will drop the specified type of handle.
145+
pub fn resource_drop_async(&mut self, ty_index: u32) -> &mut Self {
146+
self.bytes.push(0x07);
147+
ty_index.encode(&mut self.bytes);
148+
self.num_added += 1;
149+
self
150+
}
151+
152152
/// Defines a function which will return the representation of the specified
153153
/// resource type.
154154
pub fn resource_rep(&mut self, ty_index: u32) -> &mut Self {
@@ -179,7 +179,7 @@ impl CanonicalFunctionSection {
179179
/// backpressure for the caller's instance. When backpressure is enabled,
180180
/// the host must not start any new calls to that instance until
181181
/// backpressure is disabled.
182-
pub fn task_backpressure(&mut self) -> &mut Self {
182+
pub fn backpressure_set(&mut self) -> &mut Self {
183183
self.bytes.push(0x08);
184184
self.num_added += 1;
185185
self
@@ -188,15 +188,14 @@ impl CanonicalFunctionSection {
188188
/// Defines a function which returns a result to the caller of a lifted
189189
/// export function. This allows the callee to continue executing after
190190
/// returning a result.
191-
pub fn task_return(&mut self, ty: Option<impl Into<ComponentValType>>) -> &mut Self {
191+
pub fn task_return<O>(&mut self, ty: Option<ComponentValType>, options: O) -> &mut Self
192+
where
193+
O: IntoIterator<Item = CanonicalOption>,
194+
O::IntoIter: ExactSizeIterator,
195+
{
192196
self.bytes.push(0x09);
193-
if let Some(ty) = ty {
194-
self.bytes.push(0x00);
195-
ty.into().encode(&mut self.bytes);
196-
} else {
197-
self.bytes.push(0x01);
198-
0_usize.encode(&mut self.bytes);
199-
}
197+
crate::encode_resultlist(&mut self.bytes, ty);
198+
self.encode_options(options);
200199
self.num_added += 1;
201200
self
202201
}
@@ -261,11 +260,7 @@ impl CanonicalFunctionSection {
261260
{
262261
self.bytes.push(0x0f);
263262
ty.encode(&mut self.bytes);
264-
let options = options.into_iter();
265-
options.len().encode(&mut self.bytes);
266-
for option in options {
267-
option.encode(&mut self.bytes);
268-
}
263+
self.encode_options(options);
269264
self.num_added += 1;
270265
self
271266
}
@@ -278,11 +273,7 @@ impl CanonicalFunctionSection {
278273
{
279274
self.bytes.push(0x10);
280275
ty.encode(&mut self.bytes);
281-
let options = options.into_iter();
282-
options.len().encode(&mut self.bytes);
283-
for option in options {
284-
option.encode(&mut self.bytes);
285-
}
276+
self.encode_options(options);
286277
self.num_added += 1;
287278
self
288279
}
@@ -342,11 +333,7 @@ impl CanonicalFunctionSection {
342333
{
343334
self.bytes.push(0x16);
344335
ty.encode(&mut self.bytes);
345-
let options = options.into_iter();
346-
options.len().encode(&mut self.bytes);
347-
for option in options {
348-
option.encode(&mut self.bytes);
349-
}
336+
self.encode_options(options);
350337
self.num_added += 1;
351338
self
352339
}
@@ -359,11 +346,7 @@ impl CanonicalFunctionSection {
359346
{
360347
self.bytes.push(0x17);
361348
ty.encode(&mut self.bytes);
362-
let options = options.into_iter();
363-
options.len().encode(&mut self.bytes);
364-
for option in options {
365-
option.encode(&mut self.bytes);
366-
}
349+
self.encode_options(options);
367350
self.num_added += 1;
368351
self
369352
}
@@ -414,11 +397,7 @@ impl CanonicalFunctionSection {
414397
O::IntoIter: ExactSizeIterator,
415398
{
416399
self.bytes.push(0x1c);
417-
let options = options.into_iter();
418-
options.len().encode(&mut self.bytes);
419-
for option in options {
420-
option.encode(&mut self.bytes);
421-
}
400+
self.encode_options(options);
422401
self.num_added += 1;
423402
self
424403
}
@@ -434,11 +413,7 @@ impl CanonicalFunctionSection {
434413
O::IntoIter: ExactSizeIterator,
435414
{
436415
self.bytes.push(0x1d);
437-
let options = options.into_iter();
438-
options.len().encode(&mut self.bytes);
439-
for option in options {
440-
option.encode(&mut self.bytes);
441-
}
416+
self.encode_options(options);
442417
self.num_added += 1;
443418
self
444419
}
@@ -449,6 +424,19 @@ impl CanonicalFunctionSection {
449424
self.num_added += 1;
450425
self
451426
}
427+
428+
fn encode_options<O>(&mut self, options: O) -> &mut Self
429+
where
430+
O: IntoIterator<Item = CanonicalOption>,
431+
O::IntoIter: ExactSizeIterator,
432+
{
433+
let options = options.into_iter();
434+
options.len().encode(&mut self.bytes);
435+
for option in options {
436+
option.encode(&mut self.bytes);
437+
}
438+
self
439+
}
452440
}
453441

454442
impl Encode for CanonicalFunctionSection {

crates/wasm-encoder/src/component/types.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -405,20 +405,24 @@ impl<'a> ComponentFuncTypeEncoder<'a> {
405405
assert!(self.params_encoded);
406406
assert!(!self.results_encoded);
407407
self.results_encoded = true;
408-
match ty {
409-
Some(ty) => {
410-
self.sink.push(0x00);
411-
ty.encode(self.sink);
412-
}
413-
None => {
414-
self.sink.push(0x01);
415-
self.sink.push(0x00);
416-
}
417-
}
408+
encode_resultlist(self.sink, ty);
418409
self
419410
}
420411
}
421412

413+
pub(crate) fn encode_resultlist(sink: &mut Vec<u8>, ty: Option<ComponentValType>) {
414+
match ty {
415+
Some(ty) => {
416+
sink.push(0x00);
417+
ty.encode(sink);
418+
}
419+
None => {
420+
sink.push(0x01);
421+
sink.push(0x00);
422+
}
423+
}
424+
}
425+
422426
/// Used to encode component and instance types.
423427
#[derive(Debug)]
424428
pub struct ComponentTypeEncoder<'a>(&'a mut Vec<u8>);

crates/wasm-encoder/src/reencode/component.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,10 @@ pub mod component_utils {
945945
let resource = reencoder.component_type_index(resource);
946946
section.resource_drop(resource);
947947
}
948+
wasmparser::CanonicalFunction::ResourceDropAsync { resource } => {
949+
let resource = reencoder.component_type_index(resource);
950+
section.resource_drop_async(resource);
951+
}
948952
wasmparser::CanonicalFunction::ResourceRep { resource } => {
949953
let resource = reencoder.component_type_index(resource);
950954
section.resource_rep(resource);
@@ -956,11 +960,14 @@ pub mod component_utils {
956960
wasmparser::CanonicalFunction::ThreadAvailableParallelism => {
957961
section.thread_available_parallelism();
958962
}
959-
wasmparser::CanonicalFunction::TaskBackpressure => {
960-
section.task_backpressure();
963+
wasmparser::CanonicalFunction::BackpressureSet => {
964+
section.backpressure_set();
961965
}
962-
wasmparser::CanonicalFunction::TaskReturn { result } => {
963-
section.task_return(result.map(|ty| reencoder.component_val_type(ty)));
966+
wasmparser::CanonicalFunction::TaskReturn { result, options } => {
967+
section.task_return(
968+
result.map(|ty| reencoder.component_val_type(ty)),
969+
options.iter().map(|o| reencoder.canonical_option(*o)),
970+
);
964971
}
965972
wasmparser::CanonicalFunction::TaskWait { async_, memory } => {
966973
section.task_wait(async_, reencoder.memory_index(memory));

0 commit comments

Comments
 (0)