Checkpoint before integration and package validation. Assisted-by: SurmAgent:unknown [read] [edit] [bash]
118 lines
3.8 KiB
Markdown
118 lines
3.8 KiB
Markdown
# Internals
|
|
|
|
## Bytecode
|
|
|
|
The compiler generates bytecode directly with no intermediate
|
|
representation such as a parse tree, hence it is very fast. Several
|
|
optimizations passes are done over the generated bytecode.
|
|
|
|
A stack-based bytecode was chosen because it is simple and generates
|
|
compact code.
|
|
|
|
For each function, the maximum stack size is computed at compile time so that
|
|
no runtime stack overflow tests are needed.
|
|
|
|
A separate compressed line number table is maintained for the debug
|
|
information.
|
|
|
|
Access to closure variables is optimized and is almost as fast as local
|
|
variables.
|
|
|
|
Direct `eval` in strict mode is optimized.
|
|
|
|
## Runtime
|
|
|
|
### Strings
|
|
|
|
Strings are stored either as an 8 bit or a 16 bit array of
|
|
characters. Hence random access to characters is always fast.
|
|
|
|
The C API provides functions to convert JavaScript Strings to C UTF-8 encoded
|
|
strings. The most common case where the JavaScript string contains
|
|
only ASCII characters involves no copying.
|
|
|
|
### Objects
|
|
|
|
The object shapes (object prototype, property names and flags) are shared
|
|
between objects to save memory.
|
|
|
|
Arrays with no holes (except at the end of the array) are optimized.
|
|
|
|
TypedArray accesses are optimized.
|
|
|
|
### Atoms
|
|
|
|
Object property names and some strings are stored as Atoms (unique
|
|
strings) to save memory and allow fast comparison. Atoms are
|
|
represented as a 32 bit integer. Half of the atom range is reserved for
|
|
immediate integer literals from 0 to 2^31-1.
|
|
|
|
### Numbers
|
|
|
|
Numbers are represented either as 32-bit signed integers or 64-bit IEEE-754
|
|
floating point values. Most operations have fast paths for the 32-bit
|
|
integer case.
|
|
|
|
### Garbage collection
|
|
|
|
Reference counting is used to free objects automatically and
|
|
deterministically. A separate cycle removal pass is done when the allocated
|
|
memory becomes too large. The cycle removal algorithm only uses the
|
|
reference counts and the object content, so no explicit garbage
|
|
collection roots need to be manipulated in the C code.
|
|
|
|
### JSValue
|
|
|
|
It is a JavaScript value which can be a primitive type (such as
|
|
Number, String, ...) or an Object. NaN boxing is used in the 32-bit version
|
|
to store 64-bit floating point numbers. The representation is
|
|
optimized so that 32-bit integers and reference counted values can be
|
|
efficiently tested.
|
|
|
|
In 64-bit code, JSValue are 128-bit large and no NaN boxing is used. The
|
|
rationale is that in 64-bit code memory usage is less critical.
|
|
|
|
In both cases (32 or 64 bits), JSValue exactly fits two CPU registers,
|
|
so it can be efficiently returned by C functions.
|
|
|
|
### Function call
|
|
|
|
The engine is optimized so that function calls are fast. The system
|
|
stack holds the JavaScript parameters and local variables.
|
|
|
|
### RegExp
|
|
|
|
A specific regular expression engine was developed. It is both small
|
|
and efficient and supports all the ES2020+ features including the
|
|
Unicode properties. As the JavaScript compiler, it directly generates
|
|
bytecode without a parse tree.
|
|
|
|
Backtracking with an explicit stack is used so that there is no
|
|
recursion on the system stack. Simple quantifiers are specifically
|
|
optimized to avoid recursions.
|
|
|
|
Infinite recursions coming from quantifiers with empty terms are
|
|
avoided.
|
|
|
|
The full regexp library weighs about 15 KiB (x86 code), excluding the
|
|
Unicode library.
|
|
|
|
### Unicode
|
|
|
|
A specific Unicode library was developed so that there is no
|
|
dependency on an external large Unicode library such as ICU. All the
|
|
Unicode tables are compressed while keeping a reasonable access
|
|
speed.
|
|
|
|
The library supports case conversion, Unicode normalization, Unicode
|
|
script queries, Unicode general category queries and all Unicode
|
|
binary properties.
|
|
|
|
The full Unicode library weighs about 45 KiB (x86 code).
|
|
|
|
### BigInt
|
|
|
|
BigInt is implemented with the [libbf](https://bellard.org/libbf) library.
|
|
It weights about 90 KiB (x86 code) and provides arbitrary precision IEEE 754 floating
|
|
point operations and transcendental functions with exact rounding.
|