A vast amount of the size that goes into the /big/ JS engines is performance, and supporting all the many edge cases and weird behaviors that these small engines often ignore.
Another huge part is actually support JS. This VM does not do this. It precompiles the "JS" to a bwtecode, and then merely needs a bytecode interpreter. It would hopefully be obvious why this drastically simplifies the engine and helps performance.
I'm fine with this as an application specific VM, but to claim it is a JS VM, and more importantly to compare size and memory usage to VMs that are able to actually parse and execute JS seems unfair. Even if the two compared inexplicably leave out some super minor syntactic features (switch, do, for, ..).
In this particular case what I'd say is this is essentially a redevelopment of bytecode interpreted languages (p-code, etc) as used in the 70s+80s, where compiling a high level language into a bytecode and the vm to execute that bytecode allowed programs to be much smaller than compiling to native code (and more portable in some cases).
Yes, you make a good point. A decent chunk of the size of an engine like mJS or Elk (or XS) is the parser or bytecode compiler (XS and mJS use a bytecode compiler like Microvium but the compiler is designed to run on-device and so contributes to the ROM size by default). Microvium in some sense "cheats" by not having this built into the runtime engine.
From a purely practical standpoint though, how much does that matter? If you want to run JavaScript on a microcontroller and mJS works for your situation, then maybe Microvium will also work for your situation but will do it with less RAM and ROM overhead and more language features. The practical difference is that the build or release or deployment process for your scripts now includes an extra step. Whether you can afford that extra step depends on your situation.
From a philosophical perspective, it’s an interesting question. A Microvium app actually starts running at “compile-time” and a snapshot of the running VM state is downloaded to the target MCU to continue executing where it left off. From the perspective of the running app process, Microvium does support the `import` of JavaScript source text modules (and therefore also parsing), but it just loses that capability when the VM is moved from the compile-time host to the runtime host. So, the small runtime engine doesn’t support it, but Microvium as a whole does support it. I guess this goes back to the practical question of whether your particular application needs `eval` or dynamic `import` at runtime (post-snapshot).
You also brought up the handling of edge cases, which is a good point. No engine has 100% ECMAScript compliance, so it’s a matter of degree of nonconformity, but engines like Elk, mJS and Microvium are particularly far from compliant. Originally I didn’t call Microvium a JS engine (I called it an engine for JS-like scripts, or something like that) but I changed when I saw how other engines with similar capabilities and restrictions are calling themselves JS engines.
There's a similar thing being done by the folks at Moddable. I tried it a few years ago and it was decent. Knowing that microcontrollers have gotten beefier, I think it might be quite better now.
Another approach to this is Toit - some guys from the V8 engine team at Google started this company IIRC. They've written a new language inspired by JS but for microcontrollers.
Moddable's XS engine is great, and covers the full ECMAScript spec. I did a bit of contract work on the XS engine a while back, and I participated for some time as an invited expert on the ECMA TC53 committee for JS on embedded systems alongside Moddable and can say that I have a lot of respect for what they've done. For people who are running large enough devices to support XS, I highly recommend it.
I created Microvium in part because over my career as a firmware engineer there was a common pattern that most of the devices I worked on were just way too small to run any of the off-the-shelf JS engines. Even on larger microcontrollers, it's a big commitment for a company to allocate 50kB+ of ROM and 1kB+ of RAM just to run JavaScript, especially since the firmware teams were dominated by C programmers who consider JS to be very low on the priority list.
Another huge part is actually support JS. This VM does not do this. It precompiles the "JS" to a bwtecode, and then merely needs a bytecode interpreter. It would hopefully be obvious why this drastically simplifies the engine and helps performance.
I'm fine with this as an application specific VM, but to claim it is a JS VM, and more importantly to compare size and memory usage to VMs that are able to actually parse and execute JS seems unfair. Even if the two compared inexplicably leave out some super minor syntactic features (switch, do, for, ..).
In this particular case what I'd say is this is essentially a redevelopment of bytecode interpreted languages (p-code, etc) as used in the 70s+80s, where compiling a high level language into a bytecode and the vm to execute that bytecode allowed programs to be much smaller than compiling to native code (and more portable in some cases).