You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was inspired by @ncoghlan's comment suggesting using asm2wasm for converting the current asm.js JIT to a wasm one. As a fun weekend hack I got that to work:
As suggested, this simply takes the asm.js from the current backend and runs it through asm2wasm (compiled to asm.js itself), which emits a wasm binary. We then compile that in the browser.
This hit a few asm2wasm parsing bugs, all fixed in a branch. Also asm2wasm was not in the JS port of binaryen yet, so I added that in the branch as well.
Code is in a wasmjit branch in a fork of pypyjs-release. To see it in action there, run a.js in node. Note you can pick wasm or asm.js at the top of lib/pypyjs.vm.js by setting the WASM var.
This is really just a quick hack. Instead of properly building pypyjs.vm.js to run using wasm (which I saw isn't trivial as it requires a 32-bit host), I manually modified the existing pypy.vm.js build where necessary. The key changes are in this diff, and they include:
Create a wasm Memory object, as we need to share memory with the JIT code, and wasm JIT code can only import a Memory.
As a result of that, we must set up memory early on, at the top of the file - I replaced the normal point where we create the main ArrayBuffer with just an assert to verify the size is right.
The interesting part is at the end of that diff, which is if we are in the wasm path, then:
var module = Binaryen.asm2wasm(source);
var binary = module.emitBinary();
module.dispose();
var info = {
env: {
memory: wasmMemory,
table: wasmTable,
memoryBase: 0,
tableBase: 0
},
foreign: Module
};
var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), info);
func = instance.exports.singleton;
That basically just runs asm2wasm using binaryen.js, emits a wasm binary, compiles it, and gets the resulting wasm function.
Note that while this shows that it works, it isn't fast or anything like that! Limitations:
Because of how I hacked up the existing JS, pypyjs.vm.js no longer validates as asm.js, which may make the non-JIT code a lot slower. To get this done properly, we'd need to recompile it to wasm.
In the bigger picture, the proof of concept pipeline of pypy => asm.js => wasm adds a bunch of unnecessary overhead (we are emitting asm.js text, then parsing that text). It was quick to get working, but a proper approach would mean writing a wasm backend in pypy itself (perhaps using Binaryen's C API) so that we directly and efficiently emit wasm.
The text was updated successfully, but these errors were encountered:
I was inspired by @ncoghlan's comment suggesting using asm2wasm for converting the current asm.js JIT to a wasm one. As a fun weekend hack I got that to work:
a.js
in node. Note you can pick wasm or asm.js at the top oflib/pypyjs.vm.js
by setting theWASM
var.This is really just a quick hack. Instead of properly building
pypyjs.vm.js
to run using wasm (which I saw isn't trivial as it requires a 32-bit host), I manually modified the existingpypy.vm.js
build where necessary. The key changes are in this diff, and they include:ArrayBuffer
with just an assert to verify the size is right.That basically just runs asm2wasm using binaryen.js, emits a wasm binary, compiles it, and gets the resulting wasm function.
Note that while this shows that it works, it isn't fast or anything like that! Limitations:
pypyjs.vm.js
no longer validates as asm.js, which may make the non-JIT code a lot slower. To get this done properly, we'd need to recompile it to wasm.pypy => asm.js => wasm
adds a bunch of unnecessary overhead (we are emitting asm.js text, then parsing that text). It was quick to get working, but a proper approach would mean writing a wasm backend in pypy itself (perhaps using Binaryen's C API) so that we directly and efficiently emit wasm.The text was updated successfully, but these errors were encountered: