One common thing these projects share is an attempt to implement the whole language specification, together with the more or less complete standard library. This is good and bad. The good part is obvious. What's about the bad part?

First, none of the popular scripting languages have been designed for the embedded environment in the first place. They drag along some obscure constructs that take precious space, but have very little practical usage in the embedded context.

Second, in order to export a hardware-specific functionality into the scripting environment (e.g. a certain sensor API, or a certain LCD display API), a glue code must be written. And that glue code should be maintained. That, again, takes precious space and increases overall complexity.

mJS - a restricted JavaScript engine

So, please welcome mJS - a new kid on the block, a new JavaScript engine. It takes a radically different approach:

mJS does NOT implement the whole language, but a limited subset.

mJS has NO standard library.

mJS has NO glue code.

That makes mJS fit into less than 50k of flash space (!) and less than 1k of RAM (!!). That is hard to beat.

Fair enough. But how can THAT be useful, one might ask. No standard library? No glue code? Seriously?

Yes. Seriously.

The mJS's power is in having an ability to call C SDK functions directly.

FFI - calling C SDK functions directly

FFI means Foreign Function Interface. In mJS context, it's an ability to load and call C functions directly. How does mJS do that? It has to know 2 things: first, an address of the C function, and second, a signature of the C function. Then it marshals JS arguments into C values, puts them to where ABI demands (e.g. on the CPU stack), and jumps to the function's address. Practically it looks like this: