Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please support loading WebAssembly modules in extensions #65559

Closed
jmillikin opened this issue Dec 21, 2018 · 17 comments
Closed

Please support loading WebAssembly modules in extensions #65559

jmillikin opened this issue Dec 21, 2018 · 17 comments
Labels
extensions-development Issues for developing extensions feature-request Request for new features or functionality help wanted Issues identified as good community contribution opportunities
Milestone

Comments

@jmillikin
Copy link

I would like to write extensions that use libraries written in languages that compile to native code (e.g. Go, Rust, C). Today the only practical way to do this is to use a separate binary compiled for each platform supported by VS Code, either via LSP or directly invoked subprocesses. This has substantial drawbacks for performance, user experience ("please download a bunch of tools"), and extension update cadence.

Many of these languages also support WebAssembly as an output target, which means in theory I could bundle a .wasm into the extension and run it on any architecture supported by V8. In practice it doesn't work as of VS Code v1.30.1 -- the WebAssembly namespace isn't available to extensions.

Would it be possible to offer the upstream WebAssembly API (or something similar)? Then the extension could look like this:

// extension.ts
export function activate(ctx: vscode.ExtensionContext) {
	const serverPath = context.asAbsolutePath(path.join("server/out/server.js"));
	const implPath = context.asAbsolutePath(path.join("server/out/impl.wasm"));

	let serverOptions: ServerOptions = {
		module: serverPath,
		transport: TransportKind.ipc,
		args: ["--impl-path=" + implPath],
	};
	// ...
}

// server.ts
import * as fs from "fs";
const implBuf = new Uint8Array(fs.readFileSync(implPathFromArgs));
let impl: any;
WebAssembly.instantiate(implBuf, {}).then(result => {
  impl = result.instance;
});
// LSP methods can invoke methods of `impl` to tokenize, search parse tree, etc

References:

@jrieken jrieken assigned bpasero and unassigned jrieken Dec 27, 2018
@jrieken
Copy link
Member

jrieken commented Dec 27, 2018

The symbols are there but aren't defined in the node.d.ts file. That's why you get a compile error

@bpasero
Copy link
Member

bpasero commented Dec 28, 2018

Looks like this only came in via nodejs/node#23339, probably needs an update of our dependency to node.d.ts.

@bpasero bpasero added upstream Issue identified as 'upstream' component related (exists outside of VS Code) nodejs NodeJS support issues labels Dec 28, 2018
@bpasero
Copy link
Member

bpasero commented Feb 7, 2019

It does not look like WebAssembly appears even with the latest node.d.ts.

@fominok
Copy link

fominok commented Mar 9, 2019

Well, I can successfully call my wasm from js vscode extension "thanks" to no compilation. Maybe we can bypass/override these node.d.ts definitions somehow, didn't use ts before
edit:
@bpasero could you tell me where this node.d.ts is located?

@fominok
Copy link

fominok commented Mar 10, 2019

@jmillikin here is a workaround I came to today:
For webasm I use Rust language and their wasm-pack tool, which compiles my wasm code and creates npm package. I follow this guide: https://rustwasm.github.io/docs/book/game-of-life/setup.html
So I've created a project from template, let's call it vswasm, and compiled it with wasm-pack build --target nodejs. In generated pkg dir I called npm link.
In freshly created vscode extension directory enter npm link vswasm.
Now in extension.ts I'm able to do imports like import * as vswasm from 'vswasm' and call vswasm.greet().
Second part: memory. To access WA memory we need missing types, so I installed @types/webassembly-js-api with npm into extension folder. Now accessing buffer is simple as

import * as wasm from 'vswasm/vswasm_bg';
wasm.memory.buffer

Didn't do anything more than this now, but it looks like a solution. Hope it helps!

@vscodebot
Copy link

vscodebot bot commented Oct 9, 2019

