DOCUMENTATION XS Handle
Overview
Getting Started
BASE
Reference
Worker
Setup modules
COMMODETTO
Reference
Poco Renderer
Outlines
Creating Fonts
Crypt
Data
DEVICES
Moddable One
Moddable Two
Moddable Three
Moddable Four
ESP32
ESP8266
nRF52
nRF52 Low Power Notes
Raspberry Pi Pico
M5Core Ink
M5Paper
Wasm
SiLabs Gecko
QCA4020
Moddable Zero
DISPLAYS
Overview
Adafruit 1.8" ST7735
Adafruit OLED Display
BuyDisplay 2.8" CTP - ESP8266
Crystalfontz ePaper
DotStar
Generic 1.44"
Generic 2.4" & 2.8" (Resistive Touch) - ESP32
Generic 2.4" & 2.8" (Resistive Touch) - ESP8266
Generic 2.4" & 2.8" (Resistive Touch) - Pico
Sharp Memory
Sharp Memory Screen 1.3"
SparkFun TeensyView
Switch Science Reflective LCD
DRIVERS
DESTM32S display
DotStar display
ILI9341 display
LPM013M126A display
LS013B4DN04 display
MCP230XX GPIO expander
NeoStrand
SSD1306 display
SSD1351 display
ST7735 display
Files
IO
TC53 IO
Firmata
NETWORK
Reference
TLS (SecureSocket)
BLE
Ethernet
Web Things
PINS
Reference
Audio Output
PIU
Reference
Localization
Keyboard
Expanding Keyboard
Die Cut
Using After Effects Motion Data
TOOLS
Reference
Manifest
Defines in Manifests
Testing
XS
Handle
JavaScript language considerations on embedded devices using the XS engine
Mods – User Installed Extensions
ROM Colors
Using XS Preload to Optimize Applications
XS Conformance
XS Marshalling
XS Platforms
XS in C
XS linker warnings
xsbug
xst
XS Compartment
XS Profiler

Handle

Copyright 2016-17 Moddable Tech, Inc.
Revised: May 17, 2017

Objective

To develop frameworks for microcontrollers with XS, the most significant constraint is RAM.

The XS linker prepares most classes, prototypes, functions and byte codes to be accessed straightly from ROM. All the ECMAScript 2017 features, and most modules composing the frameworks are there, instantaneously available and requiring just a few KB of RAM.

For everything that is created at runtime, applications rely on the XS garbage collector to manage memory. XS divides memory into two zones: the slots and the chunks.

Slots have a fixed size (16 bytes on a 32-bit processor) and cannot move. Chunks have a variable size and can move. The XS garbage collector can compact chunks when necessary, which is a life saver for processors without an MMU.

Slots are used for anything that fits: booleans, dates, instances, numbers, properties, references, symbols, etc. Chunks are used for everything else: byte codes, arrays, strings, etc.

In practice, the slot and chunk heaps works so well for reducing peak memory use that it is tempting to use JavaScript for everything. But, for critical operations, like the layout and the update of the screen, there is a second constraint: performance.

Accessing properties to get and set their values, to call functions, etc., can have significant performance overhead when it is happening at every frame (30 or 60 fps). Even in the world of web browsers, where JavaScript engines sacrifice MB of RAM to optimize such dispatching and the layout and update of the screen are implemented in C or C++.

XS handles allow C based objects implementations to access properties and to dispatch functions with native performance, while using the memory managed by XS, i.e. slots and chunks.

Definition

As in the early days of macOS a handle is a pointer to a pointer to a memory block. A handle allows the system to move memory blocks to coalesce free space. Applications store the handle, instead of address of the pointer block, and deference the handle to access memory blocks. The value of the handle never changes, but the address of the memory block may.

In XS, it is similar: a handle is a pointer to a pointer to a chunk. Here is a schema:

The HANDLE is a pointer to the DATA part of a HOST slot. The DATA part of a HOST slot is a pointer to a chunk. Since slots do not move, a handle remains valid across garbage collections. The XS garbage collector updates the DATA part of a HOST slot when sweeping chunks.

C based objects are chunks. They can contain anything, for instance colors, coordinates, dimensions, etc. Notice that for such values, C based objects are also saving memory since they can pack several values into one chunk instead of using one slot for each value. The memory savings by applying this approach can be considerable as a JavaScript property requires a slot (16 bytes on a typical MCU) which is larger than a native boolean (1 byte), integer (2 or 4 bytes), or even a floating point double (8 bytes).

From JavaScript, C based objects are just host objects and are accessed thru the INSTANCE slot like any host objects. Thru the PROTOTYPE part of the INSTANCE slot, frameworks provides getters, setters and methods so applications can access and manipulate values as usual.

Implementation

C based objects reference other C based object thru handles, i.e. a chunk can contain a handle to another chunk. For instance a content accesses its container with

(*content)->container

That is essential for to achieve maximum performance. For instance, the layout hierarchy is traversed a lot when animating a screen at 30 fps.

What happens when XS collects garbage if a handle inside a chunk is the only reference to a C based object?

By convention, at the beginning of each chunk corresponding to a C based object there is a pointer that is a REFERENCE to the INSTANCE slot.

C based objects implement host HOOKS, which are XS garbage collector callbacks. It is the responsibility of the C based object to use such callbacks to mark its references

xsMarkSlot(the, (*((*content)->container))->reference);

Example

Please look at the Piu sources, which implement part of the KinomaJS programming interface on microcontrollers using the Commodetto graphics library.