| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 694659c commit 60e5f45
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,21 +16,18 @@ import { WASI } from 'wasi'; | |||
| 16 | 16 | import { argv, env } from 'node:process'; | |
| 17 | 17 | ||
| 18 | 18 | const wasi = new WASI({ | |
| 19 | + version: 'preview1', | ||
| 19 | 20 | args: argv, | |
| 20 | 21 | env, | |
| 21 | 22 | preopens: { | |
| 22 | 23 | '/sandbox': '/some/real/path/that/wasm/can/access', | |
| 23 | 24 | }, | |
| 24 | 25 | }); | |
| 25 | 26 | ||
| 26 | - // Some WASI binaries require: | ||
| 27 | - // const importObject = { wasi_unstable: wasi.wasiImport }; | ||
| 28 | - const importObject = { wasi_snapshot_preview1: wasi.wasiImport }; | ||
| 29 | - | ||
| 30 | 27 | const wasm = await WebAssembly.compile( | |
| 31 | 28 | await readFile(new URL('./demo.wasm', import.meta.url)), | |
| 32 | 29 | ); | |
| 33 | - const instance = await WebAssembly.instantiate(wasm, importObject); | ||
| 30 | + const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject()); | ||
| 34 | 31 | ||
| 35 | 32 | wasi.start(instance); | |
| 36 | 33 | ``` | |
@@ -43,22 +40,19 @@ const { argv, env } = require('node:process'); | |||
| 43 | 40 | const { join } = require('node:path'); | |
| 44 | 41 | ||
| 45 | 42 | const wasi = new WASI({ | |
| 43 | + version: 'preview1', | ||
| 46 | 44 | args: argv, | |
| 47 | 45 | env, | |
| 48 | 46 | preopens: { | |
| 49 | 47 | '/sandbox': '/some/real/path/that/wasm/can/access', | |
| 50 | 48 | }, | |
| 51 | 49 | }); | |
| 52 | 50 | ||
| 53 | - // Some WASI binaries require: | ||
| 54 | - // const importObject = { wasi_unstable: wasi.wasiImport }; | ||
| 55 | - const importObject = { wasi_snapshot_preview1: wasi.wasiImport }; | ||
| 56 | - | ||
| 57 | 51 | (async () => { | |
| 58 | 52 | const wasm = await WebAssembly.compile( | |
| 59 | 53 | await readFile(join(__dirname, 'demo.wasm')), | |
| 60 | 54 | ); | |
| 61 | - const instance = await WebAssembly.instantiate(wasm, importObject); | ||
| 55 | + const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject()); | ||
| 62 | 56 | ||
| 63 | 57 | wasi.start(instance); | |
| 64 | 58 | })(); | |
@@ -126,6 +120,10 @@ sandbox directory structure configured explicitly. | |||
| 126 | 120 | added: | |
| 127 | 121 | - v13.3.0 | |
| 128 | 122 | - v12.16.0 | |
| 123 | + changes: | ||
| 124 | + - version: REPLACEME | ||
| 125 | + pr-url: https://github.com/nodejs/node/pull/46469 | ||
| 126 | + description: version field added to options. | ||
| 129 | 127 | --> | |
| 130 | 128 | ||
| 131 | 129 | * `options` {Object} | |
@@ -148,6 +146,30 @@ added: | |||
| 148 | 146 | WebAssembly application. **Default:** `1`. | |
| 149 | 147 | * `stderr` {integer} The file descriptor used as standard error in the | |
| 150 | 148 | WebAssembly application. **Default:** `2`. | |
| 149 | + * `version` {string} The version of WASI requested. Currently the only | ||
| 150 | + supported versions are `unstable` and `preview1`. **Default:** `preview1`. | ||
| 151 | + | ||
| 152 | + ### `wasi.getImportObject()` | ||
| 153 | + | ||
| 154 | + <!-- YAML | ||
| 155 | + added: REPLACEME | ||
| 156 | + --> | ||
| 157 | + | ||
| 158 | + Return an import object that can be passed to `WebAssembly.instantiate()` if | ||
| 159 | + no other WASM imports are needed beyond those provided by WASI. | ||
| 160 | + | ||
| 161 | + If version `unstable` was passed into the constructor it will return: | ||
| 162 | + | ||
| 163 | + ```json | ||
| 164 | + { wasi_unstable: wasi.wasiImport } | ||
| 165 | + ``` | ||
| 166 | + | ||
| 167 | + If version `preview1` was passed into the constructor or no version was | ||
| 168 | + specified it will return: | ||
| 169 | + | ||
| 170 | + ```json | ||
| 171 | + { wasi_snapshot_preview1: wasi.wasiImport } | ||
| 172 | + ``` | ||
| 151 | 173 | ||
| 152 | 174 | ### `wasi.start(instance)` | |
| 153 | 175 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ const { | |||
| 10 | 10 | } = primordials; | |
| 11 | 11 | ||
| 12 | 12 | const { | |
| 13 | + ERR_INVALID_ARG_VALUE, | ||
| 13 | 14 | ERR_WASI_ALREADY_STARTED | |
| 14 | 15 | } = require('internal/errors').codes; | |
| 15 | 16 | const { | |
@@ -22,13 +23,14 @@ const { | |||
| 22 | 23 | validateFunction, | |
| 23 | 24 | validateInt32, | |
| 24 | 25 | validateObject, | |
| 26 | + validateString, | ||
| 25 | 27 | validateUndefined, | |
| 26 | 28 | } = require('internal/validators'); | |
| 27 | - const { WASI: _WASI } = internalBinding('wasi'); | ||
| 28 | 29 | const kExitCode = Symbol('kExitCode'); | |
| 29 | 30 | const kSetMemory = Symbol('kSetMemory'); | |
| 30 | 31 | const kStarted = Symbol('kStarted'); | |
| 31 | 32 | const kInstance = Symbol('kInstance'); | |
| 33 | + const kBindingName = Symbol('kBindingName'); | ||
| 32 | 34 | ||
| 33 | 35 | emitExperimentalWarning('WASI'); | |
| 34 | 36 | ||
@@ -45,6 +47,31 @@ class WASI { | |||
| 45 | 47 | constructor(options = kEmptyObject) { | |
| 46 | 48 | validateObject(options, 'options'); | |
| 47 | 49 | ||
| 50 | + let _WASI; | ||
| 51 | + if (options.version !== undefined) { | ||
| 52 | + validateString(options.version, 'options.version'); | ||
| 53 | + switch (options.version) { | ||
| 54 | + case 'unstable': | ||
| 55 | + ({ WASI: _WASI } = internalBinding('wasi')); | ||
| 56 | + this[kBindingName] = 'wasi_unstable'; | ||
| 57 | + break; | ||
| 58 | + // When adding support for additional wasi versions add case here | ||
| 59 | + case 'preview1': | ||
| 60 | + ({ WASI: _WASI } = internalBinding('wasi')); | ||
| 61 | + this[kBindingName] = 'wasi_snapshot_preview1'; | ||
| 62 | + break; | ||
| 63 | + // When adding support for additional wasi versions add case here | ||
| 64 | + default: | ||
| 65 | + throw new ERR_INVALID_ARG_VALUE('options.version', | ||
| 66 | + options.version, | ||
| 67 | + 'unsupported WASI version'); | ||
| 68 | + } | ||
| 69 | + } else { | ||
| 70 | + // TODO(mdawson): Remove this in a SemVer major PR before Node.js 20 | ||
| 71 | + ({ WASI: _WASI } = internalBinding('wasi')); | ||
| 72 | + this[kBindingName] = 'wasi_snapshot_preview1'; | ||
| 73 | + } | ||
| 74 | + | ||
| 48 | 75 | if (options.args !== undefined) | |
| 49 | 76 | validateArray(options.args, 'options.args'); | |
| 50 | 77 | const args = ArrayPrototypeMap(options.args || [], String); | |
@@ -138,8 +165,11 @@ class WASI { | |||
| 138 | 165 | _initialize(); | |
| 139 | 166 | } | |
| 140 | 167 | } | |
| 141 | - } | ||
| 142 | 168 | ||
| 169 | + getImportObject() { | ||
| 170 | + return { [this[kBindingName]]: this.wasiImport }; | ||
| 171 | + } | ||
| 172 | + } | ||
| 143 | 173 | ||
| 144 | 174 | module.exports = { WASI }; | |
| 145 | 175 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1247,10 +1247,10 @@ void WASI::_SetMemory(const FunctionCallbackInfo<Value>& args) { | |||
| 1247 | 1247 | wasi->memory_.Reset(wasi->env()->isolate(), args[0].As<WasmMemoryObject>()); | |
| 1248 | 1248 | } | |
| 1249 | 1249 | ||
| 1250 | - static void Initialize(Local<Object> target, | ||
| 1251 | - Local<Value> unused, | ||
| 1252 | - Local<Context> context, | ||
| 1253 | - void* priv) { | ||
| 1250 | + static void InitializePreview1(Local<Object> target, | ||
| 1251 | + Local<Value> unused, | ||
| 1252 | + Local<Context> context, | ||
| 1253 | + void* priv) { | ||
| 1254 | 1254 | Environment* env = Environment::GetCurrent(context); | |
| 1255 | 1255 | Isolate* isolate = env->isolate(); | |
| 1256 | 1256 | ||
@@ -1313,8 +1313,7 @@ static void Initialize(Local<Object> target, | |||
| 1313 | 1313 | SetConstructorFunction(context, target, "WASI", tmpl); | |
| 1314 | 1314 | } | |
| 1315 | 1315 | ||
| 1316 | - | ||
| 1317 | 1316 | } // namespace wasi | |
| 1318 | 1317 | } // namespace node | |
| 1319 | 1318 | ||
| 1320 | - NODE_BINDING_CONTEXT_AWARE_INTERNAL(wasi, node::wasi::Initialize) | ||
| 1319 | + NODE_BINDING_CONTEXT_AWARE_INTERNAL(wasi, node::wasi::InitializePreview1) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,3 +47,12 @@ assert.throws(() => { new WASI({ stderr: 'fhqwhgads' }); }, | |||
| 47 | 47 | assert.throws(() => { | |
| 48 | 48 | new WASI({ preopens: { '/sandbox': '__/not/real/path' } }); | |
| 49 | 49 | }, { code: 'UVWASI_ENOENT', message: /uvwasi_init/ }); | |
| 50 | + | ||
| 51 | + // If version is not a string, it should throw | ||
| 52 | + assert.throws(() => { new WASI({ version: { x: 'y' } }); }, | ||
| 53 | + { code: 'ERR_INVALID_ARG_TYPE', message: /\bversion\b/ }); | ||
| 54 | + | ||
| 55 | + | ||
| 56 | + // If version is an unsupported version, it should throw | ||
| 57 | + assert.throws(() => { new WASI({ version: 'not_a_version' }); }, | ||
| 58 | + { code: 'ERR_INVALID_ARG_VALUE', message: /\bversion\b/ }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,8 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | const common = require('../common'); | |
| 3 | 3 | ||
| 4 | - if (process.argv[2] === 'wasi-child') { | ||
| 4 | + if (process.argv[2] === 'wasi-child-default') { | ||
| 5 | + // test default case | ||
| 5 | 6 | const fixtures = require('../common/fixtures'); | |
| 6 | 7 | const tmpdir = require('../common/tmpdir'); | |
| 7 | 8 | const fs = require('fs'); | |
@@ -30,12 +31,49 @@ if (process.argv[2] === 'wasi-child') { | |||
| 30 | 31 | ||
| 31 | 32 | wasi.start(instance); | |
| 32 | 33 | })().then(common.mustCall()); | |
| 34 | + } else if (process.argv[2] === 'wasi-child-preview1') { | ||
| 35 | + // Test version set to preview1 | ||
| 36 | + const assert = require('assert'); | ||
| 37 | + const fixtures = require('../common/fixtures'); | ||
| 38 | + const tmpdir = require('../common/tmpdir'); | ||
| 39 | + const fs = require('fs'); | ||
| 40 | + const path = require('path'); | ||
| 41 | + | ||
| 42 | + common.expectWarning('ExperimentalWarning', | ||
| 43 | + 'WASI is an experimental feature and might change at any time'); | ||
| 44 | + | ||
| 45 | + const { WASI } = require('wasi'); | ||
| 46 | + tmpdir.refresh(); | ||
| 47 | + const wasmDir = path.join(__dirname, 'wasm'); | ||
| 48 | + const wasiPreview1 = new WASI({ | ||
| 49 | + version: 'preview1', | ||
| 50 | + args: ['foo', '-bar', '--baz=value'], | ||
| 51 | + env: process.env, | ||
| 52 | + preopens: { | ||
| 53 | + '/sandbox': fixtures.path('wasi'), | ||
| 54 | + '/tmp': tmpdir.path, | ||
| 55 | + }, | ||
| 56 | + }); | ||
| 57 | + | ||
| 58 | + // Validate the getImportObject helper | ||
| 59 | + assert.strictEqual(wasiPreview1.wasiImport, | ||
| 60 | + wasiPreview1.getImportObject().wasi_snapshot_preview1); | ||
| 61 | + const modulePathPreview1 = path.join(wasmDir, `${process.argv[3]}.wasm`); | ||
| 62 | + const bufferPreview1 = fs.readFileSync(modulePathPreview1); | ||
| 63 | + | ||
| 64 | + (async () => { | ||
| 65 | + const { instance: instancePreview1 } = | ||
| 66 | + await WebAssembly.instantiate(bufferPreview1, | ||
| 67 | + wasiPreview1.getImportObject()); | ||
| 68 | + | ||
| 69 | + wasiPreview1.start(instancePreview1); | ||
| 70 | + })().then(common.mustCall()); | ||
| 33 | 71 | } else { | |
| 34 | 72 | const assert = require('assert'); | |
| 35 | 73 | const cp = require('child_process'); | |
| 36 | 74 | const { checkoutEOL } = common; | |
| 37 | 75 | ||
| 38 | - function innerRunWASI(options, args) { | ||
| 76 | + function innerRunWASI(options, args, flavor = 'default') { | ||
| 39 | 77 | console.log('executing', options.test); | |
| 40 | 78 | const opts = { | |
| 41 | 79 | env: { | |
@@ -52,7 +90,7 @@ if (process.argv[2] === 'wasi-child') { | |||
| 52 | 90 | ...args, | |
| 53 | 91 | '--experimental-wasi-unstable-preview1', | |
| 54 | 92 | __filename, | |
| 55 | - 'wasi-child', | ||
| 93 | + 'wasi-child-' + flavor, | ||
| 56 | 94 | options.test, | |
| 57 | 95 | ], opts); | |
| 58 | 96 | console.log(child.stderr.toString()); | |
@@ -64,6 +102,7 @@ if (process.argv[2] === 'wasi-child') { | |||
| 64 | 102 | function runWASI(options) { | |
| 65 | 103 | innerRunWASI(options, ['--no-turbo-fast-api-calls']); | |
| 66 | 104 | innerRunWASI(options, ['--turbo-fast-api-calls']); | |
| 105 | + innerRunWASI(options, ['--turbo-fast-api-calls'], 'preview1'); | ||
| 67 | 106 | } | |
| 68 | 107 | ||
| 69 | 108 | runWASI({ test: 'cant_dotdot' }); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments