Cory McWilliams
2b7077ca70
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4765 ed5197a5-7fde-0310-b194-c3ffbd925b24
1121 lines
34 KiB
Plaintext
1121 lines
34 KiB
Plaintext
\input texinfo
|
|
|
|
@iftex
|
|
@afourpaper
|
|
@headings double
|
|
@end iftex
|
|
|
|
@titlepage
|
|
@afourpaper
|
|
@sp 7
|
|
@center @titlefont{QuickJS Javascript Engine}
|
|
@sp 3
|
|
@end titlepage
|
|
|
|
@setfilename spec.info
|
|
@settitle QuickJS Javascript Engine
|
|
|
|
@contents
|
|
|
|
@chapter Introduction
|
|
|
|
QuickJS is a small and embeddable Javascript engine. It supports most of the
|
|
ES2023 specification
|
|
@footnote{@url{https://tc39.es/ecma262/2023 }}
|
|
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.
|
|
|
|
@section Main Features
|
|
|
|
@itemize
|
|
|
|
@item Small and easily embeddable: just a few C files, no external dependency, 210 KiB of x86 code for a simple ``hello world'' program.
|
|
|
|
@item Fast interpreter with very low startup time: runs the 77000 tests of the ECMAScript Test Suite@footnote{@url{https://github.com/tc39/test262}} in less than 2 minutes on a single core of a desktop PC. The complete life cycle of a runtime instance completes in less than 300 microseconds.
|
|
|
|
@item Almost complete ES2023 support including modules, asynchronous
|
|
generators and full Annex B support (legacy web compatibility). Some
|
|
features from the upcoming ES2024 specification
|
|
@footnote{@url{https://tc39.es/ecma262/}} are also supported.
|
|
|
|
@item Passes nearly 100% of the ECMAScript Test Suite tests when selecting the ES2023 features.
|
|
|
|
@item Compile Javascript sources to executables with no external dependency.
|
|
|
|
@item Garbage collection using reference counting (to reduce memory usage and have deterministic behavior) with cycle removal.
|
|
|
|
@item Mathematical extensions: BigDecimal, BigFloat, operator overloading, bigint mode, math mode.
|
|
|
|
@item Command line interpreter with contextual colorization and completion implemented in Javascript.
|
|
|
|
@item Small built-in standard library with C library wrappers.
|
|
|
|
@end itemize
|
|
|
|
@chapter Usage
|
|
|
|
@section 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 @code{Makefile} if you wish to select specific
|
|
options then run @code{make}.
|
|
|
|
You can type @code{make install} as root if you wish to install the binaries and support files to
|
|
@code{/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
|
|
@code{-latomics} in the Makefile @code{LIBS} variable or disable
|
|
@code{CONFIG_ATOMICS} in @file{quickjs.c}.
|
|
|
|
@section Quick start
|
|
|
|
@code{qjs} is the command line interpreter (Read-Eval-Print Loop). You can pass
|
|
Javascript files and/or expressions as arguments to execute them:
|
|
|
|
@example
|
|
./qjs examples/hello.js
|
|
@end example
|
|
|
|
@code{qjsc} is the command line compiler:
|
|
|
|
@example
|
|
./qjsc -o hello examples/hello.js
|
|
./hello
|
|
@end example
|
|
|
|
generates a @code{hello} executable with no external dependency.
|
|
|
|
@section Command line options
|
|
|
|
@subsection @code{qjs} interpreter
|
|
|
|
@verbatim
|
|
usage: qjs [options] [file [args]]
|
|
@end verbatim
|
|
|
|
Options are:
|
|
@table @code
|
|
@item -h
|
|
@item --help
|
|
List options.
|
|
|
|
@item -e @code{EXPR}
|
|
@item --eval @code{EXPR}
|
|
Evaluate EXPR.
|
|
|
|
@item -i
|
|
@item --interactive
|
|
Go to interactive mode (it is not the default when files are provided on the command line).
|
|
|
|
@item -m
|
|
@item --module
|
|
Load as ES6 module (default=autodetect). A module is autodetected if
|
|
the filename extension is @code{.mjs} or if the first keyword of the
|
|
source is @code{import}.
|
|
|
|
@item --script
|
|
Load as ES6 script (default=autodetect).
|
|
|
|
@item --bignum
|
|
Enable the bignum extensions: BigDecimal object, BigFloat object and
|
|
the @code{"use math"} directive.
|
|
|
|
@item -I file
|
|
@item --include file
|
|
Include an additional file.
|
|
|
|
@end table
|
|
|
|
Advanced options are:
|
|
|
|
@table @code
|
|
@item --std
|
|
Make the @code{std} and @code{os} modules available to the loaded
|
|
script even if it is not a module.
|
|
|
|
@item -d
|
|
@item --dump
|
|
Dump the memory usage stats.
|
|
|
|
@item -q
|
|
@item --quit
|
|
just instantiate the interpreter and quit.
|
|
|
|
@end table
|
|
|
|
@subsection @code{qjsc} compiler
|
|
|
|
@verbatim
|
|
usage: qjsc [options] [files]
|
|
@end verbatim
|
|
|
|
Options are:
|
|
@table @code
|
|
@item -c
|
|
Only output bytecode in a C file. The default is to output an executable file.
|
|
@item -e
|
|
Output @code{main()} and bytecode in a C file. The default is to output an
|
|
executable file.
|
|
@item -o output
|
|
Set the output filename (default = @file{out.c} or @file{a.out}).
|
|
|
|
@item -N cname
|
|
Set the C name of the generated data.
|
|
|
|
@item -m
|
|
Compile as Javascript module (default=autodetect).
|
|
|
|
@item -D module_name
|
|
Compile a dynamically loaded module and its dependencies. This option
|
|
is needed when your code uses the @code{import} keyword or the
|
|
@code{os.Worker} constructor because the compiler cannot statically
|
|
find the name of the dynamically loaded modules.
|
|
|
|
@item -M module_name[,cname]
|
|
Add initialization code for an external C module. See the
|
|
@code{c_module} example.
|
|
|
|
@item -x
|
|
Byte swapped output (only used for cross compilation).
|
|
|
|
@item -flto
|
|
Use link time optimization. The compilation is slower but the
|
|
executable is smaller and faster. This option is automatically set
|
|
when the @code{-fno-x} options are used.
|
|
|
|
@item -fno-[eval|string-normalize|regexp|json|proxy|map|typedarray|promise|bigint]
|
|
Disable selected language features to produce a smaller executable file.
|
|
|
|
@item -fbignum
|
|
Enable the bignum extensions: BigDecimal object, BigFloat object and
|
|
the @code{"use math"} directive.
|
|
|
|
@end table
|
|
|
|
@section @code{qjscalc} application
|
|
|
|
The @code{qjscalc} application is a superset of the @code{qjs}
|
|
command line interpreter implementing a Javascript calculator with
|
|
arbitrarily large integer and floating point numbers, fractions,
|
|
complex numbers, polynomials and matrices. The source code is in
|
|
@file{qjscalc.js}. More documentation and a web version are available at
|
|
@url{http://numcalc.com}.
|
|
|
|
@section Built-in tests
|
|
|
|
Run @code{make test} to run the few built-in tests included in the
|
|
QuickJS archive.
|
|
|
|
@section Test262 (ECMAScript Test Suite)
|
|
|
|
A test262 runner is included in the QuickJS archive. The test262 tests
|
|
can be installed in the QuickJS source directory with:
|
|
|
|
@example
|
|
git clone https://github.com/tc39/test262.git test262
|
|
cd test262
|
|
patch -p1 < ../tests/test262.patch
|
|
cd ..
|
|
@end example
|
|
|
|
The patch adds the implementation specific @code{harness} functions
|
|
and optimizes the inefficient RegExp character classes and Unicode
|
|
property escapes tests (the tests themselves are not modified, only a
|
|
slow string initialization function is optimized).
|
|
|
|
The tests can be run with
|
|
@example
|
|
make test2
|
|
@end example
|
|
|
|
The configuration files @code{test262.conf}
|
|
(resp. @code{test262o.conf} for the old ES5.1 tests@footnote{The old
|
|
ES5.1 tests can be extracted with @code{git clone --single-branch
|
|
--branch es5-tests https://github.com/tc39/test262.git test262o}}))
|
|
contain the options to run the various tests. Tests can be excluded
|
|
based on features or filename.
|
|
|
|
The file @code{test262_errors.txt} contains the current list of
|
|
errors. The runner displays a message when a new error appears or when
|
|
an existing error is corrected or modified. Use the @code{-u} option
|
|
to update the current list of errors (or @code{make test2-update}).
|
|
|
|
The file @code{test262_report.txt} contains the logs of all the
|
|
tests. It is useful to have a clearer analysis of a particular
|
|
error. In case of crash, the last line corresponds to the failing
|
|
test.
|
|
|
|
Use the syntax @code{./run-test262 -c test262.conf -f filename.js} to
|
|
run a single test. Use the syntax @code{./run-test262 -c test262.conf
|
|
N} to start testing at test number @code{N}.
|
|
|
|
For more information, run @code{./run-test262} to see the command line
|
|
options of the test262 runner.
|
|
|
|
@code{run-test262} accepts the @code{-N} option to be invoked from
|
|
@code{test262-harness}@footnote{@url{https://github.com/bterlson/test262-harness}}
|
|
thru @code{eshost}. Unless you want to compare QuickJS with other
|
|
engines under the same conditions, we do not recommend to run the
|
|
tests this way as it is much slower (typically half an hour instead of
|
|
about 100 seconds).
|
|
|
|
@chapter Specifications
|
|
|
|
@section Language support
|
|
|
|
@subsection ES2023 support
|
|
|
|
The ES2023 specification is almost fully supported including the Annex
|
|
B (legacy web compatibility) and the Unicode related features.
|
|
|
|
The following features are not supported yet:
|
|
|
|
@itemize
|
|
|
|
@item Tail calls@footnote{We believe the current specification of tails calls is too complicated and presents limited practical interests.}
|
|
|
|
@item WeakRef and FinalizationRegistry objects
|
|
|
|
@item Symbols as WeakMap keys
|
|
|
|
@end itemize
|
|
|
|
@subsection ECMA402
|
|
|
|
ECMA402 (Internationalization API) is not supported.
|
|
|
|
@subsection Extensions
|
|
|
|
@itemize
|
|
|
|
@item The directive @code{"use strip"} indicates that the debug information (including the source code of the functions) should not be retained to save memory. As @code{"use strict"}, the directive can be global to a script or local to a function.
|
|
|
|
@item The first line of a script beginning with @code{#!} is ignored.
|
|
|
|
@end itemize
|
|
|
|
@subsection Mathematical extensions
|
|
|
|
The mathematical extensions are fully backward compatible with
|
|
standard Javascript. See @code{jsbignum.pdf} for more information.
|
|
|
|
@itemize
|
|
|
|
@item @code{BigDecimal} support: arbitrary large floating point numbers in base 10.
|
|
|
|
@item @code{BigFloat} support: arbitrary large floating point numbers in base 2.
|
|
|
|
@item Operator overloading.
|
|
|
|
@item The directive @code{"use bigint"} enables the bigint mode where integers are @code{BigInt} by default.
|
|
|
|
@item The directive @code{"use math"} enables the math mode where the division and power operators on integers produce fractions. Floating point literals are @code{BigFloat} by default and integers are @code{BigInt} by default.
|
|
|
|
@end itemize
|
|
|
|
@section Modules
|
|
|
|
ES6 modules are fully supported. The default name resolution is the
|
|
following:
|
|
|
|
@itemize
|
|
|
|
@item Module names with a leading @code{.} or @code{..} are relative
|
|
to the current module path.
|
|
|
|
@item Module names without a leading @code{.} or @code{..} are system
|
|
modules, such as @code{std} or @code{os}.
|
|
|
|
@item Module names ending with @code{.so} are native modules using the
|
|
QuickJS C API.
|
|
|
|
@end itemize
|
|
|
|
@section Standard library
|
|
|
|
The standard library is included by default in the command line
|
|
interpreter. It contains the two modules @code{std} and @code{os} and
|
|
a few global objects.
|
|
|
|
@subsection Global objects
|
|
|
|
@table @code
|
|
@item scriptArgs
|
|
Provides the command line arguments. The first argument is the script name.
|
|
@item print(...args)
|
|
Print the arguments separated by spaces and a trailing newline.
|
|
@item console.log(...args)
|
|
Same as print().
|
|
|
|
@end table
|
|
|
|
@subsection @code{std} module
|
|
|
|
The @code{std} module provides wrappers to the libc @file{stdlib.h}
|
|
and @file{stdio.h} and a few other utilities.
|
|
|
|
Available exports:
|
|
|
|
@table @code
|
|
|
|
@item exit(n)
|
|
Exit the process.
|
|
|
|
@item evalScript(str, options = undefined)
|
|
Evaluate the string @code{str} as a script (global
|
|
eval). @code{options} is an optional object containing the following
|
|
optional properties:
|
|
|
|
@table @code
|
|
@item backtrace_barrier
|
|
Boolean (default = false). If true, error backtraces do not list the
|
|
stack frames below the evalScript.
|
|
@item async
|
|
Boolean (default = false). If true, @code{await} is accepted in the
|
|
script and a promise is returned.
|
|
@end table
|
|
|
|
@item loadScript(filename)
|
|
Evaluate the file @code{filename} as a script (global eval).
|
|
|
|
@item loadFile(filename)
|
|
Load the file @code{filename} and return it as a string assuming UTF-8
|
|
encoding. Return @code{null} in case of I/O error.
|
|
|
|
@item open(filename, flags, errorObj = undefined)
|
|
Open a file (wrapper to the libc @code{fopen()}). Return the FILE
|
|
object or @code{null} in case of I/O error. If @code{errorObj} is not
|
|
undefined, set its @code{errno} property to the error code or to 0 if
|
|
no error occured.
|
|
|
|
@item popen(command, flags, errorObj = undefined)
|
|
Open a process by creating a pipe (wrapper to the libc
|
|
@code{popen()}). Return the FILE
|
|
object or @code{null} in case of I/O error. If @code{errorObj} is not
|
|
undefined, set its @code{errno} property to the error code or to 0 if
|
|
no error occured.
|
|
|
|
@item fdopen(fd, flags, errorObj = undefined)
|
|
Open a file from a file handle (wrapper to the libc
|
|
@code{fdopen()}). Return the FILE
|
|
object or @code{null} in case of I/O error. If @code{errorObj} is not
|
|
undefined, set its @code{errno} property to the error code or to 0 if
|
|
no error occured.
|
|
|
|
@item tmpfile(errorObj = undefined)
|
|
Open a temporary file. Return the FILE
|
|
object or @code{null} in case of I/O error. If @code{errorObj} is not
|
|
undefined, set its @code{errno} property to the error code or to 0 if
|
|
no error occured.
|
|
|
|
@item puts(str)
|
|
Equivalent to @code{std.out.puts(str)}.
|
|
|
|
@item printf(fmt, ...args)
|
|
Equivalent to @code{std.out.printf(fmt, ...args)}.
|
|
|
|
@item sprintf(fmt, ...args)
|
|
Equivalent to the libc sprintf().
|
|
|
|
@item in
|
|
@item out
|
|
@item err
|
|
Wrappers to the libc file @code{stdin}, @code{stdout}, @code{stderr}.
|
|
|
|
@item SEEK_SET
|
|
@item SEEK_CUR
|
|
@item SEEK_END
|
|
Constants for seek().
|
|
|
|
@item Error
|
|
|
|
Enumeration object containing the integer value of common errors
|
|
(additional error codes may be defined):
|
|
|
|
@table @code
|
|
@item EINVAL
|
|
@item EIO
|
|
@item EACCES
|
|
@item EEXIST
|
|
@item ENOSPC
|
|
@item ENOSYS
|
|
@item EBUSY
|
|
@item ENOENT
|
|
@item EPERM
|
|
@item EPIPE
|
|
@end table
|
|
|
|
@item strerror(errno)
|
|
Return a string that describes the error @code{errno}.
|
|
|
|
@item gc()
|
|
Manually invoke the cycle removal algorithm. The cycle removal
|
|
algorithm is automatically started when needed, so this function is
|
|
useful in case of specific memory constraints or for testing.
|
|
|
|
@item getenv(name)
|
|
Return the value of the environment variable @code{name} or
|
|
@code{undefined} if it is not defined.
|
|
|
|
@item setenv(name, value)
|
|
Set the value of the environment variable @code{name} to the string
|
|
@code{value}.
|
|
|
|
@item unsetenv(name)
|
|
Delete the environment variable @code{name}.
|
|
|
|
@item getenviron()
|
|
Return an object containing the environment variables as key-value pairs.
|
|
|
|
@item urlGet(url, options = undefined)
|
|
|
|
Download @code{url} using the @file{curl} command line
|
|
utility. @code{options} is an optional object containing the following
|
|
optional properties:
|
|
|
|
@table @code
|
|
@item 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.
|
|
|
|
@item full
|
|
|
|
Boolean (default = false). If true, return the an object contains
|
|
the properties @code{response} (response content),
|
|
@code{responseHeaders} (headers separated by CRLF), @code{status}
|
|
(status code). @code{response} is @code{null} is case of protocol or
|
|
network error. If @code{full} is false, only the response is
|
|
returned if the status is between 200 and 299. Otherwise @code{null}
|
|
is returned.
|
|
|
|
@end table
|
|
|
|
@item parseExtJSON(str)
|
|
|
|
Parse @code{str} using a superset of @code{JSON.parse}. The
|
|
following extensions are accepted:
|
|
|
|
@itemize
|
|
@item Single line and multiline comments
|
|
@item unquoted properties (ASCII-only Javascript identifiers)
|
|
@item trailing comma in array and object definitions
|
|
@item single quoted strings
|
|
@item @code{\f} and @code{\v} are accepted as space characters
|
|
@item leading plus in numbers
|
|
@item octal (@code{0o} prefix) and hexadecimal (@code{0x} prefix) numbers
|
|
@end itemize
|
|
@end table
|
|
|
|
FILE prototype:
|
|
|
|
@table @code
|
|
@item close()
|
|
Close the file. Return 0 if OK or @code{-errno} in case of I/O error.
|
|
@item puts(str)
|
|
Outputs the string with the UTF-8 encoding.
|
|
@item printf(fmt, ...args)
|
|
Formatted printf.
|
|
|
|
The same formats as the standard C library @code{printf} are
|
|
supported. Integer format types (e.g. @code{%d}) truncate the Numbers
|
|
or BigInts to 32 bits. Use the @code{l} modifier (e.g. @code{%ld}) to
|
|
truncate to 64 bits.
|
|
|
|
@item flush()
|
|
Flush the buffered file.
|
|
@item seek(offset, whence)
|
|
Seek to a give file position (whence is
|
|
@code{std.SEEK_*}). @code{offset} can be a number or a bigint. Return
|
|
0 if OK or @code{-errno} in case of I/O error.
|
|
@item tell()
|
|
Return the current file position.
|
|
@item tello()
|
|
Return the current file position as a bigint.
|
|
@item eof()
|
|
Return true if end of file.
|
|
@item fileno()
|
|
Return the associated OS handle.
|
|
@item error()
|
|
Return true if there was an error.
|
|
@item clearerr()
|
|
Clear the error indication.
|
|
|
|
@item read(buffer, position, length)
|
|
Read @code{length} bytes from the file to the ArrayBuffer @code{buffer} at byte
|
|
position @code{position} (wrapper to the libc @code{fread}).
|
|
|
|
@item write(buffer, position, length)
|
|
Write @code{length} bytes to the file from the ArrayBuffer @code{buffer} at byte
|
|
position @code{position} (wrapper to the libc @code{fwrite}).
|
|
|
|
@item getline()
|
|
Return the next line from the file, assuming UTF-8 encoding, excluding
|
|
the trailing line feed.
|
|
|
|
@item readAsString(max_size = undefined)
|
|
Read @code{max_size} bytes from the file and return them as a string
|
|
assuming UTF-8 encoding. If @code{max_size} is not present, the file
|
|
is read up its end.
|
|
|
|
@item getByte()
|
|
Return the next byte from the file. Return -1 if the end of file is reached.
|
|
|
|
@item putByte(c)
|
|
Write one byte to the file.
|
|
@end table
|
|
|
|
@subsection @code{os} module
|
|
|
|
The @code{os} module provides Operating System specific functions:
|
|
|
|
@itemize
|
|
@item low level file access
|
|
@item signals
|
|
@item timers
|
|
@item asynchronous I/O
|
|
@item workers (threads)
|
|
@end itemize
|
|
|
|
The OS functions usually return 0 if OK or an OS specific negative
|
|
error code.
|
|
|
|
Available exports:
|
|
|
|
@table @code
|
|
@item open(filename, flags, mode = 0o666)
|
|
Open a file. Return a handle or < 0 if error.
|
|
|
|
@item O_RDONLY
|
|
@item O_WRONLY
|
|
@item O_RDWR
|
|
@item O_APPEND
|
|
@item O_CREAT
|
|
@item O_EXCL
|
|
@item O_TRUNC
|
|
POSIX open flags.
|
|
|
|
@item O_TEXT
|
|
(Windows specific). Open the file in text mode. The default is binary mode.
|
|
|
|
@item close(fd)
|
|
Close the file handle @code{fd}.
|
|
|
|
@item seek(fd, offset, whence)
|
|
Seek in the file. Use @code{std.SEEK_*} for
|
|
@code{whence}. @code{offset} is either a number or a bigint. If
|
|
@code{offset} is a bigint, a bigint is returned too.
|
|
|
|
@item read(fd, buffer, offset, length)
|
|
Read @code{length} bytes from the file handle @code{fd} to the
|
|
ArrayBuffer @code{buffer} at byte position @code{offset}.
|
|
Return the number of read bytes or < 0 if error.
|
|
|
|
@item write(fd, buffer, offset, length)
|
|
Write @code{length} bytes to the file handle @code{fd} from the
|
|
ArrayBuffer @code{buffer} at byte position @code{offset}.
|
|
Return the number of written bytes or < 0 if error.
|
|
|
|
@item isatty(fd)
|
|
Return @code{true} is @code{fd} is a TTY (terminal) handle.
|
|
|
|
@item ttyGetWinSize(fd)
|
|
Return the TTY size as @code{[width, height]} or @code{null} if not available.
|
|
|
|
@item ttySetRaw(fd)
|
|
Set the TTY in raw mode.
|
|
|
|
@item remove(filename)
|
|
Remove a file. Return 0 if OK or @code{-errno}.
|
|
|
|
@item rename(oldname, newname)
|
|
Rename a file. Return 0 if OK or @code{-errno}.
|
|
|
|
@item realpath(path)
|
|
Return @code{[str, err]} where @code{str} is the canonicalized absolute
|
|
pathname of @code{path} and @code{err} the error code.
|
|
|
|
@item getcwd()
|
|
Return @code{[str, err]} where @code{str} is the current working directory
|
|
and @code{err} the error code.
|
|
|
|
@item chdir(path)
|
|
Change the current directory. Return 0 if OK or @code{-errno}.
|
|
|
|
@item mkdir(path, mode = 0o777)
|
|
Create a directory at @code{path}. Return 0 if OK or @code{-errno}.
|
|
|
|
@item stat(path)
|
|
@item lstat(path)
|
|
|
|
Return @code{[obj, err]} where @code{obj} is an object containing the
|
|
file status of @code{path}. @code{err} is the error code. The
|
|
following fields are defined in @code{obj}: dev, ino, mode, nlink,
|
|
uid, gid, rdev, size, blocks, atime, mtime, ctime. The times are
|
|
specified in milliseconds since 1970. @code{lstat()} is the same as
|
|
@code{stat()} excepts that it returns information about the link
|
|
itself.
|
|
|
|
@item S_IFMT
|
|
@item S_IFIFO
|
|
@item S_IFCHR
|
|
@item S_IFDIR
|
|
@item S_IFBLK
|
|
@item S_IFREG
|
|
@item S_IFSOCK
|
|
@item S_IFLNK
|
|
@item S_ISGID
|
|
@item S_ISUID
|
|
Constants to interpret the @code{mode} property returned by
|
|
@code{stat()}. They have the same value as in the C system header
|
|
@file{sys/stat.h}.
|
|
|
|
@item utimes(path, atime, mtime)
|
|
Change the access and modification times of the file @code{path}. The
|
|
times are specified in milliseconds since 1970. Return 0 if OK or @code{-errno}.
|
|
|
|
@item symlink(target, linkpath)
|
|
Create a link at @code{linkpath} containing the string @code{target}. Return 0 if OK or @code{-errno}.
|
|
|
|
@item readlink(path)
|
|
Return @code{[str, err]} where @code{str} is the link target and @code{err}
|
|
the error code.
|
|
|
|
@item readdir(path)
|
|
Return @code{[array, err]} where @code{array} is an array of strings
|
|
containing the filenames of the directory @code{path}. @code{err} is
|
|
the error code.
|
|
|
|
@item setReadHandler(fd, func)
|
|
Add a read handler to the file handle @code{fd}. @code{func} is called
|
|
each time there is data pending for @code{fd}. A single read handler
|
|
per file handle is supported. Use @code{func = null} to remove the
|
|
handler.
|
|
|
|
@item setWriteHandler(fd, func)
|
|
Add a write handler to the file handle @code{fd}. @code{func} is
|
|
called each time data can be written to @code{fd}. A single write
|
|
handler per file handle is supported. Use @code{func = null} to remove
|
|
the handler.
|
|
|
|
@item signal(signal, func)
|
|
Call the function @code{func} when the signal @code{signal}
|
|
happens. Only a single handler per signal number is supported. Use
|
|
@code{null} to set the default handler or @code{undefined} to ignore
|
|
the signal. Signal handlers can only be defined in the main thread.
|
|
|
|
@item SIGINT
|
|
@item SIGABRT
|
|
@item SIGFPE
|
|
@item SIGILL
|
|
@item SIGSEGV
|
|
@item SIGTERM
|
|
POSIX signal numbers.
|
|
|
|
@item kill(pid, sig)
|
|
Send the signal @code{sig} to the process @code{pid}.
|
|
|
|
@item exec(args[, options])
|
|
Execute a process with the arguments @code{args}. @code{options} is an
|
|
object containing optional parameters:
|
|
|
|
@table @code
|
|
@item block
|
|
Boolean (default = true). If true, wait until the process is
|
|
terminated. In this case, @code{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.
|
|
|
|
@item usePath
|
|
Boolean (default = true). If true, the file is searched in the
|
|
@code{PATH} environment variable.
|
|
|
|
@item file
|
|
String (default = @code{args[0]}). Set the file to be executed.
|
|
|
|
@item cwd
|
|
String. If present, set the working directory of the new process.
|
|
|
|
@item stdin
|
|
@item stdout
|
|
@item stderr
|
|
If present, set the handle in the child for stdin, stdout or stderr.
|
|
|
|
@item env
|
|
Object. If present, set the process environment from the object
|
|
key-value pairs. Otherwise use the same environment as the current
|
|
process.
|
|
|
|
@item uid
|
|
Integer. If present, the process uid with @code{setuid}.
|
|
|
|
@item gid
|
|
Integer. If present, the process gid with @code{setgid}.
|
|
|
|
@end table
|
|
|
|
@item getpid()
|
|
Return the current process ID.
|
|
|
|
@item waitpid(pid, options)
|
|
@code{waitpid} Unix system call. Return the array @code{[ret,
|
|
status]}. @code{ret} contains @code{-errno} in case of error.
|
|
|
|
@item WNOHANG
|
|
Constant for the @code{options} argument of @code{waitpid}.
|
|
|
|
@item dup(fd)
|
|
@code{dup} Unix system call.
|
|
|
|
@item dup2(oldfd, newfd)
|
|
@code{dup2} Unix system call.
|
|
|
|
@item pipe()
|
|
@code{pipe} Unix system call. Return two handles as @code{[read_fd,
|
|
write_fd]} or null in case of error.
|
|
|
|
@item sleep(delay_ms)
|
|
Sleep during @code{delay_ms} milliseconds.
|
|
|
|
@item sleepAsync(delay_ms)
|
|
Asynchronouse sleep during @code{delay_ms} milliseconds. Returns a promise. Example:
|
|
@example
|
|
await os.sleepAsync(500);
|
|
@end example
|
|
|
|
@item now()
|
|
Return a timestamp in milliseconds with more precision than
|
|
@code{Date.now()}. The time origin is unspecified and is normally not
|
|
impacted by system clock adjustments.
|
|
|
|
@item setTimeout(func, delay)
|
|
Call the function @code{func} after @code{delay} ms. Return a handle
|
|
to the timer.
|
|
|
|
@item clearTimeout(handle)
|
|
Cancel a timer.
|
|
|
|
@item platform
|
|
Return a string representing the platform: @code{"linux"}, @code{"darwin"},
|
|
@code{"win32"} or @code{"js"}.
|
|
|
|
@item Worker(module_filename)
|
|
Constructor to create a new thread (worker) with an API close to the
|
|
@code{WebWorkers}. @code{module_filename} is a string specifying the
|
|
module filename which is executed in the newly created thread. As for
|
|
dynamically imported module, it is relative to the current script or
|
|
module path. Threads normally don't share any data and communicate
|
|
between each other with messages. Nested workers are not supported. An
|
|
example is available in @file{tests/test_worker.js}.
|
|
|
|
The worker class has the following static properties:
|
|
|
|
@table @code
|
|
@item parent
|
|
In the created worker, @code{Worker.parent} represents the parent
|
|
worker and is used to send or receive messages.
|
|
@end table
|
|
|
|
The worker instances have the following properties:
|
|
|
|
@table @code
|
|
@item postMessage(msg)
|
|
|
|
Send a message to the corresponding worker. @code{msg} is cloned in
|
|
the destination worker using an algorithm similar to the @code{HTML}
|
|
structured clone algorithm. @code{SharedArrayBuffer} are shared
|
|
between workers.
|
|
|
|
Current limitations: @code{Map} and @code{Set} are not supported
|
|
yet.
|
|
|
|
@item onmessage
|
|
|
|
Getter and setter. Set a function which is called each time a
|
|
message is received. The function is called with a single
|
|
argument. It is an object with a @code{data} property containing the
|
|
received message. The thread is not terminated if there is at least
|
|
one non @code{null} @code{onmessage} handler.
|
|
|
|
@end table
|
|
|
|
@end table
|
|
|
|
@section QuickJS C API
|
|
|
|
The C API was designed to be simple and efficient. The C API is
|
|
defined in the header @code{quickjs.h}.
|
|
|
|
@subsection Runtime and contexts
|
|
|
|
@code{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.
|
|
|
|
@code{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.
|
|
|
|
@subsection JSValue
|
|
|
|
@code{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 (@code{JS_DupValue()}, increment the reference
|
|
count) or free (@code{JS_FreeValue()}, decrement the reference count)
|
|
JSValues.
|
|
|
|
@subsection C functions
|
|
|
|
C functions can be created with
|
|
@code{JS_NewCFunction()}. @code{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 @code{JSValue}s as parameters
|
|
(so they don't need to free them) and return a newly allocated (=live)
|
|
@code{JSValue}.
|
|
|
|
@subsection Exceptions
|
|
|
|
Exceptions: most C functions can return a Javascript exception. It
|
|
must be explicitly tested and handled by the C code. The specific
|
|
@code{JSValue} @code{JS_EXCEPTION} indicates that an exception
|
|
occurred. The actual exception object is stored in the
|
|
@code{JSContext} and can be retrieved with @code{JS_GetException()}.
|
|
|
|
@subsection Script evaluation
|
|
|
|
Use @code{JS_Eval()} to evaluate a script or module source.
|
|
|
|
If the script or module was compiled to bytecode with @code{qjsc}, it
|
|
can be evaluated by calling @code{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 @code{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. That's why there is no option to output the bytecode to a
|
|
binary file in @code{qjsc}.
|
|
|
|
@subsection 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 (@code{JSClassID}) of
|
|
the object. Hence the first step is to register a new class ID and JS
|
|
class (@code{JS_NewClassID()}, @code{JS_NewClass()}). Then you can
|
|
create objects of this class with @code{JS_NewObjectClass()} and get or
|
|
set the C opaque point with
|
|
@code{JS_GetOpaque()}/@code{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 @code{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 @code{JSRuntime}. @code{JS_SetClassProto()}
|
|
is used to define a prototype for a given class in a given
|
|
JSContext. @code{JS_NewObjectClass()} sets this prototype in the
|
|
created object.
|
|
|
|
Examples are available in @file{quickjs-libc.c}.
|
|
|
|
@subsection C Modules
|
|
|
|
Native ES6 modules are supported and can be dynamically or statically
|
|
linked. Look at the @file{test_bjson} and @file{bjson.so}
|
|
examples. The standard library @file{quickjs-libc.c} is also a good example
|
|
of a native module.
|
|
|
|
@subsection Memory handling
|
|
|
|
Use @code{JS_SetMemoryLimit()} to set a global memory allocation limit
|
|
to a given JSRuntime.
|
|
|
|
Custom memory allocation functions can be provided with
|
|
@code{JS_NewRuntime2()}.
|
|
|
|
The maximum system stack size can be set with @code{JS_SetMaxStackSize()}.
|
|
|
|
@subsection Execution timeout and interrupts
|
|
|
|
Use @code{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
|
|
@code{Ctrl-C} handler.
|
|
|
|
@chapter Internals
|
|
|
|
@section 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 @code{eval} in strict mode is optimized.
|
|
|
|
@section Executable generation
|
|
|
|
@subsection @code{qjsc} compiler
|
|
|
|
The @code{qjsc} compiler generates C sources from Javascript files. By
|
|
default the C sources are compiled with the system compiler
|
|
(@code{gcc} or @code{clang}).
|
|
|
|
The generated C source contains the bytecode of the compiled functions
|
|
or modules. If a full complete executable is needed, it also
|
|
contains a @code{main()} function with the necessary C code to initialize the
|
|
Javascript engine and to load and execute the compiled functions and
|
|
modules.
|
|
|
|
Javascript code can be mixed with C modules.
|
|
|
|
In order to have smaller executables, specific Javascript features can
|
|
be disabled, in particular @code{eval} or the regular expressions. The
|
|
code removal relies on the Link Time Optimization of the system
|
|
compiler.
|
|
|
|
@subsection Binary JSON
|
|
|
|
@code{qjsc} works by compiling scripts or modules and then serializing
|
|
them to a binary format. A subset of this format (without functions or
|
|
modules) can be used as binary JSON. The example @file{test_bjson.js}
|
|
shows how to use it.
|
|
|
|
Warning: the binary JSON format may change without notice, so it
|
|
should not be used to store persistent data. The @file{test_bjson.js}
|
|
example is only used to test the binary object format functions.
|
|
|
|
@section Runtime
|
|
|
|
@subsection 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.
|
|
|
|
@subsection 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.
|
|
|
|
@subsection 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 @math{0} to @math{2^{31}-1}.
|
|
|
|
@subsection 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.
|
|
|
|
@subsection 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.
|
|
|
|
@subsection 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.
|
|
|
|
@subsection Function call
|
|
|
|
The engine is optimized so that function calls are fast. The system
|
|
stack holds the Javascript parameters and local variables.
|
|
|
|
@section 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.
|
|
|
|
@section 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).
|
|
|
|
@section BigInt, BigFloat, BigDecimal
|
|
|
|
BigInt, BigFloat and BigDecimal are implemented with the @code{libbf}
|
|
library@footnote{@url{https://bellard.org/libbf}}. It weights about 90
|
|
KiB (x86 code) and provides arbitrary precision IEEE 754 floating
|
|
point operations and transcendental functions with exact rounding.
|
|
|
|
@chapter License
|
|
|
|
QuickJS is released under the MIT license.
|
|
|
|
Unless otherwise specified, the QuickJS sources are copyright Fabrice
|
|
Bellard and Charlie Gordon.
|
|
|
|
@bye
|