This issue is being closed to keep the number of issues in our inbox on a manageable level, we are closing issues that are not going to be addressed in the foreseeable future: We look at the number of votes the issue has received and the number of duplicate issues filed. More details here. If you disagree and feel that this issue is crucial: We are happy to listen and to reconsider.

If you wonder what we are up to, please see our roadmap and issue reporting guidelines.

Thanks for your understanding and happy coding!

@gilescope
Copy link

Web assembly isn't on the road map for VSCode extensions in the next 2 years? I find this incredible. I respectfully suggest that maybe this ticket hasn't been given the publicity and due consideration it deserves?

@rusnasonov
Copy link

@bpasero can you reopen this issue? Supporting WASM it's a big deal for extension developers.

@fominok
Copy link

fominok commented Sep 28, 2020

@bpasero can you reopen this issue? Supporting WASM it's a big deal for extension developers.

hello Emacs my old friend

@bpasero bpasero changed the title Please support loading WebAssembly modules in extensions Allow to reference WebAssembly modules in extension Sep 28, 2020
@bpasero bpasero reopened this Sep 28, 2020
@bpasero bpasero added extensions-development Issues for developing extensions feature-request Request for new features or functionality and removed *out-of-scope Posted issue is not in scope of VS Code nodejs NodeJS support issues upstream Issue identified as 'upstream' component related (exists outside of VS Code) labels Sep 28, 2020
@bpasero bpasero removed their assignment Sep 28, 2020
@bpasero bpasero added this to the Backlog Candidates milestone Sep 28, 2020
@vscode-triage-bot
Copy link

This feature request is now a candidate for our backlog. The community has 60 days to upvote the issue. If it receives 20 upvotes we will move it to our backlog. If not, we will close it. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

@bpasero
Copy link
Member

bpasero commented Sep 28, 2020

I fail to understand how the types for node.js or lib.d.ts do not have WebAssembly in them. @DanielRosenwasser can you shed some light on this? I think the TypeScript team is contributing to the nodejs.d.ts types right? Bottom line: there is a global WebAssembly type in node.js (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly) but it is not typed anywhere in d.ts files it seems?

@vscode-triage-bot
Copy link

🙂 This feature request received a sufficient number of community upvotes and we moved it to our backlog. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

@tlightsky

This comment has been minimized.

@orta
Copy link
Contributor

orta commented Oct 1, 2020

@bpasero - the WebAssembly globals do live in the dom.d.ts based on their spec pages but for them to be available here they would need to be C&P'd into @types/node.

The TS team is generally hands-off on adding new things to any @types/x packages, given the scale of community contributions - we're mainly there to maintain ecosystem stability so I guess it's just been that no-one has sent a PR for it yet

@bpasero bpasero added the help wanted Issues identified as good community contribution opportunities label Oct 1, 2020
@bpasero
Copy link
Member

bpasero commented Oct 1, 2020

Ok thanks, if someone is willing to add these types into types/node (https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) then we can pull them in. Important: it has to be added to the 12.x branch, as VSCode is not yet on node.js 14.

@bpasero bpasero removed their assignment Nov 10, 2020
@jmillikin jmillikin changed the title Allow to reference WebAssembly modules in extension Please support loading WebAssembly modules in extensions Dec 27, 2020
@jmillikin
Copy link
Author

At some point since the original filing of this issue, WebAssembly support has been enabled in the vscode Node environment. While the types are still missing, it is now possible to load a WASM module by adding the following declaration:

declare const WebAssembly: any;

I consider this issue solved, since the WASM API is small enough to operate without full types.

@jmillikin
Copy link
Author

jmillikin commented Dec 28, 2020

If anyone's interested, I wrote up some notes on a "hello world" WASM-enabled vscode LSP server at https://john-millikin.com/extending-vscode-with-webassembly

@github-actions github-actions bot locked and limited conversation to collaborators Feb 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
extensions-development Issues for developing extensions feature-request Request for new features or functionality help wanted Issues identified as good community contribution opportunities
Projects
None yet
Development

No branches or pull requests

9 participants