cred: isolate scripts in WASI and move RSA signing to AWS-LC

This commit is contained in:
2026-11-06 22:22:49 +00:00
parent 5b3e1393f5
commit 86c5d8a4e4
217 changed files with 155392 additions and 391 deletions
@@ -0,0 +1,7 @@
{
"label": "Developer Guide",
"position": 6,
"link": {
"type": "generated-index"
}
}
@@ -0,0 +1,3 @@
# API Reference
WIP.
@@ -0,0 +1,117 @@
# 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.
@@ -0,0 +1,113 @@
---
sidebar_position: 1
---
# The QuickJS C API
The C API was designed to be simple and efficient. The C API is
defined in the header `quickjs.h`.
## Runtime and contexts
`JSRuntime` represents a JavaScript runtime corresponding to an
object heap. Several runtimes can exist at the same time but they
cannot exchange objects. Inside a given runtime, no multi-threading is
supported.
`JSContext` represents a JavaScript context (or Realm). Each
JSContext has its own global objects and system objects. There can be
several JSContexts per JSRuntime and they can share objects, similar
to frames of the same origin sharing JavaScript objects in a
web browser.
## JSValue
`JSValue` represents a JavaScript value which can be a primitive
type or an object. Reference counting is used, so it is important to
explicitly duplicate (`JS_DupValue()`, increment the reference
count) or free (`JS_FreeValue()`, decrement the reference count)
JSValues.
## C functions
C functions can be created with
`JS_NewCFunction()`. `JS_SetPropertyFunctionList()` is a
shortcut to easily add functions, setters and getters properties to a
given object.
Unlike other embedded JavaScript engines, there is no implicit stack,
so C functions get their parameters as normal C parameters. As a
general rule, C functions take constant `JSValue`s as parameters
(so they don't need to free them) and return a newly allocated (=live)
`JSValue`.
## Exceptions
Most C functions can return a JavaScript exception. It
must be explicitly tested and handled by the C code. The specific
`JSValue` `JS_EXCEPTION` indicates that an exception
occurred. The actual exception object is stored in the
`JSContext` and can be retrieved with `JS_GetException()`.
## Script evaluation
Use `JS_Eval()` to evaluate a script or module source.
If the script or module was compiled to bytecode with `qjsc`, it
can be evaluated by calling `js_std_eval_binary()`. The advantage
is that no compilation is needed so it is faster and smaller because
the compiler can be removed from the executable if no `eval` is
required.
Note: the bytecode format is linked to a given QuickJS
version. Moreover, no security check is done before its
execution. Hence the bytecode should not be loaded from untrusted
sources.
## JS Classes
C opaque data can be attached to a JavaScript object. The type of the
C opaque data is determined with the class ID (`JSClassID`) of
the object. Hence the first step is to register a new class ID and JS
class (`JS_NewClassID()`, `JS_NewClass()`). Then you can
create objects of this class with `JS_NewObjectClass()` and get or
set the C opaque point with `JS_GetOpaque()` / `JS_SetOpaque()`.
When defining a new JS class, it is possible to declare a finalizer
which is called when the object is destroyed. The finalizer should be
used to release C resources. It is invalid to execute JS code from
it. A `gc_mark` method can be provided so that the cycle removal
algorithm can find the other objects referenced by this object. Other
methods are available to define exotic object behaviors.
The Class ID are allocated per-runtime. The
`JSClass` are allocated per `JSRuntime`. `JS_SetClassProto()`
is used to define a prototype for a given class in a given
`JSContext`. `JS_NewObjectClass()` sets this prototype in the
created object.
Examples are available in `quickjs-libc.c`.
## C Modules
Native ES6 modules are supported and can be dynamically or statically
linked. The standard library `quickjs-libc.c` is a good example
of a native module.
## Memory handling
Use `JS_SetMemoryLimit()` to set a global memory allocation limit
to a given `JSRuntime`.
Custom memory allocation functions can be provided with `JS_NewRuntime2()`.
The maximum system stack size can be set with `JS_SetMaxStackSize()`.
## Execution timeout and interrupts
Use `JS_SetInterruptHandler()` to set a callback which is
regularly called by the engine when it is executing code. This
callback can be used to implement an execution timeout.
It is used by the command line interpreter to implement a
`Ctrl-C` handler.