• 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 के पास है

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.