Známe obmedzenia
Phasis sa usiluje správať rovnako ako V8 pri každom pozorovateľnom teste špecifikácie. Táto stránka uvádza miesta, kde sa táto zhoda v praxi končí — zvyčajne pre zásadné rozdiely medzi interpretom PHP s prechádzaním stromu a enginom v C++, ktorý kód kompiluje pomocou JIT.
Výkonnostný strop
Engine prechádza strom, používa opportunistický VM s bajtovým kódom a transpiler JsToPhp, ktorý prevádza telá funkcií s prevažne číselnými operáciami a lokálnymi premennými (vrátane tvarov obj.method(), new Ctor() a this.member) na natívne uzávery PHP, ktoré môže trasovací JIT v PHP 8.5 skompilovať do strojového kódu. Väčšina horúcich operácií spracovania prebieha v cykle switch VM alebo priamo v kóde PHP skompilovanom JIT-om, nie prechádzaním AST. Každý operačný kód VM však stále platí daň za PHP dispatch a každý tvar, ktorý JsToPhp zatiaľ nepodporuje, sa vracia k pomalšej VM. Strop pri úlohách obmedzených rýchlosťou dispatchu je približne 100× pomalší než V8.
Pri úlohách s vloženým enginom — spúšťaní logiky dodanej používateľom nad údajmi PHP, transformačných postupoch pre obsah či validačných pravidlách — na tomto strope zriedka záleží. V8 trvá 100 ms; Phasis trvá 10 s; oboje je výrazne pod časovým limitom požiadavky. Zmenšenie rozdielu by si vyžadovalo naučiť JsToPhp ďalšie tvary (odvodzovanie typov parametrov, prevod await / yield*) alebo generovať opkódy opcache priamo namiesto sprostredkovania cez eval(). Pozrite si Benchmarky § Plán rozvoja.
Súbežnosť viacerých agentov
Model JavaScript SharedArrayBuffer + Atomics.wait + postMessage predpokladá, že hostiteľ dokáže spúšťať skutočné vlákna operačného systému. PHP to nedokáže bez pcntl_fork, ktoré nie je dostupné na každom hostiteľovi.
Phasis simuluje jediného agenta — Atomics.wait okamžite vráti „not-equal“ alebo „timed-out“, notify vždy vráti 0. Tým prejdú všetky testy test262 pre jedného agenta (overenie vstupov, chybové prípady, prázdna operácia notify), čo pokrýva 376 z 376 testov Atomics.
Testy, ktoré skutočne vyžadujú, aby sa dva súbežné agenty navzájom pozorovali, nie sú podporované. Na skutočný paralelizmus použite front pracovníkov na úrovni PHP (Redis, Beanstalkd, …).
Sémantika realmov
ShadowRealm je implementovaný, ale každý podriadený realm beží v tom istom procese PHP ako hostiteľ. Hostiteľské funkcie môžu prenášať referencie medzi realmovými prostrediami, ak nezabezpečíte izoláciu kódu PHP. Špecifikácia to povoľuje; V8 vynucuje prísnejšiu izoláciu pomocou samostatných inštancií v8::Isolate.
createRealm() (hostiteľský hák test262) vytvorí interne nový Phasis\Engine a prepojí štandardnú knižnicu.
Výber regex enginu
Phasis používa PCRE2 od PHP ako hlavný backend pre regulárne výrazy a vlastný porovnávač pre prípady, ktoré PCRE2 nedokáže spracovať presne (lookbehind so zachytávaním, kvantifikované skupiny s resetom, určitá sémantika príznaku /v). Vlastný porovnávač je pomalší než PCRE2 a použije sa iba vtedy, keď dispečer zistí nekompatibilný vzor.
Dôležitý dôsledok: tabuľka skladania veľkosti písmen v PCRE2 sa môže líšiť od verzie ICU v V8, najmä v starších distribúciách Linux (Ubuntu 22.04 obsahuje ICU 70; Phasis dodáva tabuľku skladania ICU 76+, ktorá prepisuje rozdiely hostiteľa pri vzoroch /iu).
Model pamäte
Počítanie referencií v GC PHP sa líši od trasovacieho zberača V8. Objekty PHP zachytené hostiteľskými uzávermi zostávajú nažive, kým engine uchováva tieto uzávery; cykly medzi nimi sa uvoľnia až po zničení Engine. Pre vyrovnávacie pamäte, ktoré nemajú objekty udržiavať nažive, použite WeakMap / WeakRef.
process.memoryUsage() ani podobné introspekčné API špecifické pre V8 nie sú implementované.
Načítavač modulov
Načítavač modulov ES rieši relatívne importy podľa súborového systému, nerozumie však konvenciám nástrojov na zostavovanie balíkov:
- Bez rozlišovania balíkov
node_modules. - Bez mapy
package.jsonexports. - Bez odvodzovania prípony súboru (musíte napísať
import './foo.mjs', nieimport './foo'). - Bez importov HTTP.
Zodpovedá to čistej špecifikácii ECMAScriptu, nie však správaniu Node. Vlastný resolver modulov nemožno pripojiť. Ak chcete používať balíky npm, pred odovzdaním do Phasis ich zabaľte nástrojom, ako je esbuild, do jedného skriptu alebo modulu.
Wasm
WebAssembly nie je implementované. Nie je k dispozícii runtime PHP wasm, na ktorý by sa dalo naviazať.
Webové API dostupné iba v prehliadači, ktoré vynechávame
Phasis obsahuje celý Web Platform Pack (URL, TextEncoder/TextDecoder, atob/btoa, structuredClone, performance, DOMException), celý Fetch Pack (fetch, Request, Response, Headers, Body, AbortController/AbortSignal, Blob/File, FormData, EventTarget/Event, úplné WHATWG Streams, navigator), ďalej crypto (getRandomValues, randomUUID, celé SubtleCrypto: digest, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2), WebSocket (konštruktor a kodek rámcov RFC 6455 s vymeniteľným prenosom), XMLHttpRequest (postavený na prenose fetch) a skutočnú slučku udalostí (setTimeout, setInterval, clearTimeout, clearInterval, queueMicrotask, AsyncContext). Pozrite si Webové API.
Čo sa nedodáva:
window,document, strom DOM — Phasis nie je prehliadač.localStorage,sessionStorage,IndexedDB— záležitosti hostiteľa; za ukladanie zodpovedá integrátor.Worker,SharedWorker,MessageChannel— vyžadujú skutočné vlákna OS, ktoré PHP neposkytuje.- Service Workers, Push API, Notifications, BroadcastChannel — mimo prehliadača nemajú význam.
Globálne objekty Node
process, Buffer, __dirname, __filename, require() — neexistuje ani jeden z nich. Ide o konvencie hostiteľa Node, nie o funkcie jazyka.
Ak prenášate kód Node, nahraďte require('foo') za import 'foo', process.env.X vymeňte za env.X naviazaný na hostiteľa a cesty zodpovedajúce __dirname odovzdajte z PHP.
Desatinná presnosť
Čísla ECMAScriptu sú 64-bitové hodnoty s pohyblivou rádovou čiarkou podľa IEEE 754. Desiatková aritmetika s viac než 15 platnými číslicami stráca presnosť rovnako ako v každom inom engine JS. Na presnú celočíselnú aritmetiku použite BigInt alebo na presné zlomkové výpočty použite desatinnú knižnicu JS.
PHP používa interne bcmath pre BigInt; jediným skutočným rozdielom oproti V8 je pomalšie vykonávanie veľmi veľkých operácií bigint v PHP než v implementácii V8 v C++. Číselná správnosť je rovnaká.