Skip to content

Commit 4611d5c

Browse files
feat: add error impl for streams (#4)
* feat: add error impl for stream/future closure This commit adds the implementation for error propagation during stream/future closure. When streams are closed on write, they have the option to send an error context that should be seen by the reader on the next read. Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * refactor: facilitate host read returning error context Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * fix: pass error context type for component through Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * fix: pass through error context type in more places Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * chore: improve invalid handle error messages Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * wip: clarify comments around global error context management Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * wip: finish up edge cases Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * chore: remove irrelevant comment Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * fix: remove unneeded ref translation Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * fix: remove unused err_ctx_ty Signed-off-by: Victor Adossi <vadossi@cosmonic.com> * fix: comment regarding writer and error context Co-authored-by: Joel Dice <joel.dice@fermyon.com> * fix: remove unused err_ctx_ty future/stream/flat_stream write Signed-off-by: Victor Adossi <vadossi@cosmonic.com> --------- Signed-off-by: Victor Adossi <vadossi@cosmonic.com> Co-authored-by: Joel Dice <joel.dice@fermyon.com>
1 parent d1596df commit 4611d5c

File tree

6 files changed

+519
-152
lines changed

6 files changed

+519
-152
lines changed

crates/cranelift/src/compiler/component.rs

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,17 @@ impl<'a> TrampolineCompiler<'a> {
124124
Trampoline::TaskYield { async_ } => self.translate_task_yield_call(*async_),
125125
Trampoline::SubtaskDrop { instance } => self.translate_subtask_drop_call(*instance),
126126
Trampoline::StreamNew { ty } => self.translate_future_or_stream_call(
127-
ty.as_u32(),
127+
&[ty.as_u32()],
128128
None,
129129
self.offsets.stream_new(),
130130
Vec::new(),
131131
ir::types::I64,
132132
),
133-
Trampoline::StreamRead { ty, options } => {
133+
Trampoline::StreamRead {
134+
ty,
135+
err_ctx_ty,
136+
options,
137+
} => {
134138
if let Some(info) = self.flat_stream_element_info(*ty) {
135139
self.translate_flat_stream_call(
136140
*ty,
@@ -140,7 +144,7 @@ impl<'a> TrampolineCompiler<'a> {
140144
)
141145
} else {
142146
self.translate_future_or_stream_call(
143-
ty.as_u32(),
147+
&[ty.as_u32(), err_ctx_ty.as_u32()],
144148
Some(options),
145149
self.offsets.stream_read(),
146150
vec![
@@ -162,7 +166,7 @@ impl<'a> TrampolineCompiler<'a> {
162166
)
163167
} else {
164168
self.translate_future_or_stream_call(
165-
ty.as_u32(),
169+
&[ty.as_u32()],
166170
Some(options),
167171
self.offsets.stream_write(),
168172
vec![
@@ -181,31 +185,36 @@ impl<'a> TrampolineCompiler<'a> {
181185
self.translate_cancel_call(ty.as_u32(), *async_, self.offsets.stream_cancel_write())
182186
}
183187
Trampoline::StreamCloseReadable { ty } => self.translate_future_or_stream_call(
184-
ty.as_u32(),
188+
&[ty.as_u32()],
185189
None,
186190
self.offsets.stream_close_readable(),
187191
vec![ir::AbiParam::new(ir::types::I32)],
188192
ir::types::I8,
189193
),
190-
Trampoline::StreamCloseWritable { ty } => self.translate_future_or_stream_call(
191-
ty.as_u32(),
192-
None,
193-
self.offsets.stream_close_writable(),
194-
vec![
195-
ir::AbiParam::new(ir::types::I32),
196-
ir::AbiParam::new(ir::types::I32),
197-
],
198-
ir::types::I8,
199-
),
194+
Trampoline::StreamCloseWritable { ty, err_ctx_ty } => self
195+
.translate_future_or_stream_call(
196+
&[ty.as_u32(), err_ctx_ty.as_u32()],
197+
None,
198+
self.offsets.stream_close_writable(),
199+
vec![
200+
ir::AbiParam::new(ir::types::I32),
201+
ir::AbiParam::new(ir::types::I32),
202+
],
203+
ir::types::I8,
204+
),
200205
Trampoline::FutureNew { ty } => self.translate_future_or_stream_call(
201-
ty.as_u32(),
206+
&[ty.as_u32()],
202207
None,
203208
self.offsets.future_new(),
204209
Vec::new(),
205210
ir::types::I64,
206211
),
207-
Trampoline::FutureRead { ty, options } => self.translate_future_or_stream_call(
208-
ty.as_u32(),
212+
Trampoline::FutureRead {
213+
ty,
214+
err_ctx_ty,
215+
options,
216+
} => self.translate_future_or_stream_call(
217+
&[ty.as_u32(), err_ctx_ty.as_u32()],
209218
Some(&options),
210219
self.offsets.future_read(),
211220
vec![
@@ -215,7 +224,7 @@ impl<'a> TrampolineCompiler<'a> {
215224
ir::types::I64,
216225
),
217226
Trampoline::FutureWrite { ty, options } => self.translate_future_or_stream_call(
218-
ty.as_u32(),
227+
&[ty.as_u32()],
219228
Some(options),
220229
self.offsets.future_write(),
221230
vec![
@@ -231,22 +240,23 @@ impl<'a> TrampolineCompiler<'a> {
231240
self.translate_cancel_call(ty.as_u32(), *async_, self.offsets.future_cancel_write())
232241
}
233242
Trampoline::FutureCloseReadable { ty } => self.translate_future_or_stream_call(
234-
ty.as_u32(),
243+
&[ty.as_u32()],
235244
None,
236245
self.offsets.future_close_readable(),
237246
vec![ir::AbiParam::new(ir::types::I32)],
238247
ir::types::I8,
239248
),
240-
Trampoline::FutureCloseWritable { ty } => self.translate_future_or_stream_call(
241-
ty.as_u32(),
242-
None,
243-
self.offsets.future_close_writable(),
244-
vec![
245-
ir::AbiParam::new(ir::types::I32),
246-
ir::AbiParam::new(ir::types::I32),
247-
],
248-
ir::types::I8,
249-
),
249+
Trampoline::FutureCloseWritable { ty, err_ctx_ty } => self
250+
.translate_future_or_stream_call(
251+
&[ty.as_u32(), err_ctx_ty.as_u32()],
252+
None,
253+
self.offsets.future_close_writable(),
254+
vec![
255+
ir::AbiParam::new(ir::types::I32),
256+
ir::AbiParam::new(ir::types::I32),
257+
],
258+
ir::types::I8,
259+
),
250260
Trampoline::ErrorContextNew { ty, options } => self.translate_error_context_call(
251261
*ty,
252262
options,
@@ -1109,7 +1119,7 @@ impl<'a> TrampolineCompiler<'a> {
11091119

11101120
fn translate_future_or_stream_call(
11111121
&mut self,
1112-
ty: u32,
1122+
tys: &[u32],
11131123
options: Option<&CanonicalOptions>,
11141124
offset: u32,
11151125
params: Vec<ir::AbiParam>,
@@ -1165,7 +1175,10 @@ impl<'a> TrampolineCompiler<'a> {
11651175
}
11661176

11671177
host_sig.params.push(ir::AbiParam::new(ir::types::I32));
1168-
host_args.push(self.builder.ins().iconst(ir::types::I32, i64::from(ty)));
1178+
1179+
for ty in tys {
1180+
host_args.push(self.builder.ins().iconst(ir::types::I32, i64::from(*ty)));
1181+
}
11691182

11701183
host_sig.params.extend(params);
11711184
host_args.extend(args[2..].iter().copied());

crates/environ/src/component/dfg.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ pub enum Trampoline {
308308
},
309309
StreamRead {
310310
ty: TypeStreamTableIndex,
311+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
311312
options: CanonicalOptions,
312313
},
313314
StreamWrite {
@@ -327,12 +328,14 @@ pub enum Trampoline {
327328
},
328329
StreamCloseWritable {
329330
ty: TypeStreamTableIndex,
331+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
330332
},
331333
FutureNew {
332334
ty: TypeFutureTableIndex,
333335
},
334336
FutureRead {
335337
ty: TypeFutureTableIndex,
338+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
336339
options: CanonicalOptions,
337340
},
338341
FutureWrite {
@@ -352,6 +355,7 @@ pub enum Trampoline {
352355
},
353356
FutureCloseWritable {
354357
ty: TypeFutureTableIndex,
358+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
355359
},
356360
ErrorContextNew {
357361
ty: TypeComponentLocalErrorContextTableIndex,
@@ -789,8 +793,13 @@ impl LinearizeDfg<'_> {
789793
instance: *instance,
790794
},
791795
Trampoline::StreamNew { ty } => info::Trampoline::StreamNew { ty: *ty },
792-
Trampoline::StreamRead { ty, options } => info::Trampoline::StreamRead {
796+
Trampoline::StreamRead {
797+
ty,
798+
err_ctx_ty,
799+
options,
800+
} => info::Trampoline::StreamRead {
793801
ty: *ty,
802+
err_ctx_ty: *err_ctx_ty,
794803
options: self.options(options),
795804
},
796805
Trampoline::StreamWrite { ty, options } => info::Trampoline::StreamWrite {
@@ -808,12 +817,20 @@ impl LinearizeDfg<'_> {
808817
Trampoline::StreamCloseReadable { ty } => {
809818
info::Trampoline::StreamCloseReadable { ty: *ty }
810819
}
811-
Trampoline::StreamCloseWritable { ty } => {
812-
info::Trampoline::StreamCloseWritable { ty: *ty }
820+
Trampoline::StreamCloseWritable { ty, err_ctx_ty } => {
821+
info::Trampoline::StreamCloseWritable {
822+
ty: *ty,
823+
err_ctx_ty: *err_ctx_ty,
824+
}
813825
}
814826
Trampoline::FutureNew { ty } => info::Trampoline::FutureNew { ty: *ty },
815-
Trampoline::FutureRead { ty, options } => info::Trampoline::FutureRead {
827+
Trampoline::FutureRead {
828+
ty,
829+
err_ctx_ty,
830+
options,
831+
} => info::Trampoline::FutureRead {
816832
ty: *ty,
833+
err_ctx_ty: *err_ctx_ty,
817834
options: self.options(options),
818835
},
819836
Trampoline::FutureWrite { ty, options } => info::Trampoline::FutureWrite {
@@ -831,8 +848,11 @@ impl LinearizeDfg<'_> {
831848
Trampoline::FutureCloseReadable { ty } => {
832849
info::Trampoline::FutureCloseReadable { ty: *ty }
833850
}
834-
Trampoline::FutureCloseWritable { ty } => {
835-
info::Trampoline::FutureCloseWritable { ty: *ty }
851+
Trampoline::FutureCloseWritable { ty, err_ctx_ty } => {
852+
info::Trampoline::FutureCloseWritable {
853+
ty: *ty,
854+
err_ctx_ty: *err_ctx_ty,
855+
}
836856
}
837857
Trampoline::ErrorContextNew { ty, options } => info::Trampoline::ErrorContextNew {
838858
ty: *ty,

crates/environ/src/component/info.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,10 @@ pub enum Trampoline {
738738
StreamRead {
739739
/// The table index for the specific `stream` type and caller instance.
740740
ty: TypeStreamTableIndex,
741+
742+
/// The table index for the `error-context` type in the caller instance.
743+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
744+
741745
/// Any options (e.g. string encoding) to use when storing values to
742746
/// memory.
743747
options: CanonicalOptions,
@@ -784,6 +788,9 @@ pub enum Trampoline {
784788
StreamCloseWritable {
785789
/// The table index for the specific `stream` type and caller instance.
786790
ty: TypeStreamTableIndex,
791+
792+
/// The table index for the `error-context` type in the caller instance.
793+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
787794
},
788795

789796
/// A `future.new` intrinsic to create a new `future` handle of the
@@ -797,6 +804,10 @@ pub enum Trampoline {
797804
FutureRead {
798805
/// The table index for the specific `future` type and caller instance.
799806
ty: TypeFutureTableIndex,
807+
808+
/// The table index for the `error-context` type in the caller instance.
809+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
810+
800811
/// Any options (e.g. string encoding) to use when storing values to
801812
/// memory.
802813
options: CanonicalOptions,
@@ -843,6 +854,9 @@ pub enum Trampoline {
843854
FutureCloseWritable {
844855
/// The table index for the specific `future` type and caller instance.
845856
ty: TypeFutureTableIndex,
857+
858+
/// The table index for the `error-context` type in the caller instance.
859+
err_ctx_ty: TypeComponentLocalErrorContextTableIndex,
846860
},
847861

848862
/// A `error-context.new` intrinsic to create a new `error-context` with a

crates/environ/src/component/translate/inline.rs

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -754,12 +754,17 @@ impl<'a> Inliner<'a> {
754754
else {
755755
unreachable!()
756756
};
757+
let err_ctx_ty = types.error_context_table_type()?;
757758
let options = self.adapter_options(frame, types, options);
758759
let options = self.canonical_options(options);
759-
let index = self
760-
.result
761-
.trampolines
762-
.push((*func, dfg::Trampoline::StreamRead { ty, options }));
760+
let index = self.result.trampolines.push((
761+
*func,
762+
dfg::Trampoline::StreamRead {
763+
ty,
764+
err_ctx_ty,
765+
options,
766+
},
767+
));
763768
frame.funcs.push(dfg::CoreDef::Trampoline(index));
764769
}
765770
StreamWrite { ty, func, options } => {
@@ -824,10 +829,11 @@ impl<'a> Inliner<'a> {
824829
else {
825830
unreachable!()
826831
};
827-
let index = self
828-
.result
829-
.trampolines
830-
.push((*func, dfg::Trampoline::StreamCloseWritable { ty }));
832+
let err_ctx_ty = types.error_context_table_type()?;
833+
let index = self.result.trampolines.push((
834+
*func,
835+
dfg::Trampoline::StreamCloseWritable { ty, err_ctx_ty },
836+
));
831837
frame.funcs.push(dfg::CoreDef::Trampoline(index));
832838
}
833839
FutureNew { ty, func } => {
@@ -848,12 +854,17 @@ impl<'a> Inliner<'a> {
848854
else {
849855
unreachable!()
850856
};
857+
let err_ctx_ty = types.error_context_table_type()?;
851858
let options = self.adapter_options(frame, types, options);
852859
let options = self.canonical_options(options);
853-
let index = self
854-
.result
855-
.trampolines
856-
.push((*func, dfg::Trampoline::FutureRead { ty, options }));
860+
let index = self.result.trampolines.push((
861+
*func,
862+
dfg::Trampoline::FutureRead {
863+
ty,
864+
err_ctx_ty,
865+
options,
866+
},
867+
));
857868
frame.funcs.push(dfg::CoreDef::Trampoline(index));
858869
}
859870
FutureWrite { ty, func, options } => {
@@ -918,10 +929,11 @@ impl<'a> Inliner<'a> {
918929
else {
919930
unreachable!()
920931
};
921-
let index = self
922-
.result
923-
.trampolines
924-
.push((*func, dfg::Trampoline::FutureCloseWritable { ty }));
932+
let err_ctx_ty = types.error_context_table_type()?;
933+
let index = self.result.trampolines.push((
934+
*func,
935+
dfg::Trampoline::FutureCloseWritable { ty, err_ctx_ty },
936+
));
925937
frame.funcs.push(dfg::CoreDef::Trampoline(index));
926938
}
927939
ErrorContextNew { func, options } => {

0 commit comments

Comments
 (0)