- MicroQuickJS(MQuickJS) एम्बेडेड सिस्टम्स के लिए डिज़ाइन किया गया एक अति-हल्का JavaScript इंजन है, जो लगभग 10kB RAM और 100kB ROM पर चल सकता है
- QuickJS जैसी गति बनाए रखते हुए मेमोरी उपयोग कम करने के लिए इसमें tracing garbage collector और UTF-8 string storage अपनाया गया है
- समर्थित भाषा ES5 के क़रीब JavaScript का सीमित subset है, और केवल strict mode की अनुमति है, जो त्रुटि-प्रवण syntax को प्रतिबंधित करता है
- REPL टूल
mqjs के ज़रिए script execution, bytecode save करना, और memory limit सेट करना संभव है, तथा बना हुआ bytecode सीधे ROM से चलाया जा सकता है
- पूरा इंजन और standard library ROM में resident रहते हैं, जिससे तेज़ initialization और कम memory consumption हासिल होता है और एम्बेडेड वातावरण में JavaScript execution efficiency बढ़ती है
परिचय
- MicroQuickJS(MQuickJS) एम्बेडेड सिस्टम्स को ध्यान में रखकर बनाया गया JavaScript इंजन है, जो 10kB RAM और 100kB ROM (ARM Thumb-2 code सहित) पर काम करता है
- इसकी गति QuickJS के समान है
- यह केवल ES5 के क़रीब subset को सपोर्ट करता है, और सिर्फ़ strict mode में चलता है, जो अप्रभावी या त्रुटि-प्रवण syntax को प्रतिबंधित करता है
- यह QuickJS के साथ कुछ code साझा करता है, लेकिन इसकी internal structure मेमोरी बचाने के लिए पूरी तरह अलग ढंग से डिज़ाइन की गई है
- इसमें tracing garbage collector, CPU stack का उपयोग न करना, और UTF-8 string storage का उपयोग किया गया है
REPL
- REPL command
mqjs है, जो script execution, evaluation, interactive mode, memory limit setting, और bytecode save करने को सपोर्ट करता है
- उदाहरण:
./mqjs --memory-limit 10k tests/mandelbrot.js
-o option के साथ compiled bytecode को फ़ाइल में सेव किया जा सकता है
- सेव किया गया bytecode
./mqjs mandelbrot.bin से चलाया जा सकता है
- bytecode CPU के endianness और word length (32/64-bit) के अनुसार अलग होता है, और
-m32 option से 32-bit bytecode बनाया जा सकता है
--no-column option से debug information के column number हटाए जा सकते हैं
strict mode
- केवल strict mode की अनुमति है;
with keyword का उपयोग नहीं किया जा सकता, और global variables को अनिवार्य रूप से var से declare करना होगा
- array holes की अनुमति नहीं है
- उदाहरण:
a[10] = 2 पर TypeError होगा
- यदि holes वाला array चाहिए, तो सामान्य object का उपयोग करें
- केवल global eval समर्थित है; local variables तक पहुँच नहीं है
- value boxing समर्थित नहीं है (
new Number(1) आदि)
JavaScript subset
- strict mode आधारित, ES5 compatibility पर केंद्रित
- Array object में holes नहीं होते, और range के बाहर index access करने पर error होता है
for in object की own properties पर ही iterate करता है, और for of केवल arrays को सपोर्ट करता है
- global object मौजूद है, लेकिन getter/setter की अनुमति नहीं है, और सीधे बनाई गई properties global variables के रूप में expose नहीं होतीं
- regular expressions (Regexp) में uppercase/lowercase matching केवल ASCII तक सीमित है, और
/./ UTF-16 के बजाय Unicode code points के आधार पर match करता है
- string functions केवल ASCII को संभालते हैं (
toLowerCase, toUpperCase)
- Date में केवल
Date.now() समर्थित है
- अतिरिक्त समर्थित सुविधाएँ:
for of, Typed arrays, \u{hex} string literals
- Math functions:
imul, clz32, fround, trunc, log2, log10
- exponentiation operator, regexp flags (s, y, u), string functions (
replaceAll, trimStart, trimEnd), globalThis
C API
- C library dependencies न्यूनतम रखी गई हैं;
malloc, free, printf का उपयोग नहीं होता
- memory buffer सीधे प्रदान करना होता है, और इंजन उसी buffer के भीतर memory allocate करता है
- उदाहरण:
ctx = JS_NewContext(mem_buf, sizeof(mem_buf), &js_stdlib)
- garbage collection method के कारण
JS_FreeValue() कॉल करने की आवश्यकता नहीं है
- object address हर allocation पर बदल सकता है, इसलिए
JSValue pointer का उपयोग करने की सिफ़ारिश की जाती है
JS_PushGCRef() / JS_PopGCRef() से सुरक्षित reference management संभव है
- standard library को ऐसे C structures के रूप में compile किया जाता है जिन्हें ROM में रखा जा सकता है, जिससे तेज़ initialization और कम RAM usage मिलता है
- bytecode execution ROM से संभव है, और
JS_RelocateBytecode() से relocate करने के बाद JS_LoadBytecode() और JS_Run() से चलाया जा सकता है
- math library (libm.c) और floating-point emulator अंतर्निहित हैं
आंतरिक संरचना और QuickJS से तुलना
- garbage collection: reference counting के बजाय tracing और compaction GC का उपयोग
- इससे memory fragmentation रुकती है और object size कम होता है
- value representation: CPU word size (32/64-bit) के अनुरूप डिज़ाइन
- इसमें 31-bit integers, Unicode code points, floating point values, और memory block pointers स्टोर किए जा सकते हैं
- strings UTF-8 में store की जाती हैं, जो QuickJS की 8/16-bit array approach से अधिक efficient है
- C functions को single value के रूप में store किया जा सकता है, लेकिन उनमें properties जोड़ी नहीं जा सकतीं
- standard library ROM में resident रहती है, और RAM objects को न्यूनतम रखकर तेज़ engine initialization संभव बनाती है
- bytecode stack-based है और indirect reference table के माध्यम से read-only बनाया जाता है
- Golomb code से line और column numbers compress किए जाते हैं
- compiler QuickJS जैसा है, लेकिन C stack usage सीमित रखने के लिए non-recursive parser का उपयोग करता है
- parse tree के बिना single-pass bytecode generation
टेस्ट और बेंचमार्क
- बेसिक टेस्ट:
make test
- QuickJS micro benchmark:
make microbench
- Octane benchmark (strict mode के लिए संशोधित संस्करण) अलग से डाउनलोड किया जा सकता है
- चलाने के लिए:
make octane
लाइसेंस
- MIT लाइसेंस के तहत वितरित
- source code का copyright Fabrice Bellard और Charlie Gordon के पास है
अभी कोई टिप्पणी नहीं है.