Trên GitHub, cesanta/mjs đã đạt 2.1k sao, nhóm Frontend, ngôn ngữ C. Embedded JavaScript engine for C/C++
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
VÌ SAO CHƯA CÓ REVIEW
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
mJS is designed for microcontrollers with limited resources. Main design
goals are: small footprint and simple C/C++ interoperability. mJS
implements a strict subset of ES6 (JavaScript version 6):
Any valid mJS code is a valid ES6 code.
Any valid ES6 code is not necessarily a valid mJS code.
On 32-bit ARM mJS engine takes about 50k of flash memory, and less than 1k
of RAM (see intro article).
mJS is part of MongooseOS,
where it enables scripting for IoT devices.
Restrictions
No standard library. No String, Number, RegExp, Date, Function, etc.
JSON.parse() and JSON.stringify() are available.
No closures, only lexical scoping (i.e. nested functions are allowed).
No exceptions.
No new. In order to create an object with a custom prototype, use
Object.create(), which is available.
Strict mode only.
No var, only let.
No for..of, =>, destructors, generators, proxies, promises.
No getters, setters, valueOf, prototypes, classes, template strings.
No == or !=, only === and !==.
mJS strings are byte strings, not Unicode strings: 'ы'.length === 2,
'ы'[0] === '\xd1', 'ы'[1] === '\x8b'.
mJS string can represent any binary data chunk.
Built-in API
print(arg1, arg2, ...);
Print arguments to stdout, separated by space.
load('file.js', obj);
Execute file file.js. obj paramenter is
optional. obj is a global namespace object.
If not specified, a current global namespace is passed to the script,
which allows file.js to modify the current namespace.
die(message);
Exit interpreter with the given error message
let value = JSON.parse(str);
Parse JSON string and return parsed value.
let str = JSON.stringify(value);
Get string representation of the mJS value.
let proto = {foo: 1}; let o = Object.create(proto);
Create an object with the provided prototype.
'some_string'.slice(start, end);
Return a substring between two indices. Example:
'abcdef'.slice(1,3) === 'bc';
'abc'.at(0);
Return numeric byte value at given string index. Example:
'abc'.at(0) === 0x61;
'abc'.indexOf(substr[, fromIndex]);
Return index of first occurence of substr within the string or `-1`
if not found.
'abc'.indexOf('bc') === 1;
chr(n);
Return 1-byte string whose ASCII code is the integer `n`. If `n` is
not numeric or outside of `0-255` range, `null` is returned. Example:
chr(0x61) === 'a';
let a = [1,2,3,4,5]; a.splice(start, deleteCount, ...);
Change the contents of an array by removing existing elements and/or
adding new elements. Example:
let a = [1,2,3,4,5]; a.splice(1, 2, 100, 101, 102); a === [1,100,101,102,4,5];
let s = mkstr(ptrVar, length);
Create a string backed by a C memory chunk. A string s starts
at memory location ptrVar, and is length bytes long.
let s = mkstr(ptrVar, offset, length, copy = false);
Like `mkstr(ptrVar, length)`, but string s starts
at memory location ptrVar + offset, and the caller can specify
whether the string needs to be copied to the internal mjs buffer. By default
it's not copied.
let f = ffi('int foo(int)');
Import C function into mJS. See next section.
gc(full);
Perform garbage collection. If `full` is `true`, reclaim RAM to OS.
C/C++ interoperability
mJS requires no glue code. The mJS's Foreign Function Interface (FFI)
allows the user to call an existing C function with an arbitrary signature.
Currently mJS provides a simple implementation of the FFI trampoline
that supports up to 6 32-bit arguments, or up to 2 64-bit arguments:
let floor = ffi('double floor(double)');
print(floor(1.23456));
Function arguments should be simple: only int, double, char *, void *
are supported. Use char * for NUL-terminated C strings, void * for any
other pointers. In order to import more complex functions
(e.g. the ones that use structures as arguments), write wrappers.
Callbacks
Callbacks are implemented similarly. Consider that you have a C function
that takes a callback and user data void * pointer, which should be marked
as userdata in the signature:
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. mJS resolver uses dlsym-compatible signature.
Converting structs to objects
mJS provides a helper to facilitate coversion of C structs to JS objects.
The functions is called s2o and takes two parameters: foreign pointer to
the struct and foreign pointer to the struct's descriptor which specifies
names and offsets of the struct's members. Here's an simple example:
// Assuming `s` is a foreign pointer to an instance of `my_struct`, obtained elsewhere.
let sd = ffi('void *get_my_struct_descr(void)')();
let o = s2o(s, sd);
print(o.a, o.b);
Nested structs are also supported - use MJS_STRUCT_FIELD_TYPE_STRUCT field type
and provide pointer to the definition:
The stand-alone binary uses dlsym() symbol resolver, that's why
ffi("double sin(double)")(1.23) works.
Licensing
mJS is released under commercial and
GNU GPL v.2
open source licenses.
Commercial Projects: once your project becomes commercialised, GPLv2 licensing
dictates that you need to either open your source fully or purchase a
commercial license. Cesanta offer full, royalty-free commercial licenses
without any GPL restrictions. If your needs require a custom license, we’d be
happy to work on a solution with you.
Contact us for pricing
Prototyping: While your project is still in prototyping stage and not for sale,
you can use MJS’s open source code without license restrictions.
See also
Mongoose Web Server Library - a robust, open-source solution licensed under GPLv2, designed to seamlessly integrate web server functionality into your embedded devices.
With complementary Mongoose Wizard - a no-code visual tool that enables rapid WebUI creation without the need for frontend expertise.
Technical guides
Technical atricles and deep dives into embedded networking technologies:
Embedded Web Server: A Comprehensive Guide for Modern Connected Devices
Building Embedded Web Device Dashboards
ESP32 Device Dashboard: A Step-by-Step Guide for Developers
How to build an STM32 Web Dashboard
STM32 WebSocket Guide
Web File Manager on STM32, ESP32 and Embedded Linux
Web dashboard on Zephyr RTOS
Limiting TCP/IP RAM usage on STM32
STM32 Ethernet explained
MQTT on a Microcontroller
STM32 OTA Firmware Update
RP2350 OTA Firmware Update
STM32 Ethernet and caches
NXP RW612 OTA Firmware Update
lwIP vs Mongoose - TCP/IP Stack Integration Benchmark
cesanta/mjs có 2.1k sao GitHub — tải lại trang để xem số mới nhất, hoặc xem trực tiếp github.com/cesanta/mjs. TopGit phản chiếu số sao của GitHub nhưng không cam kết đến từng phút.
cesanta/mjs có những chủ đề gì?
GitHub topics của cesanta/mjs: "embedded", "esp32", "esp8266", "javascript", "js", "mcu". TopGit xếp repo vào nhóm Frontend.
cesanta/mjs còn đang phát triển không?
Commit gần nhất trên cesanta/mjs là 5 tháng trước (theo timestamp GitHub). Repo có 185 fork — một chỉ báo về mức độ quan tâm của cộng đồng.
cesanta/mjs là gì?
cesanta/mjs (cesanta/mjs) là dự án C trên GitHub. Theo mô tả gốc: Embedded JavaScript engine for C/C++
cesanta/mjs so với các dự án Frontend khác thế nào?
cesanta/mjs được TopGit xếp vào nhóm Frontend, với 2.1k sao GitHub và viết bằng C. Xem trang chủ đề Frontend trên TopGit để so sánh với các dự án tương tự theo số sao và mức độ hoạt động.
cesanta/mjs viết bằng ngôn ngữ gì?
cesanta/mjs chủ yếu viết bằng C. Trường "language" của GitHub dựa trên phần lớn byte ở nhánh mặc định.
Vì sao cesanta/mjs được xếp vào nhóm Frontend?
TopGit xếp cesanta/mjs vào nhóm Frontend dựa trên GitHub topics và mô tả của repo (gắn thẻ: "embedded", "esp32", "esp8266"). Việc phân loại dựa trên metadata thật của repo, không phải đoán theo cảm tính biên tập.
Đọc đầy đủ README ở tab phía trên.
mjs có đáng để bạn bỏ thời gian?
ChatGPT, Claude và Perplexity đều đọc được trang này. Hỏi thử xem họ nghĩ gì về mjs.