2022-08-08 06:59:57 +00:00
|
|
|
---
|
|
|
|
title: JavaScript Engines
|
2023-02-28 11:40:44 +00:00
|
|
|
pagination_prev: demos/bigdata/index
|
|
|
|
pagination_next: solutions/input
|
2022-08-08 06:59:57 +00:00
|
|
|
---
|
|
|
|
|
|
|
|
import current from '/version.js';
|
|
|
|
import Tabs from '@theme/Tabs';
|
|
|
|
import TabItem from '@theme/TabItem';
|
2023-09-22 06:32:55 +00:00
|
|
|
import CodeBlock from '@theme/CodeBlock';
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
Browser vendors and other organizations have built "JavaScript engines". They
|
|
|
|
are independent software libraries that are capable of running JS scripts.
|
|
|
|
|
2022-08-08 06:59:57 +00:00
|
|
|
The most popular JavaScript engine is V8. Designed for embedding in software,
|
2022-08-25 08:22:28 +00:00
|
|
|
it powers Chrome, NodeJS, UXP, Deno and many other platforms.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2022-08-25 08:22:28 +00:00
|
|
|
There are many other JS engines with different design goals. Some are designed
|
2022-08-08 06:59:57 +00:00
|
|
|
for low-power or low-memory environments. Others aim for interoperability with
|
2022-08-25 08:22:28 +00:00
|
|
|
specific programming languages or environments. Typically they support ES3 and
|
|
|
|
are capable of running SheetJS code.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
This demo showcases a number of JS engines and language bindings.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
|
|
|
## General Caveats
|
|
|
|
|
|
|
|
Common browser and NodeJS APIs are often missing from light-weight JS engines.
|
|
|
|
|
|
|
|
**Global**
|
|
|
|
|
|
|
|
Some engines do not provide `globalThis` or `global` or `window`. A `global`
|
|
|
|
variable can be exposed in one line that should be run in the JS engine:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var global = (function(){ return this; }).call(null);
|
|
|
|
```
|
|
|
|
|
|
|
|
**Console**
|
|
|
|
|
|
|
|
Some engines do not provide a `console` object. `console.log` can be shimmed
|
2023-08-03 02:49:32 +00:00
|
|
|
using the engine functionality. For example, `hermes`[^1] provides `print()`:
|
2022-08-08 06:59:57 +00:00
|
|
|
|
|
|
|
```js
|
|
|
|
var console = { log: function(x) { print(x); } };
|
|
|
|
```
|
|
|
|
|
|
|
|
**Binary Data**
|
|
|
|
|
2022-08-25 08:22:28 +00:00
|
|
|
Some engines do not provide easy ways to exchange binary data. For example, it
|
|
|
|
is common to pass null-terminated arrays, which would truncate XLSX, XLS, and
|
|
|
|
other exports. APIs that accept pointers without length should be avoided.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
|
|
|
Base64 strings are safe for passing between JS and native code, but they should
|
|
|
|
only be used when there is no safe way to pass `ArrayBuffer` or `Uint8Array`.
|
|
|
|
|
2023-05-22 08:06:09 +00:00
|
|
|
**Byte Conventions**
|
|
|
|
|
2023-09-28 17:13:57 +00:00
|
|
|
Java has no native concept of unsigned bytes. Values in a `byte[]` are limited
|
2023-05-22 08:06:09 +00:00
|
|
|
to the range `-128 .. 127`. They need to be fixed within the JS engine.
|
|
|
|
|
|
|
|
Some engines support typed arrays. The `Uint8Array` constructor will fix values:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var signed_data = [-48, -49, 17, -32, /* ... */]; // 0xD0 0xCF 0x11 0xE0 ...
|
|
|
|
var fixed_data = new Uint8Array(signed_data);
|
|
|
|
```
|
|
|
|
|
|
|
|
When `Uint8Array` is not supported, values can be fixed with bitwise operations:
|
|
|
|
|
|
|
|
```js
|
|
|
|
var signed_data = [-48, -49, 17, -32, /* ... */]; // 0xD0 0xCF 0x11 0xE0 ...
|
|
|
|
var fixed_data = new Array(signed_data.length);
|
|
|
|
for(var i = 0; i < signed_data.length; ++i) fixed_data[i] = signed_data[i] & 0xFF;
|
|
|
|
```
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
## Engines
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
This list is sorted in alphabetical order.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-05-22 08:06:09 +00:00
|
|
|
### Boa
|
|
|
|
|
|
|
|
Boa is an embeddable JS engine written in Rust.
|
|
|
|
|
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/boa).
|
|
|
|
|
2023-04-09 06:58:43 +00:00
|
|
|
### ChakraCore
|
|
|
|
|
|
|
|
ChakraCore is an embeddable JS engine written in C++.
|
|
|
|
|
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/chakra).
|
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
### Duktape
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
Duktape is an embeddable JS engine written in C. It has been ported to a number
|
|
|
|
of exotic architectures and operating systems.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/duktape).
|
2023-02-13 09:20:49 +00:00
|
|
|
The demo includes examples in C and Perl.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
### Goja
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-14 06:54:02 +00:00
|
|
|
Goja is a pure Go implementation of ECMAScript 5.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-14 06:54:02 +00:00
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/goja).
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
### Hermes
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-05-30 06:41:09 +00:00
|
|
|
Hermes is an embeddable JS engine written in C++.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-05-30 06:41:09 +00:00
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/hermes).
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
### JavaScriptCore
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2022-08-23 03:20:02 +00:00
|
|
|
iOS and MacOS ship with the JavaScriptCore framework for running JS code from
|
2023-02-13 04:07:25 +00:00
|
|
|
Swift and Objective-C.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/jsc).
|
2022-08-08 06:59:57 +00:00
|
|
|
|
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
### JerryScript
|
2022-08-18 08:41:34 +00:00
|
|
|
|
|
|
|
JerryScript is a lightweight JavaScript engine designed for use in low-memory
|
|
|
|
environments like microcontrollers. As part of the build suite, the project
|
|
|
|
generates a C library and a standalone CLI tool.
|
|
|
|
|
|
|
|
The simplest way to interact with the engine is to pass Base64 strings.
|
|
|
|
|
2023-09-24 03:59:48 +00:00
|
|
|
:::note pass
|
|
|
|
|
|
|
|
This demo was tested in the following deployments:
|
|
|
|
|
|
|
|
| Architecture | Commit | Date |
|
|
|
|
|:-------------|:----------|:-----------|
|
|
|
|
| `darwin-x64` | `a588e49` | 2023-09-22 |
|
|
|
|
| `linux-x64` | `a588e49` | 2023-09-22 |
|
|
|
|
|
|
|
|
:::note pass
|
2022-08-18 08:41:34 +00:00
|
|
|
|
|
|
|
While applications should link against the official libraries, the standalone tool
|
|
|
|
is useful for verifying functionality.
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
2023-09-24 03:59:48 +00:00
|
|
|
:::caution pass
|
2022-08-18 08:41:34 +00:00
|
|
|
|
|
|
|
This demo requires a much larger heap size than is normally used in JerryScript
|
|
|
|
deployments! In local testing, the following sizes were needed:
|
|
|
|
|
|
|
|
- 8192 (8M) for <https://sheetjs.com/pres.xlsx>
|
|
|
|
- 65536 (64M) for <https://sheetjs.com/pres.numbers>
|
|
|
|
|
|
|
|
This works on a Raspberry Pi.
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
<details><summary><b>Complete Example</b> (click to show)</summary>
|
|
|
|
|
|
|
|
Due to limitations of the standalone binary, this demo will encode a test file
|
|
|
|
as a Base64 string and directly add it to an amalgamated script.
|
|
|
|
|
|
|
|
0) Build the library and command line tool with required options:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
git clone --depth=1 https://github.com/jerryscript-project/jerryscript.git
|
|
|
|
cd jerryscript
|
|
|
|
python tools/build.py --error-messages=ON --logging=ON --mem-heap=8192 --cpointer-32bit=ON
|
|
|
|
```
|
|
|
|
|
2023-09-22 06:32:55 +00:00
|
|
|
1) Download the SheetJS Standalone script, shim script and test file. Move all
|
|
|
|
three files to the `jerryscript` cloned repo directory:
|
2022-08-18 08:41:34 +00:00
|
|
|
|
|
|
|
<ul>
|
2023-04-27 09:12:19 +00:00
|
|
|
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
|
|
|
|
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
|
2022-08-18 08:41:34 +00:00
|
|
|
<li><a href="https://sheetjs.com/pres.xlsx">pres.xlsx</a></li>
|
|
|
|
</ul>
|
|
|
|
|
2023-09-22 06:32:55 +00:00
|
|
|
<CodeBlock language="bash">{`\
|
|
|
|
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
|
|
|
|
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
|
|
|
curl -LO https://sheetjs.com/pres.xlsx`}
|
|
|
|
</CodeBlock>
|
|
|
|
|
2022-08-18 08:41:34 +00:00
|
|
|
2) Bundle the test file and create `payload.js`:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
node -e "fs.writeFileSync('payload.js', 'var payload = \"' + fs.readFileSync('pres.xlsx').toString('base64') + '\";')"
|
|
|
|
```
|
|
|
|
|
|
|
|
3) Create support scripts:
|
|
|
|
|
|
|
|
- `global.js` creates a `global` variable and defines a fake `console`:
|
|
|
|
|
|
|
|
```js title="global.js"
|
|
|
|
var global = (function(){ return this; }).call(null);
|
|
|
|
var console = { log: function(x) { print(x); } };
|
|
|
|
```
|
|
|
|
|
|
|
|
- `jerry.js` will call `XLSX.read` and `XLSX.utils.sheet_to_csv`:
|
|
|
|
|
|
|
|
```js title="jerry.js"
|
2022-10-20 18:47:20 +00:00
|
|
|
/* sheetjs (C) 2013-present SheetJS -- https://sheetjs.com */
|
2022-08-18 08:41:34 +00:00
|
|
|
var wb = XLSX.read(payload, {type:'base64'});
|
|
|
|
console.log(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
|
|
|
|
```
|
|
|
|
|
|
|
|
4) Create the amalgamation `xlsx.jerry.js`:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
cat global.js xlsx.full.min.js payload.js jerry.js > xlsx.jerry.js
|
|
|
|
```
|
|
|
|
|
|
|
|
The final script defines `global` before loading the standalone library. Once
|
2022-08-25 08:22:28 +00:00
|
|
|
ready, it will read the bundled test data and print the contents as CSV.
|
2022-08-18 08:41:34 +00:00
|
|
|
|
|
|
|
5) Run the script using the `jerry` standalone binary:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
build/bin/jerry xlsx.jerry.js; echo $?
|
|
|
|
```
|
|
|
|
|
|
|
|
</details>
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-09-17 04:57:06 +00:00
|
|
|
### Jint
|
|
|
|
|
|
|
|
Jint is an embeddable JS engine for .NET written in C#.
|
|
|
|
|
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/jint).
|
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
|
2023-03-28 04:57:47 +00:00
|
|
|
### Nashorn
|
|
|
|
|
|
|
|
Nashorn shipped with some versions of Java. It is now a standalone library.
|
|
|
|
|
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/nashorn).
|
|
|
|
|
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
### QuickJS
|
2022-08-08 06:59:57 +00:00
|
|
|
|
|
|
|
QuickJS is an embeddable JS engine written in C. It provides a separate set of
|
|
|
|
functions for interacting with the filesystem and the global object. It can run
|
|
|
|
the standalone browser scripts.
|
|
|
|
|
2023-03-12 06:25:57 +00:00
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/quickjs).
|
2022-08-08 06:59:57 +00:00
|
|
|
|
|
|
|
|
2023-02-13 04:07:25 +00:00
|
|
|
### Rhino
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-15 01:00:49 +00:00
|
|
|
Rhino is an ES3+ engine in Java.
|
2022-08-08 06:59:57 +00:00
|
|
|
|
2023-02-15 01:00:49 +00:00
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/rhino).
|
2023-05-22 08:06:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
### V8
|
|
|
|
|
|
|
|
V8 is an embeddable JS engine written in C++. It powers Chromium and Chrome,
|
|
|
|
NodeJS and Deno, Adobe UXP and other platforms.
|
|
|
|
|
|
|
|
This demo has been moved [to a dedicated page](/docs/demos/engines/v8).
|
|
|
|
The demo includes examples in C++ and Rust.
|
2023-08-03 02:49:32 +00:00
|
|
|
|
|
|
|
The ["Python + Pandas" demo](/docs/demos/engines/pandas) uses V8 with Python.
|
|
|
|
|
|
|
|
[^1]: See ["Initialize Hermes"](/docs/demos/engines/hermes#initialize-hermes) in the Hermes demo.
|