Giter Club home page Giter Club logo

mjs's People

Contributors

alashkin avatar cpq avatar dimonomid avatar eliot-akira avatar novlean avatar paulrouget avatar rojer avatar ruslanvaliullin avatar timgates42 avatar zserge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mjs's Issues

mJs UART API performance problems

I try the mJs UART APIs to receive datas on ESP32 uart port.

Data rate: 46 bytes per 20ms, total 23000 bytes in 10s.

There are some performance problems.

let rxAcc = ""; // to store all the bytes received
let rx_total = 0; // total number of received bytes
// Configure UART at 115200 baud
UART.setConfig(1,{
  baudRate: 115200,
});

UART.setDispatcher(1, function(uartNo, ud) {
  let ra = UART.readAvail(uartNo);
  if (ra > 0) {
    let data = UART.read(uartNo);
    rxAcc += data;
    rx_total += data.length;  
  }
}, null);

// Enable Rx
UART.setRxEnabled(1, true);

UART.write(1,"go");  // signal, a nodejs serialport connected to EPS32 will start 
                        sending data

Timer.set(15000 /* milliseconds */, false /* repeat */, function() {
  print("rxAcc lent: "); // =>13150, some datas are lost by rxAcc += data; !!!
  print(rxAcc.length);
  print("rx_total: ");  // =>23000, all the datas are transfered from C to mJs.
  print(rx_total);
}, null);

Here, rx_total = 23000 means that all the datas are received and transfered to mJs by mongoose os kernel.
And, rxAcc.length = 13510 means some datas are lost when "rxAcc += data" is executed !!!

If I change the data rate to 46 bytes per 40ms , rxAcc.length = 23000 all the time, no bytes are lost.

If I delete the "rxAcc += data" line, no data will be lost at the MAX data rate: 46 bytes per 7ms, about 52500bps. Code is here:

UART.setDispatcher(1, function(uartNo, ud) { let ra = UART.readAvail(uartNo); if (ra > 0) { let data = UART.read(uartNo); // rxAcc += data; rx_total += data.length; } }, null);

I have tried to tune the rx buffer size to 1024/2048, the same result.

My questions are:

  1. How can I store datas without losing at data rate: 46 bytes per 20ms?

  2. Is 52500bps the TOP speed of mJs UART APIs?

  3. Is there some way to improve the performance of mJs UART APIs?

migration from v7 to mjs: v7_interrupt

In old v7 versions there was v7_interrupt in order to
"It sets a flag that will cause the interpreter to throw an InterruptedError"
is this available in mjs or the only way is to invoke internal die()?

Support require

Hello!

My experience with Mongoose OS has been great! I'm currently writing an article and I had a thought.

For onboarding of other JS users, it may be helpful to support require as well as load. Both could just reference the same function like so:

mjs_set(mjs, obj, "load", ~0, mjs_mk_foreign(mjs, mjs_load));

array push

any plan to implement array.push() as built in function?

Functions aren't considered objects

Functions are not considered objects, though in JS everything is an object.

Sample code:

let a = function () {
  // stuff
}

 // errors out
a.test = {}

Sample stack trace:

MJS error: parse error at line 6: [.test = {}]

Another test:

$ mjs -e '(function(){let a=function(){};a.test={}}())'
  at <stdin>:1
  at <stdin>:1
MJS error: unsupported object type

Add API for SPI

Now that SPI support has been added to Mongoose OS. Would it be possible to add the API to mjs. Thanks!

Segmentation Faults 2017-05-10

Hello,
I was using American Fuzzy Lop (afl-fuzz) to fuzz input the mjs program on Linux. Is fixing the crashes from these input files something you're interested in? The input files can be found here: https://github.com/rwhitworth/mjs-fuzz/tree/master/2017-05-10. I used mjs compiled from git commit 8fe46f1, as mentioned in issue #32. If there is a better way to compile this for Linux on x86_64 please let me know so I can use the latest version.

The files can be executed as ./mjs id_filename to cause seg faults.

Let me know if I can provide any more information to help narrow down this issue.

support for mJS with stm32f100R8

Hi, I'll like help about this;
I like the idea of a interpreter for stm32f100 with 128k of memory ROM.
I tried compiled for this, and I have this problems:

../mJS/mjs.c:1526:20: fatal error: memory.h: No such file or directory
compilation terminated.
Makefile:123: recipe for target 'build/mjs.o' failed
make: *** [build/mjs.o] Error 1

and this is similary for
#include <stm32_sdk_hal.h>

fine, I searched about this (stm32_sdk_hal.h) and I did not get results.
Can you help me, some configuration that i can follow ?
Thank you,
regards.

Johnny

Issue in ffi parser?

I've made a small toy environment for controlling strips of neopixels.

I think I hit a bug in the FFI parser.

With the following JS:

let fade = ffi("void fade(int keep)");
let update = ffi("void update()");
let rgb = ffi("void rgb(int p, int r, int g, int b)");
let rgbl = ffi("void rgbl(int p, int r, int g, int b, int keep)");
let hue = ffi("void hue(int p, int h)");
let msleep = ffi("void msleep(int ms)");

let i = 0;
let j = 0;
while (true) {
  hue(i, j);
  update();
  i = (i + 1) % 10;
  j = (j + 13) & 768;
  msleep(33);
}

It crashes with the error:

failed to call FFI signature "void hue(int p, int h)": wrong arg type: failed to parse val type "int p"

I don't see any error with this line. I'm using the same syntax and conventions of the other ffi lines that appear to work.

How can I extend mjs

hi,

There is no problem when use mjs. But How can I modify it? e.g. include var keyword, or String functions.

And I find It's hard to debug mjs(the source code is mixed by multi file).

Any information or suggest about this? Thanks.

High cpu load on memory increase

CPU load almost 100% on mjs manage about 3M memory.

Here is my test code and data, tested on osx x86_64.

load.c

#include "mjs.h"
#include <dlfcn.h>
#include <string.h>
#include <sys/time.h>

int main(int argc, char *argv[])
{
    /*
     * prepare big object
     */
    char strbuf[10000];
    int len = 0;
    FILE *fp = fopen("./x.json", "r");
    if (fp) {
        memset(strbuf, 0x0, sizeof(strbuf));
        len = fread(strbuf, 1, 10000, fp);
        fclose(fp);
        printf("read %d bytes from x.json\n", len);
    } else {
        printf("can't open x.json\n");
        return 1;
    }


    struct mjs *jsm = mjs_create();

    mjs_set_ffi_resolver(jsm, dlsym);

    mjs_err_t jerr;
    mjs_val_t res;
    jerr = mjs_exec_file(jsm, "./x.js", &res);
    if (jerr != MJS_OK) {
        printf("%s\n", mjs_strerror(jsm, jerr));
    }

    mjs_val_t global = mjs_get_global(jsm);
    mjs_val_t object = mjs_get(jsm, global, "myObject", ~0);
    mjs_val_t function = mjs_get(jsm, object, "test_func", ~0);

    struct timeval total_tvs, total_tve;
    gettimeofday(&total_tvs, NULL);

    for (int i = 0; i < 100; i++) {
        struct timeval tvs, tve;
        gettimeofday(&tvs, NULL);

        mjs_val_t a1 = mjs_mk_string(jsm, strbuf, len, 0);

        jerr = mjs_call(jsm, &res, function, object, 1, a1);
        if (jerr != MJS_OK) {
            printf("%s", mjs_strerror(jsm, jerr));
        }

        gettimeofday(&tve, NULL);

        //unsigned long ela = (tve.tv_sec - tvs.tv_sec) * 1000000ul + (tve.tv_usec - tvs.tv_usec);
        printf("call %d elapsed %d seconds\n", i, tve.tv_sec - tvs.tv_sec);
    }

    gettimeofday(&total_tve, NULL);

    printf("totoal elapsed %d seconds\n", total_tve.tv_sec - total_tvs.tv_sec);

    mjs_destroy(jsm);

    return 0;
}

x.js

let myObject = {
    arrs: [],
    test_func: function(orders) {
        this.arrs[this.arrs.length] = JSON.parse(orders);
        //JSON.parse(orders);
        //print(orders);
        print(this.arrs.length);
    }
};

x.json

{"orders":[{"type_desc":"已买入","count":2000,"price":460000,"type":4,"bid":true,"channel":"CXA","code":"OCC","id":"36C8E003"},{"type_desc":"已买入","count":2000,"price":320000,"type":4,"bid":true,"channel":"CXA","code":"DRM","id":"37CBE003"},{"type_desc":"已买入","count":2000,"price":500000,"type":4,"bid":true,"channel":"CXA","code":"AWE","id":"10CDE003"},{"type_desc":"已卖出","count":2000,"price":325000,"type":5,"bid":false,"channel":"CXA","code":"DRM","id":"20CEE003"},{"type_desc":"委托买入","count":2000,"price":250000,"type":1,"bid":true,"channel":"CXA","code":"BLG","id":"31D0E003"},{"type_desc":"委托买入","count":2000,"price":440000,"type":1,"bid":true,"channel":"CXA","code":"BIG","id":"57D0E003"},{"type_desc":"取消委托","count":2000,"price":465000,"type":3,"bid":false,"channel":"CXA","code":"OCC","id":"80D0E003"},{"type_desc":"已买入","count":10000,"price":95000,"type":4,"bid":true,"channel":"CXA","code":"FGR","id":"B6D0E003"},{"type_desc":"已卖出","count":2000,"price":460000,"type":5,"bid":false,"channel":"CXA","code":"OCC","id":"97D1E003"},{"type_desc":"已买入","count":2000,"price":320000,"type":4,"bid":true,"channel":"CXA","code":"DRM","id":"FBD1E003"},{"type_desc":"已卖出","count":324,"price":325000,"type":5,"bid":false,"channel":"CXA","code":"DRM","id":"8CD2E003"},{"type_desc":"已卖出","count":1676,"price":325000,"type":5,"bid":false,"channel":"CXA","code":"DRM","id":"2ED3E003"},{"type_desc":"已买入","count":2000,"price":320000,"type":4,"bid":true,"channel":"CXA","code":"DRM","id":"CED3E003"},{"type_desc":"已买入","count":2000,"price":450000,"type":4,"bid":true,"channel":"CXA","code":"OCC","id":"DDD3E003"},{"type_desc":"已买入","count":2000,"price":455000,"type":4,"bid":true,"channel":"CXA","code":"OCC","id":"F2D4E003"},{"type_desc":"已卖出","count":2000,"price":460000,"type":5,"bid":false,"channel":"CXA","code":"OCC","id":"40D6E003"},{"type_desc":"已卖出","count":2000,"price":455000,"type":5,"bid":false,"channel":"ASXT","code":"OCC","id":"44D7E003"},{"type_desc":"委托买入","count":1250,"price":450000,"type":1,"bid":true,"channel":"CXA","code":"OCC","id":"4AD7E003"},{"type_desc":"委托买入","count":2000,"price":310000,"type":1,"bid":true,"channel":"CXA","code":"LBT","id":"9AD8E003"},{"type_desc":"委托买入","count":2000,"price":415000,"type":1,"bid":true,"channel":"CXA","code":"PLS","id":"A7D8E003"},{"type_desc":"已买入","count":2000,"price":685000,"type":4,"bid":true,"channel":"CXA","code":"MMJ","id":"AADAE003"},{"type_desc":"已买入","count":2000,"price":2570000,"type":4,"bid":true,"channel":"CXA","code":"WAM","id":"83DCE003"},{"type_desc":"已买入","count":2000,"price":165000,"type":4,"bid":true,"channel":"CXA","code":"SCU","id":"4EE1E003"},{"type_desc":"取消委托","count":2000,"price":805000,"type":3,"bid":true,"channel":"CXA","code":"AC8","id":"75E1E003"},{"type_desc":"已买入","count":2000,"price":800000,"type":4,"bid":true,"channel":"CXA","code":"AC8","id":"96E3E003"},{"type_desc":"取消委托","count":2000,"price":690000,"type":3,"bid":false,"channel":"CXA","code":"MMJ","id":"A2E4E003"},{"type_desc":"已买入","count":2000,"price":675000,"type":4,"bid":true,"channel":"CXA","code":"MMJ","id":"E9E4E003"},{"type_desc":"已卖出","count":2000,"price":685000,"type":5,"bid":false,"channel":"CXA","code":"MMJ","id":"6DE5E003"},{"type_desc":"取消委托","count":7400,"price":96000,"type":3,"bid":false,"channel":"CXA","code":"FGR","id":"1FF4E003"},{"type_desc":"已卖出","count":2000,"price":805000,"type":5,"bid":false,"channel":"CXA","code":"AC8","id":"4DF4E003"},{"type_desc":"已买入","count":2000,"price":800000,"type":4,"bid":true,"channel":"CXA","code":"AC8","id":"A7FDE003"},{"type_desc":"已买入","count":2000,"price":680000,"type":4,"bid":true,"channel":"CXA","code":"MMJ","id":"6FFEE003"},{"type_desc":"取消委托","count":2000,"price":775000,"type":3,"bid":true,"channel":"CXA","code":"AC8","id":"ABFFE003"},{"type_desc":"委托买入","count":2000,"price":770000,"type":1,"bid":true,"channel":"CXA","code":"AC8","id":"D8FFE003"},{"type_desc":"已卖出","count":2000,"price":790000,"type":5,"bid":false,"channel":"CXA","code":"AC8","id":"E5FFE003"},{"type_desc":"取消委托","count":2000,"price":685000,"type":3,"bid":false,"channel":"CXA","code":"MMJ","id":"AD00E103"},{"type_desc":"已卖出","count":2000,"price":680000,"type":5,"bid":false,"channel":"CXA","code":"MMJ","id":"E300E103"},{"type_desc":"取消委托","count":2000,"price":680000,"type":3,"bid":false,"channel":"CXA","code":"MMJ","id":"F104E103"},{"type_desc":"已买入","count":500,"price":25000,"type":4,"bid":true,"channel":"ASXT","code":"AGO","id":"1D05E103"},{"type_desc":"取消委托","count":500,"price":26000,"type":3,"bid":false,"channel":"CXA","code":"AGO","id":"2405E103"},{"type_desc":"取消委托","count":10000,"price":96000,"type":3,"bid":false,"channel":"CXA","code":"FGR","id":"2B05E103"},{"type_desc":"取消委托","count":500,"price":25000,"type":3,"bid":false,"channel":"CXA","code":"AGO","id":"F805E103"},{"type_desc":"已买入","count":2000,"price":780000,"type":4,"bid":true,"channel":"CXA","code":"AC8","id":"190BE103"},{"type_desc":"取消委托","count":2000,"price":170000,"type":3,"bid":false,"channel":"CXA","code":"SCU","id":"840CE103"},{"type_desc":"取消委托","count":2000,"price":502500,"type":3,"bid":false,"channel":"CXAM","code":"AWE","id":"FE0FE103"},{"type_desc":"已买入","count":3000,"price":495000,"type":4,"bid":true,"channel":"CXA","code":"AWE","id":"EF10E103"},{"type_desc":"取消委托","count":2000,"price":500000,"type":3,"bid":true,"channel":"CXA","code":"AWE","id":"FC10E103"},{"type_desc":"已卖出","count":1254,"price":505000,"type":5,"bid":false,"channel":"CXA","code":"AWE","id":"1012E103"},{"type_desc":"已卖出","count":2000,"price":165000,"type":5,"bid":false,"channel":"CXA","code":"SCU","id":"C915E103"},{"type_desc":"已买入","count":2000,"price":405000,"type":4,"bid":true,"channel":"CXA","code":"ESE","id":"1217E103"},{"type_desc":"取消委托","count":2000,"price":410000,"type":3,"bid":false,"channel":"CXA","code":"ESE","id":"A117E103"},{"type_desc":"取消委托","count":2000,"price":385000,"type":3,"bid":true,"channel":"CXA","code":"ESE","id":"AA17E103"},{"type_desc":"取消委托","count":2000,"price":395000,"type":3,"bid":false,"channel":"CXA","code":"ESE","id":"D317E103"},{"type_desc":"取消委托","count":1494,"price":410000,"type":3,"bid":false,"channel":"CXA","code":"ESE","id":"EA17E103"},{"type_desc":"取消委托","count":1494,"price":405000,"type":3,"bid":false,"channel":"ASXT","code":"ESE","id":"F117E103"},{"type_desc":"取消委托","count":1494,"price":395000,"type":3,"bid":false,"channel":"CXA","code":"ESE","id":"F717E103"},{"type_desc":"取消委托","count":1494,"price":390000,"type":3,"bid":false,"channel":"CXA","code":"ESE","id":"0618E103"},{"type_desc":"取消委托","count":1494,"price":405000,"type":3,"bid":false,"channel":"ASXT","code":"ESE","id":"2218E103"},{"type_desc":"取消委托","count":1494,"price":390000,"type":3,"bid":false,"channel":"CXA","code":"ESE","id":"3018E103"},{"type_desc":"已卖出","count":1494,"price":395000,"type":5,"bid":false,"channel":"ASXT","code":"ESE","id":"3E18E103"},{"type_desc":"已买入","count":2000,"price":400000,"type":4,"bid":true,"channel":"ASXT","code":"ESE","id":"FC20E103"},{"type_desc":"已买入","count":2000,"price":775000,"type":4,"bid":true,"channel":"ASXT","code":"CPH","id":"D621E103"},{"type_desc":"取消委托","count":2000,"price":770000,"type":3,"bid":true,"channel":"CXA","code":"CPH","id":"D821E103"},{"type_desc":"已卖出","count":2000,"price":780000,"type":5,"bid":false,"channel":"CXA","code":"CPH","id":"4322E103"},{"type_desc":"委托卖出","count":10000,"price":95000,"type":2,"bid":false,"channel":"CXA","code":"FGR","id":"9C22E103"},{"type_desc":"取消委托","count":2000,"price":775000,"type":3,"bid":true,"channel":"CXA","code":"CPH","id":"2824E103"},{"type_desc":"取消委托","count":2000,"price":2575000,"type":3,"bid":false,"channel":"CXAM","code":"WAM","id":"7E25E103"},{"type_desc":"已卖出","count":2000,"price":2570000,"type":5,"bid":false,"channel":"CXA","code":"WAM","id":"0926E103"},{"type_desc":"已卖出","count":2000,"price":785000,"type":5,"bid":false,"channel":"CXA","code":"AC8","id":"7426E103"},{"type_desc":"委托卖出","count":500,"price":24000,"type":2,"bid":false,"channel":"CXA","code":"AGO","id":"3127E103"},{"type_desc":"已卖出","count":2000,"price":325000,"type":5,"bid":false,"channel":"CXA","code":"DRM","id":"B42BE103"},{"type_desc":"未知类型","count":10000,"price":990000,"type":0,"bid":true,"channel":"CXA","code":"PAI","id":"212DE103"},{"type_desc":"取消委托","count":2000,"price":675000,"type":3,"bid":false,"channel":"CXA","code":"MMJ","id":"C12EE103"},{"type_desc":"取消委托","count":2000,"price":670000,"type":3,"bid":false,"channel":"CXA","code":"MMJ","id":"B72FE103"},{"type_desc":"已卖出","count":2000,"price":665000,"type":5,"bid":false,"channel":"CXA","code":"MMJ","id":"0431E103"},{"type_desc":"委托买入","count":2000,"price":660000,"type":1,"bid":true,"channel":"CXA","code":"MMJ","id":"BE31E103"},{"type_desc":"委托买入","count":2000,"price":320000,"type":1,"bid":true,"channel":"CXA","code":"DRM","id":"2233E103"},{"type_desc":"委托卖出","count":3000,"price":497500,"type":2,"bid":false,"channel":"CXAM","code":"AWE","id":"FD33E103"},{"type_desc":"委托买入","count":2000,"price":765000,"type":1,"bid":true,"channel":"ASXT","code":"CPH","id":"5236E103"},{"type_desc":"委托卖出","count":2000,"price":405000,"type":2,"bid":false,"channel":"ASXT","code":"ESE","id":"8636E103"}]}

Here is the output:

read 9705 bytes from x.json
1 
call 0 elapsed 0 seconds
2 
call 1 elapsed 0 seconds
3 
call 2 elapsed 0 seconds
4 
call 3 elapsed 0 seconds
5 
call 4 elapsed 0 seconds
6 
call 5 elapsed 0 seconds
7 
call 6 elapsed 0 seconds
8 
call 7 elapsed 0 seconds
9 
call 8 elapsed 0 seconds
10 
call 9 elapsed 0 seconds
11 
call 10 elapsed 0 seconds
12 
call 11 elapsed 0 seconds
13 
call 12 elapsed 0 seconds
14 
call 13 elapsed 0 seconds
15 
call 14 elapsed 0 seconds
16 
call 15 elapsed 1 seconds
17 
call 16 elapsed 0 seconds
18 
call 17 elapsed 0 seconds
19 
call 18 elapsed 0 seconds
20 
call 19 elapsed 1 seconds
21 
call 20 elapsed 0 seconds
22 
call 21 elapsed 0 seconds
23 
call 22 elapsed 1 seconds
24 
call 23 elapsed 0 seconds
25 
call 24 elapsed 0 seconds
26 
call 25 elapsed 0 seconds
27 
call 26 elapsed 1 seconds
28 
call 27 elapsed 1 seconds
29 
call 28 elapsed 1 seconds
30 
call 29 elapsed 1 seconds
31 
call 30 elapsed 1 seconds
32 
call 31 elapsed 1 seconds
33 
call 32 elapsed 1 seconds
34 
call 33 elapsed 1 seconds
35 
call 34 elapsed 0 seconds
36 
call 35 elapsed 1 seconds
37 
call 36 elapsed 1 seconds
38 
call 37 elapsed 1 seconds
39 
call 38 elapsed 1 seconds
40 
call 39 elapsed 1 seconds
41 
call 40 elapsed 1 seconds
42 
call 41 elapsed 4 seconds
43 
call 42 elapsed 5 seconds
44 
call 43 elapsed 3 seconds
45 
call 44 elapsed 4 seconds
46 
call 45 elapsed 3 seconds
47 
call 46 elapsed 2 seconds
48 
call 47 elapsed 3 seconds
49 
call 48 elapsed 1 seconds
50 
call 49 elapsed 1 seconds
51 
call 50 elapsed 1 seconds
52 
call 51 elapsed 2 seconds
53 
call 52 elapsed 4 seconds
54 
call 53 elapsed 2 seconds
55 
call 54 elapsed 1 seconds
56 
call 55 elapsed 1 seconds
57 
call 56 elapsed 3 seconds
58 
call 57 elapsed 3 seconds
59 
call 58 elapsed 3 seconds
60 
call 59 elapsed 1 seconds
61 
call 60 elapsed 2 seconds
62 
call 61 elapsed 4 seconds
63 
call 62 elapsed 10 seconds
64 
call 63 elapsed 7 seconds
65 
call 64 elapsed 8 seconds
66 
call 65 elapsed 8 seconds
67 
call 66 elapsed 9 seconds
68 
call 67 elapsed 13 seconds
69 
call 68 elapsed 7 seconds
70 
call 69 elapsed 2 seconds
71 
call 70 elapsed 2 seconds
72 
call 71 elapsed 4 seconds
73 
call 72 elapsed 6 seconds
74 
call 73 elapsed 4 seconds
75 
call 74 elapsed 2 seconds
76 
call 75 elapsed 3 seconds
77 
call 76 elapsed 4 seconds
78 
call 77 elapsed 7 seconds
79 
call 78 elapsed 5 seconds
80 
call 79 elapsed 2 seconds
81 
call 80 elapsed 3 seconds
82 
call 81 elapsed 5 seconds
83 
call 82 elapsed 8 seconds
84 
call 83 elapsed 6 seconds
85 
call 84 elapsed 2 seconds
86 
call 85 elapsed 3 seconds
87 
call 86 elapsed 6 seconds
88 
call 87 elapsed 9 seconds
89 
call 88 elapsed 6 seconds
90 
call 89 elapsed 3 seconds
91 
call 90 elapsed 4 seconds
92 
call 91 elapsed 6 seconds
93 
call 92 elapsed 14 seconds
94 
call 93 elapsed 17 seconds
95 
call 94 elapsed 19 seconds
96 
call 95 elapsed 18 seconds
97 
call 96 elapsed 20 seconds
98 
call 97 elapsed 25 seconds
99 
call 98 elapsed 20 seconds
100 
call 99 elapsed 20 seconds
totoal elapsed 387 seconds

My load:

PID   COMMAND      %CPU TIME     #TH  #WQ  #POR MEM    PURG CMPR PGRP PPID STATE          BOOSTS     %CPU_ME %CPU_OTHRS UID  FAULT COW  MSGS MSGR SYSB SYSM CSW    PAGE IDLE POWE
4750  load         98.8 01:27.67 1/1  0    10   2240K  0B   0B   4750 978  running *0[1]      0.00000 0.00000    501  1310  126  36   15   110  63   72816+ 0    0    98.8

Minor bug in parser

I am writing up the grammar for mjs. While doing so I discovered that a parenthesized expression as a literal does not correctly check for a closing parenthesis. Any character seems to work fine:
$ mjs -e '(123+5]+6'
yields 134 without a syntax error.

Data lost on call an unexist method

say this code:

#include "mjs.h"
#include <dlfcn.h>
#include <limits.h>

int main(int argc, char *argv[])
{
    struct mjs *jsm = mjs_create();

    mjs_set_ffi_resolver(jsm, dlsym);

    mjs_err_t jerr;
    mjs_val_t res;

    jerr = mjs_exec_file(jsm, argv[1], &res);
    if (jerr != MJS_OK) {
        printf("js file error %s\n", mjs_strerror(jsm, jerr));
        return 1;
    }

    for (int i = 0 ; i < 3; i++) {
        mjs_val_t obj = mjs_get(jsm, mjs_get_global(jsm), "obj", ~0);
        mjs_val_t f1 = mjs_get(jsm, obj, "f1", ~0);

        jerr = mjs_call(jsm, &res, f1, obj, 1, mjs_mk_number(jsm, 212));
        if (jerr != MJS_OK) {
            printf("%s\n", mjs_strerror(jsm, jerr));
        }

        if (i == 1) {
            obj = mjs_get(jsm, mjs_get_global(jsm), "obj", ~0);
            f1 = mjs_get(jsm, obj, "funexist", ~0);
            jerr = mjs_call(jsm, &res, f1, obj, 1, mjs_mk_number(jsm, 212));
            if (jerr != MJS_OK) {
                printf("%s\n", mjs_strerror(jsm, jerr));
            }
        }
    }

    return 0;
}

With the follow x.js

let obj = {
    arr: []

    f1: function(a) {
        this.arr[this.arr.length] = a;

        //print('first ' + a);
        print(JSON.stringify(this.arr));
    }
};

Output:

maliang@bogon ~/code/mjs/mjs/tests$ gcc -std=c99 -o x x.c -I ../../ -L ../build/ -lmjs
maliang@bogon ~/code/mjs/mjs/tests$ ./x x.js
[212] 
[212,212] 
[212] 

There are 3 problems:

  1. parse x.js arr: [] whithout , terminate don't return error.

  2. call an unexist method funexist don't return error.

  3. After funexist called, obj.arr[] reseted to empty.

RTLD_DEFAULT not NULL on osx

Just a remind, mjs ffi dlsym can't resolve funciton on mac osx.
After modify these lines in mjs/ffi.c , turns ok.

#ifndef RTLD_DEFAULT
#if defined(__APPLE__)
#define RTLD_DEFAULT ((void *) -2)
#else
#define RTLD_DEFAULT NULL
#endif
#endif

Non-amalgated source

Hi. mjs.c seems to be generated/combined from many individual .c files.

Is the non-amalgated source available anywhere, or do you have plans to provide this?

SequenceExpressions are not parsed correctly

SequenceExpressions (i.e. comma-separated expressions) are used as a minification strategy in most minifiers (i.e. babili, uglifyjs) but they cause mjs to error out:

// this is valid javascript
print('1'),print('2')
// should result in:
// 1
// 2

^ this causes mjs to error out at runtime: MJS error: parse error at line 1: [,print('2']

This specific case can be solved by using a semicolon instead of a comma, but this doesn't work for when a minifier uses a sequence expression in a return statement.

I understand the goal of being a restricted JS engine, but parser support for sequence expressions would be very useful for reserving space in mos firmwares that use mjs. By running my firmware through a minifier first, I can improve performance and squeeze more code into the microcontroller.

ffi exports are not parsed correctly

It seems that at build time, when uses of ffi() are searched for in the JS code, the search also checks comments.

For instance, the following code can cause the build to error out:

// just to kill things: ffi('void non-existent-function(double)')

Which means that when debugging, if I want to comment out the ffi() use, I have to change the name of the function to ffi_ or anything else - I can't just comment it out.

Perhaps the defining of ffi_exports can be moved into a header file (i.e. main.h) or through main.c since they are converted to C anyways during the build process. Having the build process pull it out of the JS can lead to other issues as well and gives the illusion of dynamic interoperability - which isn't really the case anyways.

i compile mjs by arm-none-eabi-gcc,the code is very large

i put mjs.h and mjs.c into a empty project ,define MARCO #define CS_PLATFORM CS_P_STM32 in mjs.h.
then compile the project by arm-none-eabi-gcc,the code is very large.

'Invoking: Cross ARM GNU Print Size'
arm-none-eabi-size --format=berkeley "test.elf"
   text	   data	    bss	    dec	    hex	filename
 110796	   2772	    356	 113924	  1bd04	test.elf
Finished building: test.siz

the compile command is
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections --specs=nosys.specs -g3 -T "D:\workspace\test\START\stm32_flash.ld" -Xlinker --gc-sections -Wl,-Map,"test.map" -o "test.elf" ./mjs/mjs.o ./USER/io.o ./USER/main.o ./USER/uart.o ./START/startup/startup_stm32f10x_md.o ./START/system_stm32f10x.o ./LIB/stm32f10x_gpio.o ./LIB/stm32f10x_rcc.o ./LIB/stm32f10x_tim.o ./LIB/stm32f10x_usart.o ./CMSIS/core_cm3.o

mjs/mjs make generates errors about missing common/mg_str.h

mkdir -p build
clang -lm -W -Wall -g -I. -I.. -Isrc -DMJS_MAIN -DMJS_EXPOSE_PRIVATE -DCS_ENABLE_STDIO -DMJS_ENABLE_DEBUG -DCS_MMAP -Wl,--no-as-needed -ldl src/../../common/cs_dbg.c src/../../common/cs_file.c src/../../common/cs_varint.c src/../../common/mbuf.c src/../../common/str_util.c src/../../frozen/frozen.c src/ffi/ffi.c src/mjs_array.c src/mjs_bcode.c src/mjs_builtin.c src/mjs_conversion.c src/mjs_core.c src/mjs_dataview.c src/mjs_exec.c src/mjs_ffi.c src/mjs_gc.c src/mjs_json.c src/mjs_main.c src/mjs_object.c src/mjs_parser.c src/mjs_primitive.c src/mjs_string.c src/mjs_tok.c src/mjs_util.c -o build/mjs
In file included from src/../../common/cs_dbg.c:13:
../common/str_util.h:13:10: fatal error: 'common/mg_str.h' file not found
#include "common/mg_str.h"
^
1 error generated.

.length throws MJS exec error: type error

let s = "hello";
print(s); // => hello
print(s.length); // => mgos_app_init MJS exec error: type error

s.length throws MJS exec error: type error.

=> means outputs

Questions about bindings.

Just for fun, I decided to see if I can bind to various libuv functions to make a really light-weight node.js.

As a test, I tried one of the simpler functions:

int uv_exepath(char* buffer, size_t* size)

At a high level, this takes no arguments and returns a string, but this is C and memory management is hard in C.

In JavaScript I'd ideally have a function like this:

let path = exepath();

I wrote something that works, but it leaks memory and is ugly.

// Wrapper function in C
char* exepath() {
  size_t size = 2*PATH_MAX;
  char exe_path[2*PATH_MAX];
  int ret = uv_exepath(exe_path, &size);
  if (ret < 0) return "[error]";
  exe_path[size] = 0;
  char* path = malloc(size + 1);
  for (int i = 0; i < size; i++) {
    path[i] = exe_path[i];
  }
  path[size] = 0;
  return path;
}
let exepath = ffi("char *exepath()");

What are the rules about returning strings from C and how does ownership work? In all the scripting languages I've ever worked with before, the C code lends a buffer which the VM copies into itself and manages using the GC. The C code then has ownership of the original again.

I don't see any way to do this here? Does this language engine simply not care about strings in this manner?

condition express parse bug

On conditional express, such as if (expa && expb), if expa is false, expb should not be excuted.

for example:

maliang@bogon ~/code/mjs/mjs$ ./build/mjs -e "let a = 1, b = 2; if (a > 1 && (b = b+1) > 2) print(a); print(b)"
3 
undefined

b should not add 1

mg_base64_decode error in ffi

I use mg_base64_decode to do base64 decode work on ESP32.

let n = ffi('int mg_base64_decode(void *, int, void *)')(src, len, dst);

when n < 1580, It can work.
when n >1580, It will crash:
ERROR: wrong bcode offset 18443
at :1
MJS callback error: implicit type conversion is prohibited

build

lemonhall@HalldeMacBook-Pro:~/Downloads/mjs/mjs$ make
Makefile:87: ../common.mk: No such file or directory
make: *** No rule to make target `../common.mk'.  Stop.
lemonhall@HalldeMacBook-Pro:~/Downloads/mjs/mjs$

can i build it vs 2017?

i am getting errors building it on visual studio 2017?

has anyone compiled it on windows?

include in esp32 firmware

hello, i would like to integrate mjs into my firmware but i can not understand how to do it. I tried to include the sources but I can not compile. thank you

Can I extend mjs through mjs_op_getprop() ?

Say I need to pop out an item from an array, Since there is no prototypes for Array, I couldn't use array.prototype.pop() to do this.

I notice that there is a function mjs_op_getprop() nearly to it. So, Can I write my own pop properity for array val? This function is used to get valriable(push an val to &vm->dstack), not for just modify Array. I couldn't make sure is it properly?

BTW, I use array[array.length] = newitem to performe array.push(newitem), It should be more user friendly if i extended the later way.

More readable error trace

Is there any function to trace the js execution error, like v7_printf_error() in v7?

I use mjs_str_error() currently, and it's output isn't readable as much as v7_printf_error(), especially error occured with in multipile js files.

Here is my test js files:

1.js

let x = {
    floor: ffi('double floor(double)'),
    floor2: ffi('double floor_unexist(double)')
};

2.js

load("tests/1.js")

let y = {
    foo: function(n) {
        return x.floor(n);
    },
    foo2: function(n) {
        return x.floor2(n);
    }
};


y.foo(12.3);
y.foo2(12.3);

Here is the error output:
maliang@bogon ~/code/mjs/mjs$ ./build/mjs tests/2.js
at tests/2.js:8
at tests/2.js:14
undefined

There are 3 main problem:

  1. tests/1.js not appeared in error string.
  2. js function names not appeared in error string.
  3. no ffi failed (change mjs_strerror(mjs, mjs->error) to mjs_strerror(mjs, res) will have failed to call FFI...)

BTW, If I have some spell mistake in 1.js. e.g.:

let x = {
    floor: ffi('double floor(double)');
    floor2: ffi('double floor_unexist(double)')
};

Error trace message can't totoaly understood.
maliang@bogon ~/code/mjs/mjs$ ./build/mjs tests/2.js
at tests/2.js:1
undefined
If i use mjs_strerror(mjs, res) instead of mjs_strerror(mjs, mjs->error):
at tests/2.js:1
NO_ERROR
undefined

Cool feature Proxy supports

Hey guys!

I was working on an opensource project running on iOS. I found mjs is my best choice as an embedded js engine although if there is a Proxy class like this or method_missing in ruby like this.

It will make mjs more flexible. What are you thinking?

invalid JSON string on JSON.parse() when object has more than 20 nodes

As mentioned on title, tested under osx and x86_64 linux.

Here is my exe.c

#include <dlfcn.h>

#include "mjs.h"

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("useage: %s js file\n", argv[0]);
        return 1;
    }

    struct mjs *jsm = mjs_create();
    mjs_set_ffi_resolver(jsm, dlsym);

    mjs_err_t jserr;
    mjs_val_t res;

    jserr = mjs_exec_file(jsm, argv[1], &res);
    if (jserr != MJS_OK) {
        printf("%s\n", mjs_strerror(jsm, jserr));
    }

    mjs_println(jsm, res);

    return 0;
}

And there are two js file: 1.js, 2.js

let x = '{"a":1,"b":1,"c":1,"d":1,"e":1,"f":1,"g":1,"h":1,"i":1,"j":1,"k":1,"l":1,"m":1,"n":1,"o":1,"p":1,"q":1,"r":1,"s":1,"t":1}';

let xo = JSON.parse(x);
let x = '{"a":1,"b":1,"c":1,"d":1,"e":1,"f":1,"g":1,"h":1,"i":1,"j":1,"k":1,"l":1,"m":1,"n":1,"o":1,"p":1,"q":1,"r":1,"s":1,"t":1, "u": 1}';

let xo = JSON.parse(x);

Here is the output:
maliang@bogon ~/tmp/x/mjs$ ./exec 1.js
[object Object]
maliang@bogon ~/tmp/x/mjs$ ./exec 2.js
invalid JSON string
undefined

When I use cc mjs.c -DMJS_MAIN -D_DARWIN_C_SOURCE -o mjsexec, and the later js work ok when it is the command parameter
maliang@bogon ~/tmp/x/mjs$ ./mjsexec -e "let x = '{"a":1,"b":1,"c":1,"d":1,"e":1,"f":1,"g":1,"h":1,"i":1,"j":1,"k":1,"l":1,"m":1,"n":1,"o":1,"p":1,"q":1,"r":1,"s":1,"t":1, "u":1,"v":1}'; let xo = JSON.parse(x)"
[object Object]

Running unit tests on Centos 6 32-bit

I had some trouble running the unit tests to all PASS.
This is on a Centos 6 32-bit machine. I discovered that it is best to use -rdynamic as extra
CFLAGS in the Makefile. Also, I extended the typedefs in ffi.c to include the 2 and 3 argument cases
and added explicit code to detect and handle them. The problem I was seeing that f(int, double)
was not handled correctly and gave me wrong argument values.
Surprisingly, on a Centos x86_64 none of these problems occurred.

Wrong return value in callback function

I'm working on STM32F103C8 (Blue-Pill) and am unable to understand the basics of callbacks, at least so it seems since I don't get the expected results.

Here is my C code, just a simple callback test:

void (*my_callback)(int, void *);
void *my_user_data;

void timer(int seconds, void (*callback)(int, void *), void *user_data) {
	my_callback = callback;
	my_user_data = user_data;
}


void *my_dlsym(void *handle, const char *name) {
	if (strcmp(name, "timer") == 0)
		return (void *) timer;
	return NULL;
}

int main() {
...
	struct mjs *mjs = mjs_create();
	mjs_set_ffi_resolver(mjs, my_dlsym);
	mjs_exec(mjs, APP_JS, NULL);

	int j = 0;
	while (1) {
		for (uint32_t i = 0; i < 0xFFFFFF; i++) {
			asm("nop");
		}
		my_callback(++j, my_user_data);
	}
}

And a little JS:

let Timer = {
  set: ffi('void timer(int, void (*)(int, userdata), userdata)')
};

Timer.set(200, function(t) {
  print('Time now: ', t);
}, null);

print('JS is initialized');

Console output:

JS is initialized 
Time now:  ld  <-- this repeats, but actually should be counting up from 0

Also maybe the relevant build options:

Building file: ../3rdparty/mjs.c
Invoking: GNU ARM Cross C Compiler
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -flto  -g -DSTM32F103xB -DMG_ENABLE_FILESYSTEM=0 -DCS_PLATFORM=CS_P_STM32 -DHSE_VALUE=8000000U -I"/home/ivan/eclipse-workspace/blue-squirrel/3rdparty/CMSIS/Include" -I"/home/ivan/eclipse-workspace/blue-squirrel/include" -I"/home/ivan/eclipse-workspace/blue-squirrel/3rdparty/CMSIS/Device/ST/STM32F1xx/Include" -std=gnu11 -MMD -MP -MF"3rdparty/mjs.d" -MT"3rdparty/mjs.o" -c -o "3rdparty/mjs.o" "../3rdparty/mjs.c"
Finished building: ../3rdparty/mjs.c

Also I had to remove two lines in the condensed mjs.c file, since it didn't work with them:

Line 2200: #include <dirent.h> --> #error "<dirent.h> not supported"
Line 1528: #include <stm32_sdk_hal.h> --> Not using it, not required, I do the low level stuff myself

Any help is apprechiated, thx for this great project btw.

mjs not compiling

mjs will not compile any more as a library with mongoose-os mos tool on esp8266

the compillation-error output boils down to these lines around the new changes:
In function 'mjs_fprintf':
/tmp/fwbuild-volumes/users/test/esp8266mos_rebuild/build_requests/build_req_065270790/modules/mjs/mjs.c:12534:7: error: array subscript has type 'char' [-Werror=char-subscripts]
if (isprint(s[i])) {
^

am i doing something wrong?

~/.mos/bin/mos update
Up to date.
$proj/mos.yml:
author: Daniel Jürgen
description: Just a mos-project
version: 0.5.7
arch: esp8266
mongoose_os_version: master
tags:

"no userdata arg" problem

Hello! I'm trying to bind this c function:

void sc_register_callback(void (*_callback)(char *)){
}

with mjs like so:

ffi('void sc_register_callback(void (*)(char *))')

but mjs keeps asking about userdata arg:

MJS error: failed to exec file "api_websocket.js": bad ffi signature: "void sc_register_callback(void (*)(char ))": bad ffi signature: "void ()(char *)": no userdata arg

how to spilt file

this is a great project , i want deep learn this code ,but Very few lines of code,How to split header file and source file into some single file.
I hope to have nothing to do with the platform, like Lua, do not rely too much on the library.

wrong bcode offset on function parameter TYPE_ERROR

Here is the test case:

./build/mjs -e "let y = {foo: function(s){return s}, foo2: function(){y.foo('xxx' + 10)}}; y.foo2();"
  at <stdin>:1
  at <stdin>:1
ERROR: wrong bcode offset -2147483648
  at <unknown-filename>:1
Error: TYPE_ERROR

This is the js file in pretty format:

let y = {
    foo: function(s) {
        return s;
    },
    foo2: function() {
        return y.foo('xxx' + 10);
    }
};

y.foo2();

slice() throws MJS exec error: type error

let s = "hello";
print(s); // => hello
print(s.length); // =>5
let b = s.slice(1,3); // => mgos_app_init MJS exec error: type error
print(b); // => nothing output

ffi_exports.c errors

Today, when I build my mos project, I get much more ffi_exports.c erros, like this:

/app/build/gen/ffi_exports.c:146:6: error: conflicting types for 'mgos_conf_value_type'
int mgos_conf_value_type(void *);
^
/app/build/gen/ffi_exports.c:145:6: note: previous declaration of 'mgos_conf_value_type' was here
void mgos_conf_value_type(void);

The mos project can be built some days ago.
I have updated the mos tool.

Implement into a custom os

I'm trying to implement mjs into my own os called RossOS, and I'm just getting reboots and page faults.

array.splice() bug on deleteCount = 0

./build/mjs -e "let x = [{'f': 1}, {'f':2}, {'f':3}]; x.splice(1,0, {'f': 100}); print(JSON.stringify(x));"
[{"f":1},{"f":100},null,{"f":3}] 
undefined

{'f': 2} not moved to new position.

floor example do not work on esp8266

init.js:

let floor = ffi('double floor(double)');
print(floor(1.23456));

mgos_app_init MJS exec error: failed to call FFI signature "double floor(double)": cannot resolve function �

Arrays: type issue

Hi, mJS looks very promising, running it on quite restricted micro (STM32L0)!
But I have some problems with using arrays.

let a=[2,3,4];
print(a[1]);

The elements seem to have a strange type... is it float? It can't access them properly (sometimes stalls my micro, need to investigate)...

Are there any examples for the use of arrays with mJS already?

mJS FFI not working (ESP8266)

Example from the documentation:

let printf = ffi('int printf(char *, int, char *)');
printf('Hi %d %s\n', 123, 'foo');

Result: MJS callback error: failed to call FFI signature "int printf(char *, int, char *)": cannot resolve function � : failed to call FFI signature "int printf(char *, int, char *)": cannot resolve function m : failed to call FFI signature "int printf(char *, int, char *)": cannot resolve function } : failed to call FFI signature "int printf(char *, int, char *)": cannot resolve function �
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.