Quickjs
Quickjs
Quickjs
Table of Contents
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Main Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Quick start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.3 Command line options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.3.1 qjs interpreter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.3.2 qjsc compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.4 qjscalc application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.5 Built-in tests. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.6 Test262 (ECMAScript Test Suite) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3 Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1 Language support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.1 ES2023 support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.2 ECMA402 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.3 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.4 Mathematical extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.2 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3 Standard library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3.1 Global objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.3.2 std module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.3.3 os module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.4 QuickJS C API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4.1 Runtime and contexts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.2 JSValue. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.3 C functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.4 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.5 Script evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.6 JS Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4.7 C Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4.8 Memory handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4.9 Execution timeout and interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4 Internals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.1 Bytecode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2 Executable generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2.1 qjsc compiler. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2.2 Binary JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.3 Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.3.1 Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.3.2 Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.3.3 Atoms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.3.4 Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.3.5 Garbage collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.3.6 JSValue. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
ii
5 License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1
1 Introduction
QuickJS is a small and embeddable Javascript engine. It supports most of the ES2023
specification1 including modules, asynchronous generators, proxies and BigInt.
It supports mathematical extensions such as big decimal float float numbers (BigDecimal),
big binary floating point numbers (BigFloat), and operator overloading.
1
https://tc39.es/ecma262/2023
2
https://github.com/tc39/test262
3
https://tc39.es/ecma262/
2
2 Usage
2.1 Installation
A Makefile is provided to compile the engine on Linux or MacOS/X. A preliminary Windows
support is available thru cross compilation on a Linux host with the MingGW tools.
Edit the top of the Makefile if you wish to select specific options then run make.
You can type make install as root if you wish to install the binaries and support files to
/usr/local (this is not necessary to use QuickJS).
Note: On some OSes atomic operations are not available or need a specific library. If you
get related errors, you should either add -latomics in the Makefile LIBS variable or disable
CONFIG_ATOMICS in quickjs.c.
--include file
Include an additional file.
--std Make the std and os modules available to the loaded script even if it is not a module.
-d
--dump Dump the memory usage stats.
-q
--quit just instantiate the interpreter and quit.
1
The old ES5.1 tests can be extracted with git clone --single-branch --branch es5-tests
https://github.com/tc39/test262.git test262o
2
https://github.com/bterlson/test262-harness
5
3 Specifications
3.1.2 ECMA402
ECMA402 (Internationalization API) is not supported.
3.1.3 Extensions
• The directive "use strip" indicates that the debug information (including the source code
of the functions) should not be retained to save memory. As "use strict", the directive
can be global to a script or local to a function.
• The first line of a script beginning with #! is ignored.
3.2 Modules
ES6 modules are fully supported. The default name resolution is the following:
• Module names with a leading . or .. are relative to the current module path.
• Module names without a leading . or .. are system modules, such as std or os.
• Module names ending with .so are native modules using the QuickJS C API.
1
We believe the current specification of tails calls is too complicated and presents limited practical interests.
Chapter 3: Specifications 6
sprintf(fmt, ...args)
Equivalent to the libc sprintf().
in
out
err Wrappers to the libc file stdin, stdout, stderr.
SEEK_SET
SEEK_CUR
SEEK_END Constants for seek().
Error
Enumeration object containing the integer value of common errors (additional error
codes may be defined):
EINVAL
EIO
EACCES
EEXIST
ENOSPC
ENOSYS
EBUSY
ENOENT
EPERM
EPIPE
strerror(errno)
Return a string that describes the error errno.
gc() Manually invoke the cycle removal algorithm. The cycle removal algorithm is auto-
matically started when needed, so this function is useful in case of specific memory
constraints or for testing.
getenv(name)
Return the value of the environment variable name or undefined if it is not defined.
setenv(name, value)
Set the value of the environment variable name to the string value.
unsetenv(name)
Delete the environment variable name.
getenviron()
Return an object containing the environment variables as key-value pairs.
urlGet(url, options = undefined)
Download url using the curl command line utility. options is an optional object
containing the following optional properties:
binary Boolean (default = false). If true, the response is an ArrayBuffer instead
of a string. When a string is returned, the data is assumed to be UTF-8
encoded.
Chapter 3: Specifications 8
full
Boolean (default = false). If true, return the an object contains the
properties response (response content), responseHeaders (headers
separated by CRLF), status (status code). response is null is case of
protocol or network error. If full is false, only the response is returned
if the status is between 200 and 299. Otherwise null is returned.
parseExtJSON(str)
Parse str using a superset of JSON.parse. The following extensions are accepted:
• Single line and multiline comments
• unquoted properties (ASCII-only Javascript identifiers)
• trailing comma in array and object definitions
• single quoted strings
• \f and \v are accepted as space characters
• leading plus in numbers
• octal (0o prefix) and hexadecimal (0x prefix) numbers
FILE prototype:
close() Close the file. Return 0 if OK or -errno in case of I/O error.
puts(str)
Outputs the string with the UTF-8 encoding.
printf(fmt, ...args)
Formatted printf.
The same formats as the standard C library printf are supported. Integer format
types (e.g. %d) truncate the Numbers or BigInts to 32 bits. Use the l modifier (e.g.
%ld) to truncate to 64 bits.
flush() Flush the buffered file.
seek(offset, whence)
Seek to a give file position (whence is std.SEEK_*). offset can be a number or a
bigint. Return 0 if OK or -errno in case of I/O error.
tell() Return the current file position.
tello() Return the current file position as a bigint.
eof() Return true if end of file.
fileno() Return the associated OS handle.
error() Return true if there was an error.
clearerr()
Clear the error indication.
read(buffer, position, length)
Read length bytes from the file to the ArrayBuffer buffer at byte position
position (wrapper to the libc fread).
write(buffer, position, length)
Write length bytes to the file from the ArrayBuffer buffer at byte position
position (wrapper to the libc fwrite).
getline()
Return the next line from the file, assuming UTF-8 encoding, excluding the trailing
line feed.
Chapter 3: Specifications 9
readAsString(max_size = undefined)
Read max_size bytes from the file and return them as a string assuming UTF-8
encoding. If max_size is not present, the file is read up its end.
getByte()
Return the next byte from the file. Return -1 if the end of file is reached.
putByte(c)
Write one byte to the file.
3.3.3 os module
The os module provides Operating System specific functions:
• low level file access
• signals
• timers
• asynchronous I/O
• workers (threads)
The OS functions usually return 0 if OK or an OS specific negative error code.
Available exports:
open(filename, flags, mode = 0o666)
Open a file. Return a handle or < 0 if error.
O_RDONLY
O_WRONLY
O_RDWR
O_APPEND
O_CREAT
O_EXCL
O_TRUNC POSIX open flags.
O_TEXT (Windows specific). Open the file in text mode. The default is binary mode.
close(fd)
Close the file handle fd.
seek(fd, offset, whence)
Seek in the file. Use std.SEEK_* for whence. offset is either a number or a bigint.
If offset is a bigint, a bigint is returned too.
read(fd, buffer, offset, length)
Read length bytes from the file handle fd to the ArrayBuffer buffer at byte posi-
tion offset. Return the number of read bytes or < 0 if error.
write(fd, buffer, offset, length)
Write length bytes to the file handle fd from the ArrayBuffer buffer at byte
position offset. Return the number of written bytes or < 0 if error.
isatty(fd)
Return true is fd is a TTY (terminal) handle.
ttyGetWinSize(fd)
Return the TTY size as [width, height] or null if not available.
Chapter 3: Specifications 10
ttySetRaw(fd)
Set the TTY in raw mode.
remove(filename)
Remove a file. Return 0 if OK or -errno.
rename(oldname, newname)
Rename a file. Return 0 if OK or -errno.
realpath(path)
Return [str, err] where str is the canonicalized absolute pathname of path and
err the error code.
getcwd() Return [str, err] where str is the current working directory and err the error
code.
chdir(path)
Change the current directory. Return 0 if OK or -errno.
mkdir(path, mode = 0o777)
Create a directory at path. Return 0 if OK or -errno.
stat(path)
lstat(path)
Return [obj, err] where obj is an object containing the file status of path. err is
the error code. The following fields are defined in obj: dev, ino, mode, nlink, uid,
gid, rdev, size, blocks, atime, mtime, ctime. The times are specified in milliseconds
since 1970. lstat() is the same as stat() excepts that it returns information about
the link itself.
S_IFMT
S_IFIFO
S_IFCHR
S_IFDIR
S_IFBLK
S_IFREG
S_IFSOCK
S_IFLNK
S_ISGID
S_ISUID Constants to interpret the mode property returned by stat(). They have the same
value as in the C system header sys/stat.h.
utimes(path, atime, mtime)
Change the access and modification times of the file path. The times are specified
in milliseconds since 1970. Return 0 if OK or -errno.
symlink(target, linkpath)
Create a link at linkpath containing the string target. Return 0 if OK or -errno.
readlink(path)
Return [str, err] where str is the link target and err the error code.
readdir(path)
Return [array, err] where array is an array of strings containing the filenames
of the directory path. err is the error code.
Chapter 3: Specifications 11
setReadHandler(fd, func)
Add a read handler to the file handle fd. func is called each time there is data
pending for fd. A single read handler per file handle is supported. Use func = null
to remove the handler.
setWriteHandler(fd, func)
Add a write handler to the file handle fd. func is called each time data can be
written to fd. A single write handler per file handle is supported. Use func = null
to remove the handler.
signal(signal, func)
Call the function func when the signal signal happens. Only a single handler per
signal number is supported. Use null to set the default handler or undefined to
ignore the signal. Signal handlers can only be defined in the main thread.
SIGINT
SIGABRT
SIGFPE
SIGILL
SIGSEGV
SIGTERM POSIX signal numbers.
kill(pid, sig)
Send the signal sig to the process pid.
exec(args[, options])
Execute a process with the arguments args. options is an object containing op-
tional parameters:
block Boolean (default = true). If true, wait until the process is terminated.
In this case, exec return the exit code if positive or the negated signal
number if the process was interrupted by a signal. If false, do not block
and return the process id of the child.
usePath Boolean (default = true). If true, the file is searched in the PATH envi-
ronment variable.
file String (default = args[0]). Set the file to be executed.
cwd String. If present, set the working directory of the new process.
stdin
stdout
stderr If present, set the handle in the child for stdin, stdout or stderr.
env Object. If present, set the process environment from the object key-
value pairs. Otherwise use the same environment as the current process.
uid Integer. If present, the process uid with setuid.
gid Integer. If present, the process gid with setgid.
getpid() Return the current process ID.
waitpid(pid, options)
waitpid Unix system call. Return the array [ret, status]. ret contains -errno
in case of error.
Chapter 3: Specifications 12
3.4.2 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 ref-
erence count) or free (JS_FreeValue(), decrement the reference count) JSValues.
3.4.3 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 JSValues as
parameters (so they don’t need to free them) and return a newly allocated (=live) JSValue.
3.4.4 Exceptions
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().
3.4.6 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 globally allocated (i.e. for all runtimes). 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.
Chapter 3: Specifications 14
3.4.7 C Modules
Native ES6 modules are supported and can be dynamically or statically linked. Look at the
test_bjson and bjson.so examples. The standard library quickjs-libc.c is also a good
example of a native module.
4 Internals
4.1 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.
4.3 Runtime
4.3.1 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.
4.3.2 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.
Chapter 4: Internals 16
4.3.3 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 231 − 1.
4.3.4 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.
4.3.6 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.
4.4 RegExp
A specific regular expression engine was developed. It is both small and efficient and supports
all the ES2023 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.
The full regexp library weights about 15 KiB (x86 code), excluding the Unicode library.
4.5 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 weights about 45 KiB (x86 code).
Chapter 4: Internals 17
1
https://bellard.org/libbf
18
5 License
QuickJS is released under the MIT license.
Unless otherwise specified, the QuickJS sources are copyright Fabrice Bellard and Charlie
Gordon.