0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

feat(std/wasi): add start method to Context (#8141)

This adds a start method to the Context to make starting a command less
tedious and yield consistent errors.

Manually setting the memory is still valid for more complex scenarios,
just undocumented for the time being.
This commit is contained in:
Casper Beyer 2020-11-03 01:50:45 +08:00 committed by GitHub
parent a8ca9fe7bb
commit c5611636fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 25 deletions

View file

@ -68,21 +68,5 @@ const instance = await WebAssembly.instantiate(module, {
"wasi_snapshot_preview1": context.exports,
});
const {
_start: start,
_initialize: initialize,
memory,
} = instance.exports;
context.memory = memory as WebAssembly.Memory;
if (start instanceof Function) {
start();
} else if (initialize instanceof Function) {
initialize();
} else {
throw new Error(
"No '_start' or '_initialize' entry point found in WebAssembly module, make sure to compile with wasm32-wasi as the target.",
);
}
context.start(instance);
```

View file

@ -270,7 +270,6 @@ export interface ContextOptions {
args?: string[];
env?: { [key: string]: string | undefined };
preopens?: { [key: string]: string };
memory?: WebAssembly.Memory;
}
export default class Context {
@ -285,7 +284,7 @@ export default class Context {
constructor(options: ContextOptions) {
this.args = options.args ? options.args : [];
this.env = options.env ? options.env : {};
this.memory = options.memory!;
this.memory = null!;
this.fds = [
{
@ -1554,4 +1553,39 @@ export default class Context {
}),
};
}
/**
* Attempt to begin execution of instance as a command by invoking its
* _start() export.
*
* If the instance does not contain a _start() export, or if the instance
* contains an _initialize export an error will be thrown.
*
* The instance must also have a WebAssembly.Memory export named "memory"
* which will be used as the address space, if it does not an error will be
* thrown.
*/
start(instance: WebAssembly.Instance) {
const { _start, _initialize, memory } = instance.exports;
if (!(memory instanceof WebAssembly.Memory)) {
throw new TypeError("WebAsembly.instance must provide a memory export");
}
this.memory = memory;
if (typeof _initialize == "function") {
throw new TypeError(
"WebAsembly.instance export _initialize must not be a function",
);
}
if (typeof _start != "function") {
throw new TypeError(
"WebAssembly.Instance export _start must be a function",
);
}
_start();
}
}

View file

@ -1,5 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { assertEquals } from "../testing/asserts.ts";
import Context from "./snapshot_preview1.ts";
import { assertEquals, assertThrows } from "../testing/asserts.ts";
import { copy } from "../fs/mod.ts";
import * as path from "../path/mod.ts";
@ -137,3 +138,45 @@ for (const pathname of tests) {
},
});
}
Deno.test("context_start", function () {
assertThrows(
() => {
const context = new Context({});
context.start({
exports: {
_start() {},
},
});
},
TypeError,
"must provide a memory export",
);
assertThrows(
() => {
const context = new Context({});
context.start({
exports: {
_initialize() {},
memory: new WebAssembly.Memory({ initial: 1 }),
},
});
},
TypeError,
"export _initialize must not be a function",
);
assertThrows(
() => {
const context = new Context({});
context.start({
exports: {
memory: new WebAssembly.Memory({ initial: 1 }),
},
});
},
TypeError,
"export _start must be a function",
);
});

View file

@ -16,8 +16,4 @@ const instance = new WebAssembly.Instance(module, {
"wasi_snapshot_preview1": context.exports,
});
const memory = instance.exports.memory as WebAssembly.Memory;
context.memory = memory;
const start = instance.exports._start as CallableFunction;
start();
context.start(instance);