Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
V86: x86 virtualization in the browser, recompiling x86 to WASM on the fly (github.com/copy)
265 points by tomduncalf on May 5, 2022 | hide | past | favorite | 39 comments


This is a really cool project. I'm currently working on a tutorial on how to use it with Buildroot Linux and Tiny C Compiler, where I now have tcc in the browser. v86 is unable to debug with gdb (v8, 10.2, 11.2) (though it works if you use gdb to intercept gdbserver from another device), so I'm experimenting with strace, and have written a basic streaming parser for read/writev syscalls. What strace does is intercept printf/puts/gets/readline etc and by parsing its output, one can create a simple but highly stylable "console" in html that prints and reads text input. No support for TUI's, this is where xterm.js shines.

Compilation in tcc with a file of ~300 lines of code, linking to a library, takes roughly 50 ms. Compiling the entire libharu library takes 23 s. It's ~120.000 SLOC but where most is long arrays of encoding data.

I have used musl as toolchain, but will look into uclibc because of a weird problem: printf without \n in the end doesn't display the text before something creates a newline. And that could be readline, in which case you'd get:

  Pizza
  What's your favourite food?
At least I think this is because of musl where there's a problem with the syscall writev: https://www.openwall.com/lists/musl/2013/05/05/9.

Really looking forward to get the tutorial out and I hope it'll be with the strace based console!


Sounds like you have a problem with "line buffering". You can normally configure libc libraries at compile time how you want them to behave in that respect.


Thanks, that did the trick. setvbuf was what I was looking for.


If the title is true, that would be a huge achievement. Unfortunately, the page says nothing about how it works and nothing about the speed advantage you get.

For my emulator jor1k [1] I tried something similar years ago [2]. However I haven't continued on this topic because of priority shifts. But the potential speed advantages are astonishing. My proof of context reached more than 1 billion emulated machine instructions per second.

[1] https://github.com/s-macke/jor1k

[2] https://github.com/s-macke/jor1k/wiki/Breaking-the-1-billion...


> If the title is true, that would be a huge achievement.

Fundamentally it's "just" a JIT that compiles to WASM. It's a ton of effort to build something like that, but I think fundamentally it's not an impossible undertaking.

The JIT seems to be living there, so you can probably explore from there: https://github.com/copy/v86/blob/master/src/rust/jit.rs

WRT speed advantage: compared to what?


It is definitely not "just" a JIT compiler. For example, you can't just copy QEMU's JIT solution and hope that it works. So I'm interested in your solution. For example, do you compile each code block (from jump to jump instruction) into a separate WebAssembly module? If yes, then I wonder how many millions of small WebAssembly modules a browser can handle, how well the foreign function interface between JavaScript and WebAssembly actually performs and how much of the time the Browser JIT spends in compiling your generated code. How do you handle machine code manipulation during execution for example? How do you mark already compiled memory pages as dirty.

I will definitely look at your code :-)

> WRT speed advantage: compared to what?

The speed advantage between interpreted and JIT compiled execution.


I just want to clarify that this is not my code. I just happened to remember this project from a while back.


I'm not entirely sure that the browser runtimes are suited for this since I watched a friend demo-ing V86 and the amount of crashes with modern OSs just seemed to make it a toy (though I might be proven wrong).

One plausible guess I have is that they might be running out of memory since the browser runtimes are expecting the WASM code to be long lived whilst a emulator JIT by nature should be able to adapt to rapidly changing code and blows out of memory before things are cleaned up.


Presumably the crashes are happening because the instruction set implemented by the JIT is on Pentium II level and so encountering modern X86 instructions makes it fail. I am not familiar with the linked project but there is no real reason why you could not emulate a 32bit Intel perfectly in WASM. For 64bit I'm not sure if wasm64 wouldn't be required.


I think there are browser-level crashes too because you're using the WASM JIT-compiler in ways it hasn't been thoroughly tested for.

The Chromium team is pretty receptive to patches though, so for a big project like this it doesn't seem unreasonable to just patch the browser to perform well enough for your use case, and then upstream the patch so everyone has it within a few months when you're ready to launch your product.


