diff options
author | Casper Beyer <caspervonb@pm.me> | 2020-12-04 02:57:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-03 19:57:35 +0100 |
commit | 0ea1c6f5b07e18dad60bca5f1c7631be5b5005b3 (patch) | |
tree | afee2a181dc7d2e78cb84c53764d7f9544d1ee43 /std/wasi/snapshot_preview1.ts | |
parent | de036e1f08dad4c5d0c6641f1942750558e3e787 (diff) |
feat(std/wasi): add return on exit option (#8605)
This adds an exitOnReturn option to context making it
possible to unwind the stack on the exit(2) syscall
instead of delegating to it directly.
Use case is being able to treat WASI execution contexts
as children that don't kill the parent on exit.
Diffstat (limited to 'std/wasi/snapshot_preview1.ts')
-rw-r--r-- | std/wasi/snapshot_preview1.ts | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/std/wasi/snapshot_preview1.ts b/std/wasi/snapshot_preview1.ts index 4c974fe1d..30756fe82 100644 --- a/std/wasi/snapshot_preview1.ts +++ b/std/wasi/snapshot_preview1.ts @@ -207,6 +207,10 @@ function syscall<T extends CallableFunction>(target: T) { try { return target(...args); } catch (err) { + if (err instanceof ExitStatus) { + throw err; + } + switch (err.name) { case "NotFound": return ERRNO_NOENT; @@ -266,15 +270,25 @@ interface FileDescriptor { entries?: Deno.DirEntry[]; } +export class ExitStatus { + code: number; + + constructor(code: number) { + this.code = code; + } +} + export interface ContextOptions { args?: string[]; env?: { [key: string]: string | undefined }; preopens?: { [key: string]: string }; + exitOnReturn?: boolean; } export default class Context { args: string[]; env: { [key: string]: string | undefined }; + exitOnReturn: boolean; memory: WebAssembly.Memory; fds: FileDescriptor[]; @@ -284,6 +298,7 @@ export default class Context { constructor(options: ContextOptions) { this.args = options.args ? options.args : []; this.env = options.env ? options.env : {}; + this.exitOnReturn = options.exitOnReturn ?? true; this.memory = null!; this.fds = [ @@ -1497,7 +1512,11 @@ export default class Context { "proc_exit": syscall(( rval: number, ): never => { - Deno.exit(rval); + if (this.exitOnReturn) { + Deno.exit(rval); + } + + throw new ExitStatus(rval); }), "proc_raise": syscall(( |