@vscode/wasm-wasi
TypeScript icon, indicating that this package has built-in type declarations

0.8.2 • Public • Published

VS Code WASI Implementation

Build Status

This npm module implements the WASI specification against the VS Code extension host API. This allows a WASM to read and write files from the workspace as well as reading from and writing to the terminal using stdin and stdout.

Example

The following example is written for the Desktop version of VS Code since it is easier to execute and test. Main reason is that WebAssembly execution for the browser needs cross origin isolation to be enabled.

To enable this for the browser version of VS Code add the query string ?vscode-coi= to the URL.

The C file

#include <stdio.h>

int main(void)
{
    printf("Hello, World\n");
    return 0;
}

This file needs to be compiled to the wasm-wasi target. This is best done using the WASI-SDK. When installed use the following command to compile it

clang hello.c -o hello.wasm

The WASM worker

Web assembly execution in VS Code is only supported when executing the web assembly in a separate worker. I can't be executed in the same worker as the extension code is running. A corresponding worker looks like this:

import * as fs from 'fs';
import * as path from 'path';
import { parentPort  } from 'worker_threads';

import { ClientConnection } from '@vscode/sync-api-common/node';
import { ApiClient, Requests } from '@vscode/sync-api-client';
import { WASI } from '@vscode/wasm-wasi/node';

if (parentPort === null) {
	process.exit();
}

// A special connection that allows the worker to talk to the
// extension host API using sync API.
const connection = new ClientConnection<Requests>(parentPort);
connection.serviceReady().then(async (params) => {
	const name = 'Run C Example';
	// A client that provides sync VS Code API
	const apiClient = new ApiClient(connection);
	const exitHandler = (rval: number): void => {
		apiClient.process.procExit(rval);
	};
	// The WASI implementation.
	const wasi = WASI.create(name, apiClient, exitHandler, {
		mapDir: []
	});
	// The file contain the web assembly code
	const wasmFile = path.join(__dirname, 'hello.wasm');
	const binary = fs.readFileSync(wasmFile);
	// Create a web assembly instance from the wasm file using the
	// provided WASI implementation.
	const { instance } = await WebAssembly.instantiate(binary, {
		wasi_snapshot_preview1: wasi
	});
	wasi.initialize(instance);
	// Run the web assembly
	(instance.exports._start as Function)();
	apiClient.process.procExit(0);
}).catch(console.error);

The actual extension code

The actual extension sets up the sync version of the VS Code api and starts the worker thread executing the web assembly code.

import * as path from 'path';
import { Worker } from 'worker_threads';

import { commands, ExtensionContext, window } from 'vscode';

import { ServiceConnection } from '@vscode/sync-api-common/node';
import { ApiService, Requests } from '@vscode/sync-api-service';

export async function activate(_context: ExtensionContext) {

	commands.registerCommand('vscode-wasm-wasi-c-example.run', () => {
		const name = 'Run C Example';
		// The worker to execute the web assembly
		const worker = new Worker(path.join(__dirname, './worker.js'));
		// A special connection that allows the worker to talk to the
		// extension host API using sync API.
		const connection = new ServiceConnection<Requests>(worker);
		// The actual sync implementation of parts of the VS Code API
		const apiService = new ApiService(name, connection, {
			exitHandler: (_rval) => {
				process.nextTick(() => worker.terminate());
			}
		});
		// A terminal to show the output of the web assembly execution
		const terminal = window.createTerminal({ name, pty: apiService.getPty() });
		terminal.show();

		connection.signalReady();
	});
}

export function deactivate() {
}

The complete example, include a package.json and a tsconfig.json file, can be found here

Readme

Keywords

Package Sidebar

Install

npm i @vscode/wasm-wasi

Weekly Downloads

111

Version

0.8.2

License

MIT

Unpacked Size

211 kB

Total Files

41

Last publish

Collaborators

  • microsoft1es
  • joaomoreno.ms
  • sbatten
  • alexandrudima
  • lszomoru
  • kaimaetzel
  • vscode-bot