qjs Интерпретаторqjscqjscalc ПриложениеstdosqjscQuickJS - это небольшой и встраиваемый двигатель JavaScript, который поддерживает спецификации ES2020, включая модули, асинхронные генераторы и прокси.
По желанию поддерживает математические расширения, такие как крупные целые числа (bigint), большие номера с плавающей запятой (Bigfloat) и перегрузка оператора.
Официальный сайт: https://bellard.org/quickjs/
Китайский сайт: https://github.com/quickjs-zh/
QuickJS QQ Группа 1: 598609506 .
Китайская вики: https://github.com/quickjs-zh/quickjs/wiki
Нажмите, чтобы просмотреть конкретный контент теста на тесте QuickJSS
Обеспечивает маркировку, которые могут быть скомпилированы на Linux или MacOS/X. Предварительная поддержка Windows может быть получена путем перекрестной компиляции на хосте Linux с использованием инструмента Mingw.
Если вы хотите выбрать конкретную опцию, отредактируйте верхнюю часть Makefile и запустите make .
Выполнить make install Используя root, чтобы установить скомпилированные бинарные и поддержки файлов в /usr/local (это не требуется для использования QuickJS).
ПРИМЕЧАНИЕ . Вы можете обратиться к китайской документации QuickJS по компиляции и установке под Windows, а также компиляцией и установкой под Linux.
qjs -это анализатор командной строки (цикл чтения-эвер-принте).
./qjs examples/hello.js
qjsc - компилятор командной строки:
./qjsc -o hello examples/hello.js
./hello
Создайте исполняемый файл hello без внешних зависимостей.
qjsbn и qjscbn являются соответствующими интерпретаторами и компиляторами с математическими расширениями:
./qjsbn examples/pi.js 1000
Дисплей 1000 цифр PI
./qjsbnc -o pi examples/pi.js
./pi 1000
Скомпилируйте и выполните PI -программу.
qjs ИнтерпретаторИспользование: QJS [Параметры] [файлы]
Параметры:
-h
--help
Список параметров.
-e `EXPR`
--eval `EXPR`
Выполнить эксп.
-i
--interactive
Перейдите в интерактивный режим (это не режим по умолчанию, когда файл обслуживается в командной строке).
-m
--module
Загрузите как модуль ES6 (по умолчанию расширение файла .mjs).
Расширенные варианты включают:
-d
--dump
Передача статистики использования памяти.
-q
--quit
Просто создайте экземпляр переводчика и выходит.
qjscИспользование: QJSC [Параметры] [Файлы]
Параметры:
-c
Только байт -код в файле C является выводом, а по умолчанию - вывод исполняемого файла.
-e
main() Вывод и байт -код в файле C, по умолчанию является исполняемый файл вывода.
-o output
Установите имя выходного файла (default = out.c или a.out).
-N cname
Устанавливает имя C сгенерированных данных.
-m
Скомпилируйте как модуль JavaScript (по умолчанию - расширение .mjs).
-M module_name[,cname]
Добавьте код инициализации для внешних модулей C. Проверьте пример c_module .
-x
Byte Swap
-flto
Используйте оптимизация времени ссылки. Компиляция медленнее, но исполнители меньше и быстрее. Эта опция автоматически устанавливается при использовании опции -fno-x .
-fno-[eval|string-normalize|regexp|json|proxy|map|typedarray|promise]
Отключите выбранную языковую функцию, чтобы генерировать меньшие исполняемые файлы.
qjscalc Приложение Приложение qjscalc является суперсетом интерпретатора командной строки qjsbn , которая реализует калькулятор JavaScript с произвольными большими целыми числами и номерами с плавающими темпами, фракциями, комплексными числами, полиномами и матрицами. Исходный код в QJSCALC.JS. Больше документации и веб -версий доступны на http://numcalc.com.
Запустите make test , чтобы запустить некоторые встроенные тесты, включенные в архив QuickJS.
Архив QuickJS содержит программу Test262 Runner.
Для справки, полный тест Test262 представлен в архиве QJS-Tests-Yyyy-Mm-Dd.Tar.xz. Вам просто нужно расстегнуть его в справочник QuickJS Source.
В качестве альтернативы можно установить тест Test262:
git clone https://github.com/tc39/test262.git test262
cd test262
git checkout 94b1e80ab3440413df916cd56d29c5a2fa2ac451
patch -p1 < ../tests/test262.patch
cd ..
Патч добавляет функции harness , специфичные для реализации, и оптимизирует неэффективные классы символов REGEXP и испытания атрибута Unicode (сам тест не будет изменен, оптимизирована только функция медленной строки).
Тест может работать
make test2
Для получения дополнительной информации запустите ./run-test262 , чтобы увидеть параметры для Test262 Runner. Файл конфигурации test262.conf и test262bn.conf содержат параметры для запуска различных тестов.
Спецификация 2 ES2019, которая включает в себя приложение B (Legacy Web Compatibility) и функции, связанные с Unicode, уже в основном поддерживается. Следующие функции еще не поддерживаются:
Парсеры JSON в настоящее время поддерживаются более широким диапазоном, чем спецификация.
ECMA402 (International API) еще не поддерживается.
"use strip" не сохраняет информацию отладки (включая исходный код функции) для сохранения памяти. Директива "use strict" может применять глобальные сценарии или конкретные функции.#! в начале сценария будет проигнорирована. Расширения математики доступны в версии qjsbn и полностью обратно совместимы со стандартным jsbignum.pdf .
BigInt (большое целое число) TC39 уже поддерживается.BigFloat поддерживает: любой большой номер плавающей запятой в кардинал 2."use bigint" позволяет Bigint Mode, а BigInt по умолчанию является целым числом."use math" обеспечивает математический режим, в котором операторы деления и электроэнергии на целых числах производят фракции. По умолчанию литералы с плавающей запятой являются значением по умолчанию, а целые числа являются значением BigInt по умолчанию.ES6 модуль полностью поддерживает. Правила разрешения имен по умолчанию следующие:
. .. это путь относительно текущего модуля.os модуля не .. std ..so и является собственным модулем, использующим API QuickJS C. По умолчанию стандартная библиотека включена в интерпретатор командной строки. Он содержит два модуля std и os и некоторые глобальные объекты.
scriptArgs
Укажите параметры командной строки. Первый параметр - это имя скрипта.
print(...args)
Отпечатывает параметры, разделенные пространствами и новенами.
console.log(...args)
То же, что и print ().
std Модуль std предоставляет обертки для libc stdlib.h и stdio.h и некоторых других утилит.
Экспорт доступен:
exit(n)
Выйдите из процесса.
evalScript(str)
Запустите сценарий String str (Global Eval).
loadScript(filename)
Запустите скрипт filename (Global Eval).
Error(errno)
std.Error Constructor. Экземпляр ошибки содержит поля errno (код ошибки) и message (результат std.Error.strerror(errno) ).
Конструктор содержит следующие поля:
EINVAL
EIO
EACCES
EEXIST
ENOSPC
ENOSYS
EBUSY
ENOENT
EPERM
EPIPE
Обычно неверные целочисленные значения (дополнительные коды ошибок могут быть определены).
strerror(errno)
Возвращает строку errno , которая описывает ошибку.
open(filename, flags)
Откройте файл (обертка Libc fopen() ). Бросить std.Error в ошибку ввода/вывода
tmpfile()
Откройте временный файл. Бросить std.Error в ошибку ввода/вывода.
puts(str)
Это эквивалентно std.out.puts(str) .
printf(fmt, ...args)
Эквивалент std.out.printf(fmt, ...args)
sprintf(fmt, ...args)
Эквивалент Libc Sprintf ().
in
out
err
Оберните stdin , stdout , stderr of libc file.
SEEK_SET
SEEK_CUR
SEEK_END
постоянные поиска ()
global
Ссылки на глобальные объекты.
gc()
Вручную вызовите алгоритм удаления петли. Алгоритм удаления цикла автоматически начинается при необходимости, поэтому эта функция очень полезна, когда конкретные ограничения памяти или тестирование.
getenv(name)
Возвращает name значения переменной среды или undefined , если не определено.
Файл -прототип:
close()
Закройте файл.
puts(str)
Используйте кодирование UTF-8 на выходные строки.
printf(fmt, ...args)
Format printf, так же, как формат Printf Libc.
flush()
Обновите забуференный файл.
seek(offset, whence)
Ищу конкретное местоположение файла (откуда std.SEEK_* ). Бросить std.Error в ошибку ввода/вывода.
tell()
Вернитесь в текущее местоположение файла.
eof()
Верните True, если файл заканчивается.
fileno()
Возвращает соответствующую ручку ОС.
read(buffer, position, length)
В position файла в положении байта прочитайте байт length в buffer ArrayBuffer ( fread LIBC).
write(buffer, position, length)
Напишите байты length в buffer ArrayBuffer, начиная с position положения байта в файл ( fread LIBC).
getline()
Возвращает следующую строку в файле, предполагая, что она является кодировкой UTF-8, за исключением новичков с притяжениями.
getByte()
Возвращает следующий байт в файле.
putByte(c)
Напишите байт в файл.
os Модуль os обеспечивает специфические функции операционной системы:
Если ОК, функция ОС обычно возвращает 0, или ОС возвращает конкретный код ошибки.
Экспортные функции доступны:
open(filename, flags, mode = 0o666)
Откройте файл. Если ошибка, верните рукоятку или <0.
O_RDONLY
O_WRONLY
O_RDWR
O_APPEND
O_CREAT
O_EXCL
O_TRUNC
Posix Open Знак.
O_TEXT
(Специфичная для Windows). Откройте файл в текстовом режиме. По умолчанию двоичный режим.
close(fd)
Закрыть ручку файла fd .
seek(fd, offset, whence)
Ищу файлы. Используйте std.SEEK_* или whence .
read(fd, buffer, offset, length)
Начиная с ручки файла fd с offset положения байта, прочитайте байт length в buffer ArrayBuffer. Возвращает количество чтения байтов, и если возникает ошибка, она возвращает значение менее 0.
write(fd, buffer, offset, length)
Запишите байт length в buffer ArrayBuffer, начиная с offset ручку файла fd . Возвращает количество записанных байтов, и если возникает ошибка, возвращается значение меньше 0.
isatty(fd)
fd - это ручка TTY (терминал), которая возвращает true .
ttyGetWinSize(fd)
Возвращает размер TTY [width, height] или null если недоступен.
ttySetRaw(fd)
Установите TTY в исходном режиме.
remove(filename)
Удалить файл. Вернуть 0, если обычно, верните <0, если ошибка
rename(oldname, newname)
Переименовать файл. Вернуть 0, если обычно, верните <0, если ошибка
setReadHandler(fd, func)
Добавьте обработчик чтения в ручку файла fd . fd вызывает func каждый раз, когда есть данные, которые должны быть добавлены в процесс. Поддерживает один обработчик чтения для каждой ручки файла. Используйте func = null , чтобы удалить ручку.
setWriteHandler(fd, func)
Добавьте обработчик записи в ручку файла fd . fd вызывает func каждый раз, когда есть данные, которые должны быть записаны в процесс. Используйте `func = null, чтобы удалить ручку.
signal(signal, func)
Вызовите func когда происходит signal . Только один обработчик поддерживается на номер сигнала. Используйте обработанные или undefined сигналы игнорирования по умолчанию, установленные null .
SIGINT
SIGABRT
SIGFPE
SIGILL
SIGSEGV
SIGTERM
Номер сигнала POSIX.
setTimeout(func, delay)
Вызовите функцию func после delay миллисекунды. Возвращает ручку к таймеру.
clearTimer(handle)
Отменить таймер.
platform
Возвращает строку, представляющую платформу: "linux" , "darwin" , "win32" или "js" .
C API прост и эффективен. C API определяется в заголовке quickjs.h .
JSRuntime представляет время выполнения JavaScript, соответствующую куче объекта. Несколько времени выполнения могут существовать одновременно, но они не могут поменять объекты. В течение данного времени выполнения многопоточное чтение не поддерживается.
JSContext представляет контекст JavaScript (или домен). Каждый JSContext имеет свои собственные глобальные и системные объекты. В JSruntime может быть несколько JSContexts, и они могут делиться объектами, аналогичными структурам с теми же источниками, разделяющими объекты JavaScript в веб -браузере.
JSValue представляет значение JavaScript, которое может быть примитивным типом или объектом. Используйте ссылки, поэтому важно явно копировать ( JS_DupValue() , увеличение количества ссылок) или выпуск ( JS_FreeValue() , уменьшение ссылки) JSValues.
Используйте JS_NewCFunction() для создания C -функций. JS_SetPropertyFunctionList() - это простой способ легко добавить свойства функции, сеттера и геттера к данному объекту.
В отличие от других встроенных двигателей JavaScript, QuickJS не имеет неявного стека, поэтому функция C передает свои параметры в качестве нормальных параметров C. Общее правило состоит в том, что функции C принимают JSValue в качестве аргументов (поэтому их не нужно освобождать) и возвращать недавно выделенное (активное) JSValue .
Исключение: большинство функций C могут вернуть исключение JavaScript. Он должен быть явно протестирован и обработан с помощью C -кода. Конкретное JSValue , то есть JS_EXCEPTION , указывает, что произошло исключение. Фактический объект исключения хранится в JSContext и может быть получен с помощью JS_GetException() .
Используйте JS_Eval() для оценки скрипта или исходного кода модуля.
Если скрипт или модуль были скомпилированы в байт -код с использованием qjsc , то использование JS_EvalBinary() может достичь того же результата. Преимущество состоит в том, что он не требует компиляции, поэтому он быстрее и меньше по размеру, потому что, если eval не требуется, компилятор может быть удален из исполняемого файла.
ПРИМЕЧАНИЕ. Формат ByteCode связан с конкретной версией QuickJS. Кроме того, до исполнения не проводились проверки безопасности. Следовательно, байт -код не должен быть загружен из ненадежных источников. Вот почему в qjsc нет опции для вывода Bytecode в двоичные файлы.
Невысокие данные C могут быть прикреплены к объектам JavaScript. Тип непрозрачных данных определяется идентификатором класса объекта ( JSClassID ). Поэтому первым шагом является регистрация нового идентификатора класса и JS Class ( JS_NewClassID() , JS_NewClass() ). Затем вы можете создать объект этого класса, используя JS_NewObjectClass() и использовать JS_GetOpaque() / JS_SetOpaque() чтобы получить или установить непрозрачный указатель на C.
При определении нового класса JS вы можете объявить деструктор, который называется, когда объект уничтожен. Метод gc_mark может быть предоставлен таким образом, чтобы алгоритм удаления цикла мог найти другие объекты, на которые ссылается объект. Существуют и другие методы, которые можно использовать для определения гетерогенного поведения объекта.
Идентификатор класса выделяется во всем мире (т.е. применимо ко всем временем запуска). JSClass выделяется в каждом JSRuntime . JS_SetClassProto() используется для определения прототипов для данного класса в данном JSContext . JS_NewObjectClass() устанавливает этот прототип в созданном объекте.
Примеры приведены в JS_LIBC.C.
Нативные модули ES6, которые поддерживают динамические или статические ссылки. Проверьте примеры test_bjson и bjson.so. Стандартная библиотека JS_LIBC.C также является хорошим примером местных модулей.
Установите границы распределения глобальных памяти для данного JSruntime с использованием JS_SetMemoryLimit() .
JS_NewRuntime2() может предоставить пользовательские функции распределения памяти.
JS_SetMaxStackSize() может быть установлен с использованием максимального размера стека системы
Используйте JS_SetInterruptHandler() , чтобы настроить функцию обратного вызова, которая регулярно называется, когда двигатель выполняет код. Эта функция обратного вызова может использоваться для реализации тайм -аута выполнения.
Интерпретатор командной строки использует его для реализации обработчика Ctrl-C .
Компилятор генерирует байт -код напрямую, без промежуточных представлений (например, деревьев разбора), так что это очень быстро. Несколько шагов оптимизации выполняются на сгенерированном байт -коде.
На основе стека байт-код выбран, потому что он прост, а сгенерированный код компактный.
Для каждой функции максимальный размер стека рассчитывается во время компиляции, поэтому нет необходимости в тестах на переполнение стека выполнения.
Для отладки хранится отдельная таблица номеров сжатой строки.
Доступ к переменным закрытия оптимизирован и почти такой же быстрый, как локальные переменные.
Прямая eval в строгом режиме оптимизирована.
qjsc Компилятор qjsc генерирует исходный код C из файлов JavaScript. По умолчанию C -исходный код компилируется с использованием системного компилятора ( gcc или clang ).
Сгенерированный исходный код C содержит байт -код скомпилированной функции или модуля. Если требуется полный исполняемый файл, он также содержит функцию main() , которая содержит необходимый C -код для инициализации двигателя JavaScript и выполнения скомпилированных функций и модулей.
Код JavaScript может быть смешан с C -модулями.
Для генерации меньших исполняемых файлов можно отключить конкретные функции JavaScript, особенно eval или регулярные выражения. Удаление кода связано с системой, зависимой от компилятора, оптимизации времени ссылки.
qjsc работает, скомпилируя сценарии или модули, а затем сериализует их в двоичный формат. Подмножество этого формата (исключая функции или модули) может использоваться в качестве двоичного JSON. Образец test_bjson.js показывает, как его использовать.
ПРЕДУПРЕЖДЕНИЕ: Бинарный формат JSON может измениться без уведомления и не должен использоваться для хранения постоянных данных. Пример test_bjson.js используется только для тестирования функций в формате двоичного объекта.
Строки хранятся как 8-битные или 16-битные массивы символов. Поэтому случайный доступ к символам всегда быстр.
CPI C предоставляет функции для преобразования строк JavaScript в кодируемые строки C UTF-8. Наиболее распространенным случаем является то, что строки JavaScript содержат только строки ASCII и не включают копирование.
Формы объектов (прототип объекта, имя атрибута и флаг) делятся между объектами для сохранения памяти.
Оптимизированные массивы без отверстий (за исключением конца массива).
Доступ к TypedArray оптимизирован.
Имя свойства объекта и некоторые строки хранятся в виде атомов (уникальных строк) для сохранения памяти и обеспечения быстрого сравнения. Атомы представлены как 32-разрядные целые числа. Половина атомного диапазона зарезервирована для немедленного целого числа значений поверхности от 0 до 2^{31} -1.
Числа могут быть представлены как 32-битные значения с плавающей запятой IEEE-754. Большинство операций имеют быстрые пути для 32-битных целочисленных случаев.
Справочное количество используется для автоматического и точно отключения объектов. Когда выделенная память становится слишком большой, выполняется отдельная операция удаления цикла. В алгоритме удаления цикла используется только количество эталонных подсчетов и содержание объекта, поэтому нет необходимости явно манипулировать корнем сбора мусора в C -коде.
JSValue - это значение JavaScript, которое может быть примитивным типом (например, число, строка и т. Д.) или объектом. В 32-битной версии NAN Boxing используется для хранения 64-битных номеров плавающей запятой. Представление оптимизировано для эффективного тестирования 32-разрядных целых чисел и значений эталонного количества.
В 64-битном коде размер jsvalue составляет 128 бит и не вкладывается с использованием NAN. Причина в том, что в 64-битном коде использование памяти не так критическое.
В обоих случаях (32-битный или 64-битный) JSValue подходит ровно двум регистрам процессора, поэтому его можно эффективно возвращать функциями C.
Двигатель был оптимизирован, поэтому функциональные вызовы быстрые. Системный стек содержит параметры JavaScript и локальные переменные.
Был разработан специфический регулярный двигатель выражения. Он небольшой и эффективный и поддерживает все функции ES2019, включая свойства Unicode. Как компилятор JavaScript, он напрямую генерирует байт -код без дерева разбора.
Используйте явную обратную пробку стека, чтобы в стеке системы не было рекурсии. Простые кванторики специально оптимизированы, чтобы избежать рекурсии.
Бесконечная рекурсия от квантоза с пустыми терминами избегается.
Вес полной библиотеки регулярного выражения составляет приблизительно 15 киб (код x86), за исключением библиотеки Unicode.
Разработана конкретная библиотека Unicode, поэтому она не зависит от внешних библиотеки больших Unicode, таких как ICU. Сжатие всех таблиц Unicode при сохранении разумных скоростей доступа.
Библиотека поддерживает преобразование случая, нормализацию Unicode, запросы Script Unicode, запросы общей категории Unicode и все бинарные свойства Unicode.
Полная библиотека Unicode весит приблизительно 45 киб (код x86).
Bigint и Bigfloat реализованы с использованием библиотеки libbf libbf . Он имеет около 60 киб (код x86) и предоставляет операции IEEE 754 с плавающей запятой с произвольной точностью и трансцендентными функциями с точным округлением.
QuickJS выпускается по протоколу MIT.
Если не указано иное, авторское право источника QuickJS принадлежит Фабрису Белларду и Чарли Гордону.
https://github.com/tc39/test262
https://tc39.github.io/ecma262/
Мы считаем, что текущая спецификация хвостового вызова слишком сложна и имеет ограниченные фактические преимущества.
https://bellard.org/libbf
Библиотека QuickJs-Quickjs под iOS
Quickjs - библиотека Android Quickjs под Android
QuickJs-RS Rust's Quickjs Library
QuickJspp C ++ QuickJs Library
Go-quickjs Go's Quickjs Library
txiki.js крошечное время выполнения JavaScript, построенное с Quickjs, Libuv и ❤
QuickJS-Pascal QuickJS Freepascal / Delphi Привязки