Skip to content

Commit

Permalink
Minor refactorings for ErrorContext
Browse files Browse the repository at this point in the history
* Rename `error_context_new` to `ErrorContext::new`.
* Add `debug_message()` to `Display`/`Debug` impls.
* Remove some panics on native which might otherwise be confusing.
* Use a more typed-version of `error_context_debug_message` with fewer
  casts necessary.
  • Loading branch information
alexcrichton committed Mar 3, 2025
1 parent e0d2b88 commit ce6d976
Showing 1 changed file with 42 additions and 39 deletions.
81 changes: 42 additions & 39 deletions crates/guest-rust/rt/src/async_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,31 @@ pub struct ErrorContext {
}

impl ErrorContext {
/// Call the `error-context.new` canonical built-in function.
pub fn new(debug_message: &str) -> ErrorContext {
#[cfg(not(target_arch = "wasm32"))]
{
_ = debug_message;
unreachable!();
}

#[cfg(target_arch = "wasm32")]
{
#[link(wasm_import_module = "$root")]
extern "C" {
#[link_name = "[error-context-new;encoding=utf8]"]
fn context_new(_: *const u8, _: usize) -> i32;
}

unsafe {
let handle = context_new(debug_message.as_ptr(), debug_message.len());
// SAFETY: Handles (including error context handles are guaranteed to
// fit inside u32 by the Component Model ABI
ErrorContext::from_handle(u32::try_from(handle).unwrap())
}
}
}

#[doc(hidden)]
pub fn from_handle(handle: u32) -> Self {
Self { handle }
Expand All @@ -380,49 +405,52 @@ impl ErrorContext {
pub fn debug_message(&self) -> String {
#[cfg(not(target_arch = "wasm32"))]
{
_ = self;
unreachable!();
String::from("<no debug message on native hosts>")
}

#[cfg(target_arch = "wasm32")]
{
#[repr(C)]
struct RetPtr {
ptr: *mut u8,
len: usize,
}
#[link(wasm_import_module = "$root")]
extern "C" {
#[link_name = "[error-context-debug-message;encoding=utf8;realloc=cabi_realloc]"]
fn error_context_debug_message(_: u32, _: *mut u8);
fn error_context_debug_message(_: u32, _: &mut RetPtr);
}

unsafe {
let mut ret = [0u32; 2];
error_context_debug_message(self.handle, ret.as_mut_ptr() as *mut _);
let len = usize::try_from(ret[1]).unwrap();
String::from_raw_parts(usize::try_from(ret[0]).unwrap() as *mut _, len, len)
let mut ret = RetPtr {
ptr: ptr::null_mut(),
len: 0,
};
error_context_debug_message(self.handle, &mut ret);
String::from_raw_parts(ret.ptr, ret.len, ret.len)
}
}
}
}

impl Debug for ErrorContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ErrorContext").finish()
f.debug_struct("ErrorContext")
.field("debug_message", &self.debug_message())
.finish()
}
}

impl Display for ErrorContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Error")
Display::fmt(&self.debug_message(), f)
}
}

impl std::error::Error for ErrorContext {}

impl Drop for ErrorContext {
fn drop(&mut self) {
#[cfg(not(target_arch = "wasm32"))]
{
unreachable!();
}

#[cfg(target_arch = "wasm32")]
{
#[link(wasm_import_module = "$root")]
Expand Down Expand Up @@ -539,28 +567,3 @@ pub fn task_backpressure(enabled: bool) {
}
}
}

/// Call the `error-context.new` canonical built-in function.
pub fn error_context_new(debug_message: &str) -> ErrorContext {
#[cfg(not(target_arch = "wasm32"))]
{
_ = debug_message;
unreachable!();
}

#[cfg(target_arch = "wasm32")]
{
#[link(wasm_import_module = "$root")]
extern "C" {
#[link_name = "[error-context-new;encoding=utf8]"]
fn context_new(_: *const u8, _: usize) -> i32;
}

unsafe {
let handle = context_new(debug_message.as_ptr(), debug_message.len());
// SAFETY: Handles (including error context handles are guaranteed to
// fit inside u32 by the Component Model ABI
ErrorContext::from_handle(u32::try_from(handle).unwrap())
}
}
}

0 comments on commit ce6d976

Please sign in to comment.