cesanta / mjs

Embedded JavaScript engine for C/C++
https://mongoose-os.com
Other
1.9k stars 172 forks source link

AVR (ATMega328) support #89

Open RossComputerGuy opened 6 years ago

RossComputerGuy commented 6 years ago

I'm working on a project and I'm using AVR Libc and AVR GCC to compile it. I'm needing a JavaScript engine, so I am using this one. However, whenever I compile, I get lots of errors. Output:

deps/mjs/mjs.c:67:2: error: #error "CS_PLATFORM is not specified and we couldn't guess it."
 #error "CS_PLATFORM is not specified and we couldn't guess it."
  ^
deps/mjs/mjs.c:2232:40: error: unknown type name ‘bool’
 void ffi_set_bool(struct ffi_arg *arg, bool v);
                                        ^
deps/mjs/mjs.c: In function ‘json_vprintf’:
deps/mjs/mjs.c:5726:20: error: expected ‘:’ before ‘PRIu64’
 #define UINT64_FMT PRIu64
                    ^
deps/mjs/mjs.c:6221:48: note: in expansion of macro ‘UINT64_FMT’
         const char *fmt2 = fmt[3] == 'u' ? "%" UINT64_FMT : "%" INT64_FMT;
                                                ^
deps/mjs/mjs.c:6336:34: error: expected ‘)’ before ‘PRId64’
         if ((n + 1 == strlen("%" PRId64) && strcmp(fmt2, "%" PRId64) == 0) ||
                                  ^
deps/mjs/mjs.c:6336:62: error: expected ‘)’ before ‘PRId64’
         if ((n + 1 == strlen("%" PRId64) && strcmp(fmt2, "%" PRId64) == 0) ||
                                                              ^
deps/mjs/mjs.c:6337:34: error: expected ‘)’ before ‘PRIu64’
             (n + 1 == strlen("%" PRIu64) && strcmp(fmt2, "%" PRIu64) == 0)) {
                                  ^
deps/mjs/mjs.c:6337:62: error: expected ‘)’ before ‘PRIu64’
             (n + 1 == strlen("%" PRIu64) && strcmp(fmt2, "%" PRIu64) == 0)) {
                                                              ^
deps/mjs/mjs.c:6339:26: error: ‘PRIu64’ undeclared (first use in this function)
           skip += strlen(PRIu64) - 1;
                          ^
deps/mjs/mjs.c:6339:26: note: each undeclared identifier is reported only once for each function it appears in
deps/mjs/mjs.c: In function ‘longtok3’:
deps/mjs/mjs.c:14281:23: warning: left shift count >= width of type [-Wshift-count-overflow]
     return p->pos[-2] << 16 | p->pos[-1] << 8 | p->pos[0];
                       ^
deps/mjs/mjs.c: In function ‘longtok4’:
deps/mjs/mjs.c:14291:23: warning: left shift count >= width of type [-Wshift-count-overflow]
     return p->pos[-3] << 24 | p->pos[-2] << 16 | p->pos[-1] << 8 | p->pos[0];
                       ^
deps/mjs/mjs.c:14291:42: warning: left shift count >= width of type [-Wshift-count-overflow]
     return p->pos[-3] << 24 | p->pos[-2] << 16 | p->pos[-1] << 8 | p->pos[0];
                                          ^
deps/mjs/mjs.c: In function ‘ptranslate’:
deps/mjs/mjs.c:14374:26: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define TT(a, b, c) ((a) << 16 | (b) << 8 | (c))
                          ^
deps/mjs/mjs.c:14421:10: note: in expansion of macro ‘TT’
     case TT('=','=','='): return TOK_EQ_EQ;
          ^
deps/mjs/mjs.c:14421:5: error: case label does not reduce to an integer constant
     case TT('=','=','='): return TOK_EQ_EQ;
     ^
deps/mjs/mjs.c:14374:26: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define TT(a, b, c) ((a) << 16 | (b) << 8 | (c))
                          ^
deps/mjs/mjs.c:14422:10: note: in expansion of macro ‘TT’
     case TT('!','=','='): return TOK_NE_NE;
          ^
deps/mjs/mjs.c:14422:5: error: case label does not reduce to an integer constant
     case TT('!','=','='): return TOK_NE_NE;
     ^
deps/mjs/mjs.c:14374:26: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define TT(a, b, c) ((a) << 16 | (b) << 8 | (c))
                          ^
deps/mjs/mjs.c:14423:10: note: in expansion of macro ‘TT’
     case TT('<','<','='): return TOK_LSHIFT_ASSIGN;
          ^
deps/mjs/mjs.c:14423:5: error: case label does not reduce to an integer constant
     case TT('<','<','='): return TOK_LSHIFT_ASSIGN;
     ^
deps/mjs/mjs.c:14374:26: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define TT(a, b, c) ((a) << 16 | (b) << 8 | (c))
                          ^
deps/mjs/mjs.c:14424:10: note: in expansion of macro ‘TT’
     case TT('>','>','='): return TOK_RSHIFT_ASSIGN;
          ^
deps/mjs/mjs.c:14424:5: error: case label does not reduce to an integer constant
     case TT('>','>','='): return TOK_RSHIFT_ASSIGN;
     ^
deps/mjs/mjs.c:14374:26: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define TT(a, b, c) ((a) << 16 | (b) << 8 | (c))
                          ^
deps/mjs/mjs.c:14425:10: note: in expansion of macro ‘TT’
     case TT('>','>','>'): return TOK_URSHIFT;
          ^
deps/mjs/mjs.c:14425:5: error: case label does not reduce to an integer constant
     case TT('>','>','>'): return TOK_URSHIFT;
     ^
deps/mjs/mjs.c:14375:29: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define QT(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
                             ^
deps/mjs/mjs.c:14426:10: note: in expansion of macro ‘QT’
     case QT('>','>','>','='): return TOK_URSHIFT_ASSIGN;
          ^
deps/mjs/mjs.c:14375:41: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define QT(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
                                         ^
deps/mjs/mjs.c:14426:10: note: in expansion of macro ‘QT’
     case QT('>','>','>','='): return TOK_URSHIFT_ASSIGN;
          ^
deps/mjs/mjs.c:14426:5: error: case label does not reduce to an integer constant
     case QT('>','>','>','='): return TOK_URSHIFT_ASSIGN;
     ^
deps/mjs/mjs.c: In function ‘mjs_jprintf’:
deps/mjs/mjs.c:5723:19: error: expected ‘)’ before ‘PRId64’
 #define INT64_FMT PRId64
                   ^
deps/mjs/mjs.c:14531:28: note: in expansion of macro ‘INT64_FMT’
       json_printf(out, "%" INT64_FMT, (int64_t) d);
                            ^
deps/mjs/mjs.c:5723:19: error: expected ‘)’ before ‘PRId64’
 #define INT64_FMT PRId64
                   ^
deps/mjs/mjs.c:14562:28: note: in expansion of macro ‘INT64_FMT’
     json_printf(out, "%s%" INT64_FMT "%s", "<???", (int64_t) v, ">");
                            ^
deps/mjs/mjs.c: In function ‘mjs_disasm_single’:
deps/mjs/mjs.c:14659:19: warning: variable ‘name’ set but not used [-Wunused-but-set-variable]
       const char *name = "???";
                   ^
deps/mjs/mjs.c:14712:14: warning: variable ‘start’ set but not used [-Wunused-but-set-variable]
       size_t start = 0;
              ^
src/config/targets/firmware/build.mk:20: recipe for target 'deps/mjs/mjs.o' failed
make: *** [deps/mjs/mjs.o] Error 1
jockm commented 6 years ago

TL;DR: You can't run on the m328, It won't work. You might want to look at uLua

There isn't any explicit support for the AVR platform, if you go to mjs.c line 33 (or so if things have changed), you will see where CS_PLATFORM is defined.

Later on in the file you will see various #ifdef statements that use CS_PLATFORM to configure the environment to the given platform. You would need to do this work for the AVR platform. It doesn't look horrible, but it will be a bit of work.

However there may be some other challenges porting to the m328 specifically. The stated code size of mJS is 50K, and the m328 only has 32K of flash. Additionally because the AVR is an 8-bit platform the generated code would likely be even larger than 50K.

Then you have RAM. You only have 2K of of it on the m328. While mJS can startup in 800 bytes (and again this may be larger on the 8-bit AVR), any JS program is likely to need much of what is left for it's own variable space.

This means your JS code would have to live in either flash (which you don't have enough of), or in EEPROM. The m328 has 2K of that, though you would need to write custom functions to access it.

In short: You might be able to port mJS to the m644 (which has 4K of RAM), but the m1284 (16K) would be more likely. This is a much bigger chip, and more expensive, but it could be done.

If you are looking for a scripting language that can run on an AVR take a look at uLua: https://github.com/deemess/uLua

jockm commented 6 years ago

For those curious, there is a JS Engine that works on the 328p: https://github.com/getfilament/throwback

cpq commented 6 years ago

Does is work on m328 ? Their readme mentions 2k RAM requirement.

to @SpaceboyRoss01 - look at common/platform stuff, add headers for the AVR and re-amalgamate, that shouldn't be hard.

jockm commented 6 years ago

Yes, the m328 has 2K of RAM. The whole project is structured as an Arduino IDE library, and has a simple Arduino test program. It looks like they are executing out of the string which would be held in flash.

cpq commented 6 years ago

Yeah, executing directly from a source is a nice idea. mjs in its early stages (now it's the 5th iteration of refactoring) did the same.

jockm commented 6 years ago

Yeah, there are tradeoffs to it. The biggest code size and the fact that you have to publish the source. Still it is an impressive little project.

jockm commented 6 years ago

Should this issue be closed?