New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@vscode/wasm-wasi

Package Overview
Dependencies
Maintainers
7
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vscode/wasm-wasi

A WASI implementation that uses VS Code's extension host as the implementing API

  • 0.8.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
107
increased by55.07%
Maintainers
7
Weekly downloads
 
Created
Source

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

Keywords

FAQs

Package last updated on 14 Nov 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc