Live data from Hacker News

mJS – A new approach to embedded scripting

mongoose-iot.com

21–30 of 61 posts

Re: mJS – A new approach to embedded scripting

#22

25k of flash space sounds like a lot for what is effectively just a JavaScript parser and interpreter. I recall the days when you could fit a whole language's compiler into a few measly KB. 1KB RAM is also quite a lot for certain boards, especially if it has to be stack or SRAM. How's the performance? Will my 72MHz Cortex or 16MHz Arduino be able to run interesting things with mJS? If I have to do everything through…

I'd wager a large amount of that is handling symbol lookup for calling through the FFI.

Re: mJS – A new approach to embedded scripting

#23

25k of flash space sounds like a lot for what is effectively just a JavaScript parser and interpreter. I recall the days when you could fit a whole language's compiler into a few measly KB. 1KB RAM is also quite a lot for certain boards, especially if it has to be stack or SRAM. How's the performance? Will my 72MHz Cortex or 16MHz Arduino be able to run interesting things with mJS? If I have to do everything through…

I'd wager a large amount of that is handling symbol lookup for calling through the FFI.

I quote the mJS readme from the repo:

> In order to make FFI work, mJS must be able to get the address of a C function by its name. On POSIX systems, dlsym() API can do that. On Windows, GetProcAddress(). On embedded systems, a system resolver should be either manually written, or be implemented with some aid from a firmware linker script.

So I guess they don't provide any implementation for their FFI linking on embedded platforms? It's not clear if the 25k size figure includes any dlsym support, but if it requires instrumenting your firmware image on-disk then the size costs could balloon significantly.

Re: mJS – A new approach to embedded scripting

#24
post #3

I've never worked with embedded systems, so forgive my ignorance. Why is this any more useful than just writing c code, if all the code that actually interacts with the hardware has to be written in c anyway?

a nice graphic on the layers of an embedded software is this: http://www.limifrog.io/wordpress/wp-content/uploads/2015/07/... - getting the toolchain running to blink a LED takes some efforts. With scripting, you could save time in the context of prototyping a connected experience (networking, hardware, network protocols)

Re: mJS – A new approach to embedded scripting

#25
Is this a re-packaged v7 [0] (it's from Cesanta as well)? mjs.c is 477K. It looks like it as v7.c is 475K [1]. It shaves whole entire 1MB from my staticly linked builds (v7 1.9MB vs. mjs 998K), and almost 2MB from dynamically linked builds (v7 1.9MB vs. mjs 99K) on amd64. If it shares the same underlying architecture and api [2] then this is a pretty great achievement.

In their docs, they claim 25K storage and 10K RAM. Blog post claims 25K storage and 1K RAM.

[0] https://github.com/cesanta/mjs/blob/master/mjs.c

[1] https://github.com/cesanta/v7/blob/master/v7.c

[2] https://docs.cesanta.com/v7/master/#/v7-internals/

Re: mJS – A new approach to embedded scripting

#26

Earlier quoted context omitted.

I'd wager a large amount of that is handling symbol lookup for calling through the FFI.

I quote the mJS readme from the repo: > In order to make FFI work, mJS must be able to get the address of a C function by its name. On POSIX systems, dlsym() API can do that. On Windows, GetProcAddress(). On embedded systems, a system resolver should be either manually written, or be implemented with some aid from a firmware linker script. So I guess they don't provide any implementation for their FFI linking on embe…

Currently we use mJS in our Mongoose OS firmware framework. There, a symbol resolver is generated automatically from the configuration file which tells which symbols you'd like to use.

https://github.com/cesanta/mongoose-os/blob/master/fw/exampl...

Re: mJS – A new approach to embedded scripting

#27
post #25

Is this a re-packaged v7 [0] (it's from Cesanta as well)? mjs.c is 477K. It looks like it as v7.c is 475K [1]. It shaves whole entire 1MB from my staticly linked builds (v7 1.9MB vs. mjs 998K), and almost 2MB from dynamically linked builds (v7 1.9MB vs. mjs 99K) on amd64. If it shares the same underlying architecture and api [2] then this is a pretty great achievement. In their docs, they claim 25K storage and 10K RA…

i wonder if the size could be reduced by replacing the yacc code with a hand-written parser.

Re: mJS – A new approach to embedded scripting

#28
post #12

Earlier quoted context omitted.

Scripting is rarely about syntax. It's about being able to load code dynamically, being able to create ad-hoc data structures, quick changes and distributing executables as source rather than binaries.

None of which are particularly appropriate for embedded programming.

All of these which are very appropriate for a company who wants to sell hobbyist kits to kids who already know JavaScript, so they can built IoT toys quickly.

I understand your point. These tools aren't appropriate for serious embedded systems, but they're also not meant for them. They're meant for people who want to have fun and want to play with things quickly.

Re: mJS – A new approach to embedded scripting

#29
post #27
post #25

Is this a re-packaged v7 [0] (it's from Cesanta as well)? mjs.c is 477K. It looks like it as v7.c is 475K [1]. It shaves whole entire 1MB from my staticly linked builds (v7 1.9MB vs. mjs 998K), and almost 2MB from dynamically linked builds (v7 1.9MB vs. mjs 99K) on amd64. If it shares the same underlying architecture and api [2] then this is a pretty great achievement. In their docs, they claim 25K storage and 10K RA…

i wonder if the size could be reduced by replacing the yacc code with a hand-written parser.

There is no yacc code in either V7 or mJS.

V7 uses hand-written recursive-descent parser. Initially, it was using ordinary C functions, and that created a problem on systems with low stack size. E.g. each '(' starts statement parsing from the top, so 1 + (2 + (3 + (4 + 5))) consumed stack, and sometimes resulted in stack overflow in e.g. interrupt handlers or network callbacks.

Therefore we have rewritten recursive descent using C coroutines, and that is extremely sophisticated piece of work. See https://raw.githubusercontent.com/cesanta/v7/master/v7.c , search for #line 1 "v7/src/parser.c"

mJS on the other hand uses lemon parser generator - the one from sqlite project. It generates a LALR parser which is quite efficient in terms of memory.

Re: mJS – A new approach to embedded scripting

#30
post #12

Earlier quoted context omitted.

Scripting is rarely about syntax. It's about being able to load code dynamically, being able to create ad-hoc data structures, quick changes and distributing executables as source rather than binaries.

None of which are particularly appropriate for embedded programming.

I've adopted a rule where I try to replace a sentence, thought, or expression with, "That's different from how we do things right now," and then try to see if it changes the meaning of what was actually said. Mostly, this is useful when the comment serves to justify shooting down another idea.

"We can't do things that way, because we do things a different way", is something that many people will automatically recognize as a bad argument if you put it that way. (It's in the same bucket as, "Well, nobody has ever complained before.") But anyone—even by accident—can end up using this argument while saying different words. The effect is that it comes in a different package that's more difficult to spot. In the end, though, it's the same invalid discussion killer.

Anyway, that's a lot of exposition. What I came here to say is that your comment is tripping the filter for me right now.

What's inappropriate about a fast development feedback cycle when doing embedded programming?

Post reply on HN