Lewati ke konten

Batasan yang diketahui

Phasis bertujuan berperilaku identik dengan V8 pada setiap uji spesifikasi yang dapat diamati. Halaman ini mencantumkan bagian ketika identitas itu berbeda dalam praktik — biasanya karena perbedaan mendasar antara interpreter PHP tree-walking dan engine C++ yang dikompilasi JIT.

Batas performa

Engine ini adalah tree-walker dengan VM bytecode oportunistis dan transpiler JsToPhp yang menurunkan badan yang banyak menggunakan angka / variabel lokal (termasuk bentuk obj.method(), new Ctor(), dan this.member) menjadi closure PHP native yang dapat dikompilasi menjadi kode mesin oleh JIT penelusur PHP 8.5. Sebagian besar dispatch panas terjadi di dalam loop switch VM atau langsung di PHP yang dikompilasi JIT — bukan dengan menelusuri AST — tetapi setiap opcode VM tetap menanggung biaya dispatch PHP, dan bentuk apa pun yang belum ditangani JsToPhp kembali ke VM yang lebih lambat. Batas performa untuk beban kerja yang dibatasi dispatch kira-kira ~100× lebih lambat daripada V8.

Untuk beban kerja penyematan — menjalankan logika yang diberikan pengguna pada data PHP, pipeline transformasi konten, aturan validasi — batas ini jarang berpengaruh. V8 adalah 100 ms; Phasis adalah 10 s; keduanya jauh di bawah batas waktu permintaan. Untuk memperkecil selisih, JsToPhp perlu memahami lebih banyak bentuk (inferensi tipe parameter, penurunan await / yield*) atau mengeluarkan opcode opcache secara langsung, bukan melalui eval(). Lihat Tolok ukur § Peta jalan.

Konkurensi multi-agen

Model SharedArrayBuffer + Atomics.wait + postMessage milik JavaScript mengasumsikan host dapat menjalankan thread OS sungguhan. PHP tidak bisa (tanpa pcntl_fork, yang tidak tersedia di setiap host).

Phasis menyimulasikan satu agen — Atomics.wait langsung mengembalikan "not-equal" atau "timed-out", notify selalu mengembalikan 0. Ini lolos setiap pengujian test262 yang berjalan dengan satu agen (validasi input, jalur error, notify tanpa operasi), mencakup 376 dari 376 pengujian Atomics.

Pengujian yang benar-benar memerlukan dua agen bersamaan untuk saling mengamati tidak didukung. Gunakan antrean worker di tingkat PHP (Redis, Beanstalkd, …) untuk paralelisme sungguhan.

Semantik realm

ShadowRealm telah diimplementasikan, tetapi setiap realm anak berjalan dalam proses PHP yang sama dengan host. Fungsi host dapat membocorkan referensi antar-realm kecuali Anda berhati-hati menjaga kode PHP tetap terisolasi. Spesifikasi mengizinkan hal ini; V8 menerapkan isolasi yang lebih ketat melalui instance v8::Isolate terpisah.

createRealm() (hook host test262) membuat Phasis\Engine baru secara internal dan menjembatani pustaka standar.

Pilihan engine regex

Phasis menggunakan PCRE2 milik PHP sebagai backend regex utama, dengan matcher khusus untuk kasus yang tidak dapat ditangani PCRE2 secara persis (lookbehind dengan capture, grup terkuantifikasi dengan reset, semantik flag /v tertentu). Matcher khusus ini lebih lambat daripada PCRE2 dan hanya digunakan saat dispatch mendeteksi pola yang tidak kompatibel.

Konsekuensi penting: tabel pelipatan huruf besar-kecil PCRE2 mungkin berbeda dari versi ICU milik V8, terutama pada distro Linux yang lebih lama (Ubuntu 22.04 menyertakan ICU 70; Phasis menyertakan tabel pelipatan ICU 76+ untuk mengatasi perbedaan host pada pola /iu).

Model memori

GC penghitungan referensi milik PHP berbeda dari pengumpul tracing milik V8. Objek PHP yang ditangkap oleh closure host tetap hidup selama engine menyimpan closure tersebut, dan siklus di antara objek-objek itu tidak dikumpulkan sampai Engine dihancurkan. Gunakan WeakMap / WeakRef untuk cache yang tidak ingin Anda pertahankan tetap hidup.

API introspeksi khusus process.memoryUsage() dan V8 sejenisnya tidak diimplementasikan.

Pemuat modul

Pemuat modul ES menyelesaikan impor relatif berdasarkan sistem file, tetapi tidak memahami konvensi bundler:

  • Tidak ada resolusi node_modules.
  • Tidak ada peta package.json exports.
  • Tidak ada inferensi ekstensi file (Anda harus menulis import './foo.mjs', bukan import './foo').
  • Tidak ada impor HTTP.

Ini sesuai dengan spesifikasi ECMAScript dasar, tetapi tidak dengan perilaku Node. Tidak ada hook untuk resolver modul kustom. Untuk menggunakan paket npm, bundel paket tersebut dengan alat seperti esbuild menjadi satu skrip atau modul sebelum meneruskannya ke Phasis.

Wasm

WebAssembly tidak diimplementasikan. Tidak ada runtime wasm PHP untuk dihubungkan.

Web API khusus browser yang kami lewati

Phasis menyertakan seluruh Paket Platform Web (URL, TextEncoder/TextDecoder, atob/btoa, structuredClone, performance, DOMException), seluruh Paket Fetch (fetch, Request, Response, Headers, Body, AbortController/AbortSignal, Blob/File, FormData, EventTarget/Event, WHATWG Streams lengkap, navigator), ditambah crypto (getRandomValues, randomUUID, SubtleCrypto lengkap: digest, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2), WebSocket (konstruktor + codec frame RFC 6455, transport yang dapat diganti), XMLHttpRequest (berlapis di atas transport fetch), dan event loop sungguhan (setTimeout, setInterval, clearTimeout, clearInterval, queueMicrotask, AsyncContext). Lihat API Web.

Yang tidak disertakan:

  • window, document, pohon DOM — Phasis bukan browser.
  • localStorage, sessionStorage, IndexedDB — hal-hal di sisi host; embedder yang mengelola persistensi.
  • Worker, SharedWorker, MessageChannel — memerlukan thread OS sungguhan, yang tidak disediakan PHP.
  • Service Workers, Push API, Notifications, BroadcastChannel — tidak relevan di luar browser.

Global Node

process, Buffer, __dirname, __filename, require() — semua ini juga tidak ada. Semuanya adalah konvensi host Node, bukan fitur bahasa.

Jika Anda memindahkan kode Node, ganti require('foo') dengan import 'foo', tukar process.env.X dengan env.X yang terikat ke host, dan teruskan jalur yang setara dengan __dirname dari PHP.

Presisi desimal

Angka ECMAScript adalah double IEEE 754. Aritmetika desimal dengan lebih dari 15 digit signifikan kehilangan presisi seperti pada setiap engine JS lainnya. Gunakan BigInt untuk matematika bilangan bulat eksak atau gunakan pustaka desimal JS jika Anda memerlukan matematika pecahan yang eksak.

PHP menggunakan bcmath secara internal untuk BigInt; satu-satunya perbedaan nyata dibandingkan V8 adalah operasi bigint yang sangat besar lebih lambat di PHP daripada di implementasi C++ milik V8. Ketepatan numeriknya identik.