// Package sys includes constants and types used by both public and internal APIs.
package sys import ( ) // These two special exit codes are reserved by wazero for context Cancel and Timeout integrations. // The assumption here is that well-behaving Wasm programs won't use these two exit codes. const ( // ExitCodeContextCanceled corresponds to context.Canceled and returned by ExitError.ExitCode in that case. ExitCodeContextCanceled uint32 = 0xffffffff // ExitCodeDeadlineExceeded corresponds to context.DeadlineExceeded and returned by ExitError.ExitCode in that case. ExitCodeDeadlineExceeded uint32 = 0xefffffff ) // ExitError is returned to a caller of api.Function when api.Module CloseWithExitCode was invoked, // or context.Context passed to api.Function Call was canceled or reached the Timeout. // // ExitCode zero value means success while any other value is an error. // // Here's an example of how to get the exit code: // // main := module.ExportedFunction("main") // if err := main(ctx); err != nil { // if exitErr, ok := err.(*sys.ExitError); ok { // // This means your module exited with non-zero code! // } // --snip-- // // Note: While possible the reason of this was "proc_exit" from "wasi_snapshot_preview1", it could be from other host // functions, for example an AssemblyScript's abort handler, or any arbitrary caller of CloseWithExitCode. // // See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#proc_exit and // https://www.assemblyscript.org/concepts.html#special-imports // // Note: In the case of context cancellation or timeout, the api.Module from which the api.Function created is closed. type ExitError struct { // Note: this is a struct not a uint32 type as it was originally one and // we don't want to break call-sites that cast into it. exitCode uint32 } var exitZero = &ExitError{} func ( uint32) *ExitError { if == 0 { return exitZero } return &ExitError{exitCode: } } // ExitCode returns zero on success, and an arbitrary value otherwise. func ( *ExitError) () uint32 { return .exitCode } // Error implements the error interface. func ( *ExitError) () string { switch .exitCode { case ExitCodeContextCanceled: return fmt.Sprintf("module closed with %s", context.Canceled) case ExitCodeDeadlineExceeded: return fmt.Sprintf("module closed with %s", context.DeadlineExceeded) default: return fmt.Sprintf("module closed with exit_code(%d)", .exitCode) } } // Is allows use via errors.Is func ( *ExitError) ( error) bool { if , := .(*ExitError); { return .exitCode == .exitCode } if .exitCode == ExitCodeContextCanceled && == context.Canceled { return true } if .exitCode == ExitCodeDeadlineExceeded && == context.DeadlineExceeded { return true } return false }