qjsqjscqjscalcstdosqjscQuickJS adalah mesin JavaScript yang kecil dan dapat disematkan yang mendukung spesifikasi ES2020 termasuk modul, generator asinkron, dan proxy.
Secara opsional mendukung ekstensi matematika seperti bilangan bulat besar (BigInt), nomor titik mengambang besar (BigFloat), dan kelebihan operator.
Situs Resmi: https://bellard.org/quickjs/
Situs Cina: https://github.com/quickjs-zh/
QuickJS QQ Group 1: 598609506 .
Wiki Cina: https://github.com/quickjs-zh/quickjs/wiki
Klik untuk melihat konten spesifik tes benchmark QuickJS
Menyediakan makefile yang dapat dikompilasi di Linux atau MacOS/X. Dukungan Windows awal dapat diperoleh dengan kompilasi silang pada host Linux menggunakan alat MINGW.
Jika Anda ingin memilih opsi tertentu, edit bagian atas Makefile dan Run make .
Execute make install menggunakan root untuk menginstal file biner dan dukungan yang dikompilasi ke /usr/local (ini tidak diperlukan untuk menggunakan QuickJS).
Catatan : Anda dapat merujuk ke dokumentasi China QuickJS tentang kompilasi dan instalasi di bawah Windows dan kompilasi dan instalasi di bawah Linux.
qjs adalah parser baris perintah (loop baca-eval-print).
./qjs examples/hello.js
qjsc adalah kompiler baris perintah:
./qjsc -o hello examples/hello.js
./hello
Hasilkan file hello yang dapat dieksekusi tanpa dependensi eksternal.
qjsbn dan qjscbn adalah penerjemah dan kompiler yang sesuai dengan ekstensi matematika:
./qjsbn examples/pi.js 1000
Tampilkan 1000 digit pi
./qjsbnc -o pi examples/pi.js
./pi 1000
Kompilasi dan jalankan program PI.
qjsPenggunaan: QJS [Opsi] [File]
Opsi:
-h
--help
Daftar opsi.
-e `EXPR`
--eval `EXPR`
Lakukan Expr.
-i
--interactive
Buka mode interaktif (ini bukan mode default ketika file disajikan pada baris perintah).
-m
--module
Muat sebagai modul ES6 (default adalah ekstensi file .mjs).
Opsi canggih meliputi:
-d
--dump
Transfer Statistik Penggunaan Memori.
-q
--quit
Cukup instantiate penerjemah dan keluar.
qjscPenggunaan: QJSC [Opsi] [File]
Opsi:
-c
Hanya bytecode dalam file C adalah output, dan standarnya adalah untuk mengeluarkan file yang dapat dieksekusi.
-e
main() output dan bytecode dalam file C, default adalah file output yang dapat dieksekusi.
-o output
Atur nama file output (default = out.c atau A.out).
-N cname
Mengatur nama C dari data yang dihasilkan.
-m
Kompilasi sebagai modul JavaScript (default adalah ekstensi .mjs).
-M module_name[,cname]
Tambahkan kode inisialisasi untuk modul C eksternal. Lihat contoh c_module .
-x
Output byte swap (hanya untuk kompilasi silang).
-flto
Gunakan pengoptimalan waktu tautan. Kompilasi lebih lambat, tetapi executable lebih kecil dan lebih cepat. Opsi ini diatur secara otomatis saat menggunakan opsi -fno-x .
-fno-[eval|string-normalize|regexp|json|proxy|map|typedarray|promise]
Nonaktifkan fitur bahasa yang dipilih untuk menghasilkan file yang dapat dieksekusi lebih kecil.
qjscalc Aplikasi qjscalc adalah superset dari interpreter baris perintah qjsbn yang mengimplementasikan kalkulator JavaScript dengan bilangan bulat besar yang sewenang -wenang dan angka titik mengambang, fraksi, bilangan kompleks, polinomial, dan matriks. Kode sumber ada di qjscalc.js. Lebih banyak dokumentasi dan versi web tersedia di http://numcalc.com.
Run make test untuk menjalankan beberapa tes bawaan yang termasuk dalam arsip QuickJS.
Arsip QuickJS berisi program Test262 Runner.
Untuk referensi, tes test262 lengkap disediakan dalam arsip QJS-tes-yyyy-mm-dd.tar.xz. Anda hanya perlu membuka ritsletingnya ke direktori sumber QuickJS.
Atau, tes test262 dapat diinstal:
git clone https://github.com/tc39/test262.git test262
cd test262
git checkout 94b1e80ab3440413df916cd56d29c5a2fa2ac451
patch -p1 < ../tests/test262.patch
cd ..
Patch menambahkan fungsi harness khusus implementasi dan mengoptimalkan kelas karakter RegExp yang tidak efisien dan uji pelarian atribut unicode (tes itu sendiri tidak akan dimodifikasi, hanya fungsi inisialisasi string lambat yang dioptimalkan).
Tes dapat berjalan
make test2
Untuk informasi lebih lanjut, jalankan ./run-test262 untuk melihat opsi untuk test262 runner. File konfigurasi test262.conf dan test262bn.conf berisi opsi untuk menjalankan berbagai tes.
Spesifikasi ES2019 2, yang mencakup Lampiran B (Kompatibilitas Web Legacy) dan fitur terkait unicode, pada dasarnya sudah didukung. Fitur -fitur berikut belum didukung:
JSON Parsers saat ini didukung oleh rentang yang lebih luas dari spesifikasi.
ECMA402 (API Internasional) belum didukung.
"use strip" tidak menyimpan informasi debug (termasuk kode sumber fungsi) untuk menyimpan memori. Arahan "use strict" dapat menerapkan skrip global, atau fungsi spesifik.#! Ekstensi matematika tersedia dalam versi qjsbn dan sepenuhnya kompatibel dengan jsbignum.pdf standar.
BigInt (Integer Besar) TC39 sudah didukung.BigFloat : Setiap nomor titik mengambang besar dalam kardinalitas 2."use bigint" memungkinkan Bigint Mode, dan BigInt adalah bilangan bulat secara default."use math" memungkinkan mode matematika di mana pembagian dan operator daya pada bilangan bulat menghasilkan fraksi. Secara default, floating point literal adalah nilai default dan bilangan bulat adalah nilai default Bigint.Modul ES6 sepenuhnya mendukung. Aturan resolusi nama default adalah sebagai berikut:
. atau .. adalah jalur relatif terhadap modul saat ini.. Atau .. adalah modul sistem seperti std atau os ..so dan merupakan modul asli menggunakan API QuickJS C. Secara default, pustaka standar termasuk dalam penerjemah baris perintah. Ini berisi dua modul std dan os dan beberapa objek global.
scriptArgs
Berikan parameter baris perintah. Parameter pertama adalah nama skrip.
print(...args)
Parameter mencetak dipisahkan oleh spasi dan trailing newline.
console.log(...args)
Sama seperti print ().
std Modul std menyediakan pembungkus untuk libc stdlib.h dan stdio.h dan beberapa utilitas lainnya.
Ekspor Tersedia:
exit(n)
Keluar dari prosesnya.
evalScript(str)
Jalankan String str Scripted (Global Eval).
loadScript(filename)
Jalankan skrip filename (Global Eval).
Error(errno)
std.Error Constructor. Contoh kesalahan berisi bidang errno (kode kesalahan) dan message (hasil std.Error.strerror(errno) ).
Konstruktor berisi bidang -bidang berikut:
EINVAL
EIO
EACCES
EEXIST
ENOSPC
ENOSYS
EBUSY
ENOENT
EPERM
EPIPE
Nilai integer yang salah (kode kesalahan tambahan dapat didefinisikan).
strerror(errno)
Mengembalikan string errno yang menjelaskan kesalahan.
open(filename, flags)
Buka file (libc's wrapper fopen() ). Lempar std.Error dalam kesalahan I/O
tmpfile()
Buka file sementara. Lempar std.Error dalam kesalahan I/O.
puts(str)
Itu setara dengan std.out.puts(str) .
printf(fmt, ...args)
Setara dengan std.out.printf(fmt, ...args)
sprintf(fmt, ...args)
Setara dengan libc's sprintf ().
in
out
err
Bungkus stdin , stdout , stderr dari file libc.
SEEK_SET
SEEK_CUR
SEEK_END
Konstanta Seek ()
global
Referensi ke objek global.
gc()
Hubungi algoritma penghapusan loop secara manual. Algoritma pelepasan loop secara otomatis dimulai saat dibutuhkan, sehingga fitur ini sangat berguna ketika batas atau pengujian memori spesifik.
getenv(name)
Mengembalikan name nilai variabel lingkungan, atau undefined jika tidak ditentukan.
Prototipe file:
close()
Tutup file.
puts(str)
Gunakan pengkodean UTF-8 untuk string output.
printf(fmt, ...args)
Format printf, sama dengan format libc printf.
flush()
Segarkan file buffered.
seek(offset, whence)
Mencari lokasi file tertentu (dari mana std.SEEK_* ). Lempar std.Error dalam kesalahan I/O.
tell()
Kembali ke lokasi file saat ini.
eof()
Kembalikan true jika file berakhir.
fileno()
Mengembalikan pegangan OS terkait.
read(buffer, position, length)
Dari position file dalam posisi byte, baca byte length ke buffer arraybuffer (libc's wrapper fread ).
write(buffer, position, length)
Tulis byte length dalam buffer arraybuffer dimulai dengan position posisi byte ke file (libc's wrapper fread ).
getline()
Mengembalikan baris berikutnya dalam file, dengan asumsi itu adalah pengkodean UTF-8, tidak termasuk trailing newline.
getByte()
Mengembalikan byte berikutnya dalam file.
putByte(c)
Tulis byte ke file.
os Modul os menyediakan fungsi spesifik sistem operasi:
Jika OK, fungsi OS biasanya mengembalikan 0, atau OS mengembalikan kode kesalahan tertentu.
Fungsi Ekspor Tersedia:
open(filename, flags, mode = 0o666)
Buka file. Jika kesalahan, kembalikan pegangan atau <0.
O_RDONLY
O_WRONLY
O_RDWR
O_APPEND
O_CREAT
O_EXCL
O_TRUNC
POSIX OPEN TANDA.
O_TEXT
(Spesifik Windows). Buka file dalam mode teks. Default adalah mode biner.
close(fd)
Tutup pegangan file fd .
seek(fd, offset, whence)
Mencari file. Gunakan std.SEEK_* atau whence .
read(fd, buffer, offset, length)
Mulai dari pegangan file fd dengan posisi byte offset , baca byte length ke buffer arraybuffer. Mengembalikan jumlah byte yang dibaca, dan jika terjadi kesalahan, ia mengembalikan nilai kurang dari 0.
write(fd, buffer, offset, length)
Tulis byte length di buffer arraybuffer dimulai dengan posisi byte offset pegangan file fd . Mengembalikan jumlah byte yang ditulis, dan jika terjadi kesalahan, nilai kurang dari 0 dikembalikan.
isatty(fd)
fd adalah pegangan TTY (terminal) yang mengembalikan true .
ttyGetWinSize(fd)
Mengembalikan ukuran TTY [width, height] atau null jika tidak tersedia.
ttySetRaw(fd)
Atur TTY dalam mode asli.
remove(filename)
Hapus file. Kembalikan 0 jika normal, kembalikan <0 jika kesalahan
rename(oldname, newname)
Ganti nama file. Kembalikan 0 jika normal, kembalikan <0 jika kesalahan
setReadHandler(fd, func)
Tambahkan penangan baca ke pegangan file fd . fd Calls func Setiap kali ada data yang akan ditambahkan ke proses. Mendukung satu penangan baca tunggal untuk setiap pegangan file. Gunakan func = null untuk menghapus pegangan.
setWriteHandler(fd, func)
Tambahkan penangan tulis ke pegangan file fd . fd Calls func Setiap kali ada data yang harus ditulis untuk diproses. Gunakan `func = null untuk menghapus pegangan.
signal(signal, func)
Hubungi func saat signal terjadi. Hanya satu penangan yang didukung per nomor sinyal. Gunakan sinyal abaikan yang diproses atau undefined yang ditetapkan oleh null .
SIGINT
SIGABRT
SIGFPE
SIGILL
SIGSEGV
SIGTERM
Nomor Sinyal POSIX.
setTimeout(func, delay)
Hubungi fungsi func setelah delay milidetik. Mengembalikan pegangan ke timer.
clearTimer(handle)
Batalkan timer.
platform
Mengembalikan string yang mewakili platform: "linux" , "darwin" , "win32" atau "js" .
API C sederhana dan efektif. API C didefinisikan dalam header quickjs.h .
JSRuntime mewakili runtime JavaScript yang sesuai dengan tumpukan objek. Beberapa runtime dapat ada pada saat yang sama, tetapi mereka tidak dapat bertukar objek. Dalam runtime yang diberikan, multithreading tidak didukung.
JSContext mewakili konteks JavaScript (atau domain). Setiap JScontext memiliki objek global dan sistemnya sendiri. Mungkin ada beberapa JScontext di JSruntime, dan mereka dapat berbagi objek, mirip dengan kerangka kerja dengan sumber yang sama berbagi objek JavaScript di browser web.
JSValue mewakili nilai JavaScript, yang dapat berupa tipe primitif atau objek. Gunakan jumlah referensi, jadi penting untuk disalin secara eksplisit ( JS_DupValue() , meningkatkan jumlah referensi) atau rilis ( JS_FreeValue() , mengurangi jumlah referensi) JSVALUES.
Gunakan JS_NewCFunction() untuk membuat fungsi C. JS_SetPropertyFunctionList() adalah cara mudah untuk dengan mudah menambahkan fungsi, setter, dan mendapatkan properti ke objek yang diberikan.
Tidak seperti mesin javascript tertanam lainnya, QuickJs tidak memiliki tumpukan implisit, sehingga fungsi C melewati parameternya sebagai parameter C normal. Aturan umumnya adalah bahwa fungsi C mengambil JSValue sebagai argumen (sehingga mereka tidak perlu dibebaskan) dan mengembalikan JSValue yang baru dialokasikan (aktif).
Pengecualian: Sebagian besar fungsi C dapat mengembalikan pengecualian JavaScript. Itu harus diuji secara eksplisit dan diproses melalui kode C. JSValue spesifik, yaitu JS_EXCEPTION , menunjukkan bahwa pengecualian telah terjadi. Objek pengecualian aktual disimpan dalam JSContext dan dapat diambil menggunakan JS_GetException() .
Gunakan JS_Eval() untuk mengevaluasi skrip atau kode sumber modul.
Jika skrip atau modul telah dikompilasi ke dalam bytecode menggunakan qjsc , maka menggunakan JS_EvalBinary() dapat mencapai hasil yang sama. Keuntungannya adalah tidak memerlukan kompilasi, sehingga ukurannya lebih cepat dan lebih kecil, karena jika eval tidak diperlukan, kompiler dapat dihapus dari yang dapat dieksekusi.
Catatan: Format bytecode dikaitkan dengan versi QuickJS tertentu. Selain itu, tidak ada pemeriksaan keamanan yang dilakukan sebelum dieksekusi. Oleh karena itu, bytecode tidak boleh dimuat dari sumber yang tidak dipercaya. Inilah sebabnya mengapa tidak ada opsi dalam qjsc untuk meng -output bytecode ke file biner.
Data buram C dapat dilampirkan ke objek JavaScript. Jenis data buram C ditentukan oleh ID kelas objek ( JSClassID ). Oleh karena itu, langkah pertama adalah mendaftarkan ID kelas baru dan kelas JS ( JS_NewClassID() , JS_NewClass() ). Anda kemudian dapat membuat objek dari kelas itu menggunakan JS_NewObjectClass() dan menggunakan JS_GetOpaque() / JS_SetOpaque() untuk mendapatkan atau mengatur pointer buram ke C.
Saat mendefinisikan kelas JS baru, Anda dapat mendeklarasikan destruktor yang dipanggil saat objek dihancurkan. Metode gc_mark dapat disediakan sehingga algoritma penghapusan loop dapat menemukan objek lain yang dirujuk oleh objek. Ada metode lain yang dapat digunakan untuk mendefinisikan perilaku objek yang heterogen.
ID kelas dialokasikan secara global (mis. Berlaku untuk semua runtime). JSClass dialokasikan di setiap JSRuntime . JS_SetClassProto() digunakan untuk mendefinisikan prototipe untuk kelas tertentu dalam JSContext yang diberikan. JS_NewObjectClass() Mengatur prototipe ini di objek yang dibuat.
Contoh disediakan dalam JS_LIBC.C.
Modul ES6 asli yang mendukung tautan dinamis atau statis. Lihat contoh test_bjson dan bjson.so. Perpustakaan standar js_libc.c juga merupakan contoh yang baik dari modul asli.
Tetapkan batas alokasi memori global untuk jsruntime yang diberikan menggunakan JS_SetMemoryLimit() .
JS_NewRuntime2() dapat menyediakan fungsi alokasi memori khusus.
JS_SetMaxStackSize() dapat diatur menggunakan ukuran tumpukan sistem maksimum
Gunakan JS_SetInterruptHandler() untuk mengatur fungsi panggilan balik yang disebut secara teratur ketika mesin menjalankan kode. Fungsi panggilan balik ini dapat digunakan untuk mengimplementasikan batas waktu eksekusi.
Interpreter baris perintah menggunakannya untuk mengimplementasikan penangan Ctrl-C .
Kompiler menghasilkan bytecode secara langsung, tanpa representasi perantara (seperti pohon parse), sehingga sangat cepat. Beberapa langkah optimasi dilakukan pada bytecode yang dihasilkan.
Bytecode berbasis tumpukan dipilih karena sederhana dan kode yang dihasilkan kompak.
Untuk setiap fungsi, ukuran tumpukan maksimum dihitung pada waktu kompilasi, jadi tidak perlu untuk tes overflow stack runtime.
Tabel nomor baris terkompresi terpisah dipertahankan untuk informasi debugging.
Akses ke variabel penutupan dioptimalkan dan hampir secepat variabel lokal.
eval langsung dalam mode ketat dioptimalkan.
qjsc Kompiler qjsc menghasilkan kode sumber C dari file JavaScript. Secara default, kode sumber C dikompilasi menggunakan System Compiler ( gcc atau clang ).
Kode sumber C yang dihasilkan berisi bytecode dari fungsi atau modul yang dikompilasi. Jika diperlukan eksekusi lengkap, itu juga berisi fungsi main() yang berisi kode C yang diperlukan untuk menginisialisasi mesin JavaScript dan memuat dan menjalankan fungsi dan modul yang dikompilasi.
Kode JavaScript dapat dicampur dengan modul C.
Untuk menghasilkan executable yang lebih kecil, fitur JavaScript spesifik, terutama eval atau ekspresi reguler, dapat dinonaktifkan. Penghapusan kode ditautkan ke optimasi waktu tautan yang bergantung pada kompiler sistem.
qjsc berfungsi dengan menyusun skrip atau modul dan kemudian membuat serial ke dalam format biner. Subset dari format ini (tidak termasuk fungsi atau modul) dapat digunakan sebagai JSON biner. Sampel test_bjson.js menunjukkan cara menggunakannya.
PERINGATAN: Format Binary JSON dapat berubah tanpa pemberitahuan dan tidak boleh digunakan untuk menyimpan data yang persisten. Contoh test_bjson.js hanya digunakan untuk menguji fungsi dalam format objek biner.
String disimpan sebagai array karakter 8-bit atau 16-bit. Oleh karena itu, akses acak ke karakter selalu cepat.
API C menyediakan fungsi untuk mengubah string JavaScript menjadi string yang dikodekan C UTF-8. Kasus yang paling umum adalah bahwa string JavaScript hanya berisi string ASCII dan tidak melibatkan penyalinan.
Bentuk objek (prototipe objek, nama atribut, dan bendera) dibagikan di antara objek untuk menyimpan memori.
Array yang dioptimalkan tanpa lubang (kecuali di akhir array).
Akses TypedArray dioptimalkan.
Nama properti objek dan beberapa string disimpan sebagai atom (string unik) untuk menghemat memori dan memungkinkan perbandingan cepat. Atom direpresentasikan sebagai bilangan bulat 32-bit. Setengah dari rentang atom dicadangkan untuk nilai nominal integer langsung dari 0 hingga 2^{31} -1.
Angka dapat direpresentasikan sebagai bilangan bulat yang ditandatangani 32-bit atau nilai floating point IEEE-754 64-bit. Sebagian besar operasi memiliki jalur cepat untuk kasus bilangan bulat 32-bit.
Hitungan referensi digunakan untuk melepaskan objek secara otomatis dan akurat. Ketika memori yang dialokasikan menjadi terlalu besar, operasi penghapusan loop terpisah dilakukan. Algoritma penghapusan loop hanya menggunakan jumlah referensi dan konten objek, jadi tidak perlu secara eksplisit memanipulasi root pengumpulan sampah dalam kode C.
JSValue adalah nilai JavaScript yang bisa menjadi tipe primitif (seperti angka, string, dll.) Atau objek. Dalam versi 32-bit, Nan Boxing digunakan untuk menyimpan angka floating point 64-bit. Representasi dioptimalkan untuk menguji integer 32-bit secara efisien dan nilai jumlah referensi.
Dalam kode 64-bit, ukuran JSValue adalah 128 bit dan tidak kotak menggunakan NAN. Alasannya adalah bahwa dalam kode 64-bit, penggunaan memori tidak begitu penting.
Dalam kedua kasus (32-bit atau 64-bit), JSValue cocok tepat dua register CPU, sehingga dapat dikembalikan secara efisien oleh fungsi C.
Mesin telah dioptimalkan, sehingga panggilan fungsi cepat. Tumpukan sistem berisi parameter JavaScript dan variabel lokal.
Mesin ekspresi reguler tertentu dikembangkan. Ini kecil dan efisien dan mendukung semua fitur ES2019, termasuk properti Unicode. Sebagai kompiler JavaScript, secara langsung menghasilkan bytecode tanpa pohon parse.
Gunakan backtracking tumpukan eksplisit sehingga tidak ada rekursi pada tumpukan sistem. Quantizer sederhana dioptimalkan secara khusus untuk menghindari rekursi.
Rekursi tak terbatas dari kuantizer dengan istilah kosong dihindari.
Berat perpustakaan ekspresi reguler lengkap adalah sekitar 15 kib (kode x86), tidak termasuk pustaka Unicode.
Perpustakaan Unicode spesifik dikembangkan, sehingga tidak bergantung pada perpustakaan unicode besar eksternal seperti ICU. Kompres semua tabel unicode sambil mempertahankan kecepatan akses yang wajar.
Perpustakaan mendukung konversi kasus, normalisasi unicode, kueri skrip unicode, kueri kategori umum unicode, dan semua properti biner Unicode.
Perpustakaan Unicode lengkap memiliki berat sekitar 45 kib (kode x86).
BigInt dan BigFloat diimplementasikan menggunakan perpustakaan libbf libbf Library. Ini memiliki sekitar 60 kib (kode x86) dan menyediakan operasi titik mengambang IEEE 754 dengan presisi sewenang -wenang dan fungsi transenden dengan pembulatan yang tepat.
QuickJS dirilis di bawah protokol MIT.
Kecuali dinyatakan lain, hak cipta sumber QuickJS milik Fabrice Bellard dan Charlie Gordon.
https://github.com/tc39/test262
https://tc39.github.io/ecma262/
Kami percaya bahwa spesifikasi panggilan ekor saat ini terlalu kompleks dan memiliki manfaat aktual yang terbatas.
https://bellard.org/libbf
Perpustakaan Quickjs-Quickjs Di Bawah IOS
QuickJS - Perpustakaan Android QuickJs Di Bawah Android
Perpustakaan QuickJS Quickjs-Rs Rust
Quickjspp c ++ pustaka quickjs
Perpustakaan QuickJS Go-Quickjs Go
txiki.js Runtime JavaScript kecil yang dibangun dengan QuickJs, Libuv dan ❤️
Binding Quickjs-Pascal QuickJS Freepascal / Delphi