I have done a lot with wasm and I can't say I ran into browser level crashes.


> Unfortunately, the page says nothing about how it works.

It's literally the source. It looks like gen/generate_jit.js is what you want.


Your jor1k project is listed in the credits for some drivers.


> My proof of context reached more than 1 billion emulated machine instructions per second.

Which are the calculations about the billion instructions per second? Emulating instructions, even on a relatively simple system, requires a lot of support: decoding, cpu state, memory access/mapping, buses - and this doesn't even include the instructions themselves.


The calculations is based on the machine instructions, the compiled code by the JIT is able to perform on average. In this case a simple 32-Bit machine with OpenRISC architecture.

For the proof of concept, that was the compiled code in [1]. Just look for code snipplets such as "cycles = cyles - xxxx|0", that does the calculation during runtime.

So, my calculation does not include decoding, but CPU state, memory access/mapping, buses.

[1] https://gist.github.com/s-macke/0d79d2ba78a022269cb7859a4417...


See WebVM


This is an awesome project! I've integrated it into my Desktop Environment in the browser so that you can drag on ISO/IMG files and run them directly in the emulator. It also automatically saves states on close into /Users/Public/Snapshots. For networking I am using the same WebSocket proxy that v86 uses.

https://github.com/DustinBrett/daedalOS


I never actually played with Windows 1.0, but wanted to see what the concept was about.

It's interesting to see that the window sizes are automatic. There are no real windows. Also, it's kind of fun to see that there's no "Maximize", but "Zoom", just like macOS.. And double-clicking the titlebar actually minimizes the application to an icon, just like macOS.

The write.exe program is pretty cool


Windows 1.0 is more similar to Norton Commander and DOS Shell (built-in to later DOS versions), as well as the Borland Turbovision products, in that it's something between a textual and graphical "shell" that you can manipulate files and run other programs off of.

At that time, it was nowhere close to being called an OS. It was a collection of GUI-ish tools for DOS. This started to change with Windows 3. That one still required DOS to function, but by that time it was clear DOS was the past on the PC and Windows (in some form) was the way forward.


Well not completely as I see it. Yes functionality is limited, but I was able to execute multiple applications and multiple instances of them. I could also switch between then.

With Norton commander you could only spawn one process from NC. NC itself had quite a lot for built in tools (viewer, editor, comparison, 2 file panes).

So I’d call windows 1.0 more an OS in terms of process “management”, UI, etc. No hardware layer of course.


Wait, what version had DOS Shell?

My last version was MS-DOS 6.22, but I can't remember that. Personally I used volkov commander.

Edit: I see it was discontinued in 6.22, I wonder why.


Yeah, my mind messed up the details (this was many moons ago!). Link for the curious: https://en.wikipedia.org/wiki/DOS_Shell

I guess it was discontinued probably because by that time MS was focusing on Windows as the operating system "shell".


I think it was still available in MS-DOS 6.22 but it wasn't installed by default anymore. You had to install it manually from the 4th optional disk.


There is a working, client-side only linux running with another similar technology: https://leaningtech.com/cheerpx/


Direct link to our interactive demo of CheerpX: https://webvm.io/


Looks like an older precursor to WebVM (which is closed source). https://news.ycombinator.com/item?id=30167403


Hi, CTO of LeaningTech and lead dev of WebVM here. Thanks for mentioning our tech, which we believe to be the most advanced currently existing.

I am happy to answer questions.


I tried WebVM but it feels a bit slow. Do you think performance could be improved by supporting native wasm binaries? Something like wasm-*-linux compilation target.


The Windows 2000 demo reminded me of just how clean, fast and consistent Windows was in that era. Compared to today.


Ok so umm does that mean we can push a full operating system in any mobile app with a webview?


I crashed IE5 in Win98 by just using Google. Brings me back...


Booting Windows 98 crashed my whole browser.


All right, you win


So it's working!

SCNR



Nice to see Oberon System 3 there, it doesn't seem complete though.


Very, very cool. And slow. But cool.


Incredibly cool. And the demos are impressive.


Github teaches humility.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: