|
2 | 2 | #![allow(static_mut_refs)]
|
3 | 3 |
|
4 | 4 | extern crate std;
|
5 |
| - |
6 |
| -use { |
7 |
| - futures::{ |
8 |
| - channel::oneshot, |
9 |
| - future::FutureExt, |
10 |
| - stream::{FuturesUnordered, StreamExt}, |
11 |
| - }, |
12 |
| - once_cell::sync::Lazy, |
13 |
| - std::{ |
14 |
| - alloc::{self, Layout}, |
15 |
| - any::Any, |
16 |
| - boxed::Box, |
17 |
| - collections::hash_map, |
18 |
| - collections::HashMap, |
19 |
| - fmt::{self, Debug, Display}, |
20 |
| - future::Future, |
21 |
| - pin::Pin, |
22 |
| - ptr, |
23 |
| - sync::Arc, |
24 |
| - task::{Context, Poll, Wake, Waker}, |
25 |
| - vec::Vec, |
26 |
| - }, |
27 |
| -}; |
| 5 | +use std::alloc::{self, Layout}; |
| 6 | +use std::any::Any; |
| 7 | +use std::boxed::Box; |
| 8 | +use std::collections::{hash_map, HashMap}; |
| 9 | +use std::fmt::{self, Debug, Display}; |
| 10 | +use std::future::Future; |
| 11 | +use std::pin::Pin; |
| 12 | +use std::ptr; |
| 13 | +use std::string::String; |
| 14 | +use std::sync::Arc; |
| 15 | +use std::task::{Context, Poll, Wake, Waker}; |
| 16 | +use std::vec::Vec; |
| 17 | + |
| 18 | +use futures::channel::oneshot; |
| 19 | +use futures::future::FutureExt; |
| 20 | +use futures::stream::{FuturesUnordered, StreamExt}; |
| 21 | +use once_cell::sync::Lazy; |
28 | 22 |
|
29 | 23 | mod future_support;
|
30 | 24 | mod stream_support;
|
@@ -330,6 +324,31 @@ impl ErrorContext {
|
330 | 324 | pub fn handle(&self) -> u32 {
|
331 | 325 | self.handle
|
332 | 326 | }
|
| 327 | + |
| 328 | + /// Extract the debug message from a given [`ErrorContext`] |
| 329 | + pub fn debug_message(&self) -> String { |
| 330 | + #[cfg(not(target_arch = "wasm32"))] |
| 331 | + { |
| 332 | + _ = self; |
| 333 | + unreachable!(); |
| 334 | + } |
| 335 | + |
| 336 | + #[cfg(target_arch = "wasm32")] |
| 337 | + { |
| 338 | + #[link(wasm_import_module = "$root")] |
| 339 | + extern "C" { |
| 340 | + #[link_name = "[error-context-debug-message;encoding=utf8;realloc=cabi_realloc]"] |
| 341 | + fn error_context_debug_message(_: u32, _: *mut u8); |
| 342 | + } |
| 343 | + |
| 344 | + unsafe { |
| 345 | + let mut ret = [0u32; 2]; |
| 346 | + error_context_debug_message(self.handle, ret.as_mut_ptr() as *mut _); |
| 347 | + let len = usize::try_from(ret[1]).unwrap(); |
| 348 | + String::from_raw_parts(usize::try_from(ret[0]).unwrap() as *mut _, len, len) |
| 349 | + } |
| 350 | + } |
| 351 | + } |
333 | 352 | }
|
334 | 353 |
|
335 | 354 | impl Debug for ErrorContext {
|
@@ -469,3 +488,28 @@ pub fn task_backpressure(enabled: bool) {
|
469 | 488 | }
|
470 | 489 | }
|
471 | 490 | }
|
| 491 | + |
| 492 | +/// Call the `error-context.new` canonical built-in function. |
| 493 | +pub fn error_context_new(debug_message: &str) -> ErrorContext { |
| 494 | + #[cfg(not(target_arch = "wasm32"))] |
| 495 | + { |
| 496 | + _ = debug_message; |
| 497 | + unreachable!(); |
| 498 | + } |
| 499 | + |
| 500 | + #[cfg(target_arch = "wasm32")] |
| 501 | + { |
| 502 | + #[link(wasm_import_module = "$root")] |
| 503 | + extern "C" { |
| 504 | + #[link_name = "[error-context-new;encoding=utf8]"] |
| 505 | + fn context_new(_: *const u8, _: usize) -> i32; |
| 506 | + } |
| 507 | + |
| 508 | + unsafe { |
| 509 | + let handle = context_new(debug_message.as_ptr(), debug_message.len()); |
| 510 | + // SAFETY: Handles (including error context handles are guaranteed to |
| 511 | + // fit inside u32 by the Component Model ABI |
| 512 | + ErrorContext::from_handle(u32::try_from(handle).unwrap()) |
| 513 | + } |
| 514 | + } |
| 515 | +} |
0 commit comments