Developing embedded JavaScript engine, V7 – Marko Mikolucic (?)

v7 is an embedded javascript vm – embedded in the sense that you link it into a different application (cfr. mongoose).

Javascript is tough, e.g. the truth table of the equality comparison is quite complicated. So why do you want such a scripting engine on your device, when there are alternatives like Lua? Why: everybody knows a bit of javascript, it’s widely available and not stagnating. So having js as the way your users can extend your application makes sense.

Compared to other javascript VMs, v7’s goal is to be portable, small (runtime size and code size), reasonably fast. For this it uses some tricks, like a compacting GC and no reference counting. You can store snapshots (like the parsed code) and mmap compiled bytecode (but that requires a port to your platform). On very small machines, the stack size limit makes it impossible to use a typical recursive parser, so instead the parser is based on coroutines with segmented stacks.

v7 is embedded, so you can execute a string and retrieve the resulting values. Values are not represented as a union (because the size would be the largest object size, typically double), and you need a type byte which requires padding for struct alignment. So instead a trick is used from floating point representation: a NaN needs just a few bits, so all non-double types are represented as a NaN. This is done with macros and not with gcc extensions so it can be used with any compiler.

To reduce the size of the AST, it is not constructed with pointers but as a stack (because you know how many operands each operator takes, and you can distinguish operators from values, so you can reconstruct the tree from just a flat array of operators and values).

The bytecode uses a simple stack-based programming model.

The only libc function it uses if malloc.

It’s been developed by 2 people in about one year.

Currently supports 32-bit and 64-bit architectures, might be ported to 16-bit in the future.