|
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