Copyright 2018-2023 Moddable Tech, Inc.
Revised: August 31, 2023
The XS engine targets embedded platforms built around microcontrollers like the ESP8266 or ESP32. XS also runs on the usual desktop and mobile platforms.
Despite such constraints, and unlike other scripting libraries available on microcontrollers, XS always strives to fully implement the quite extensive ECMAScript Language Specification.
Spare runtime resources
Embedded platforms do not exist alone. You need a computer to develop applications for them. Therefore, you should prepare in advance of execution, at compile time, everything you can in order to spare run-time resources.
At Moddable, we generalized this approach beyond scripts to all kinds of assets. Fonts, movies, pictures, sounds, and textures are always encoded on your computer into the most practical format for the specific hardware target.
It is a common to mischaracterize web applications as static or dynamic based on whether its assets are adapted for a specific target device. Using content negotiation, for example, web applications can be as live as you want while still running optimized modules and assets. In this case, the compile-time is on the server side, the run-time is on the client side, with caches in between.
Prepare the environment
On embedded platforms, the amount of RAM is extremely small, often under 64 KB. The amount of ROM is larger, 512 KB to 4 MB, roughly the same amount of data downloaded for a typical modern web page. An application's native code and data are flashed into ROM.
- Modules your application uses to do something useful, like a user interface framework, a secure network framework, etc.
Constructing built-ins and loading modules creates many classes, functions, and prototype objects. These objects often require more RAM than is present on a modest microcontroller.
The benefits are significant:
- Since almost nothing is ever copied from ROM to RAM, your application runs with a small amount of RAM.
- Since everything is ready in ROM, your application boots instantaneously.
Freeze most objects
The XS linker cannot preload a module with a body that calls a native function that is only available on the microcontroller. Typically there will be only one module like that to start your application.
But what happens when applications want to modify objects that the XS linker prepared in ROM?
The XS engine maintains a a table of aliases which is initially empty. All aliasable objects in ROM have an index in that table. When an application modifies an aliasable object, the aliasable object is cloned into RAM and inserted into the table to override the aliasable object.
Object.freeze. When objects are frozen, the XS linker does not index them as aliasable.
Modules can use
Object.freeze in their body to tell the XS linker which objects do not need to be indexed as aliasable. Calling that for each object is tedious enough, so the XS linker can automatically freeze all class, function and prototype objects, as well as other built-in objects like
In ECMAScript parlance, that is related to a frozen realm.
Strip unused features
Based on the byte code of your modules, the XS linker can strip unused native code from the XS engine itself. So your application will run its own version of the XS engine, tailored to reduce its ROM footprint.
That is automatic for applications that are self-contained and updated as a whole, which is still common on embedded platforms for the sake of consistency, safety, and security.
Function, etc to get rid of the XS parser and byte coder.
Use native code
At Moddable, we use native code only when necessary, for instance to build drivers, or when the memory footprint or performance gains are obvious, for instance in our graphics library and user interface framework.
Since the tool chain always requires compiling and linking native code, there is no overhead in your development cycle.
When its environment is not frozen and when its engine is not stripped, XS passes 99.5% of the tests that are part of the Official ECMAScript Conformance Test Suite. The XS Conformance document describes the results and test procedures.
Here are a few incompatibilities that you should be aware of:
Function: XS does not store the source code of functions so
Function.prototype.toString always fails.
RegExp: By default the Unicode property escapes are not built-in because of the size of the tables they require.
String: Strings are UTF-8 encoded, their length is the number of code points instead of the number of code units they contain and they are indexed by code points instead of code units.
Tagged Template: XS supports tagged templates but does not currently implement the tagged templates cache.
No XS hosts are web browsers, so the Annex B of the ECMAScript Language Specification is not supported. However XS implements
The ECMAScript Internationalization API Specification is separate from the ECMAScript Language Specification and is not supported by XS.