
# Ismert korlátok

Az Phasis célja, hogy minden megfigyelhető specifikációs tesztben azonosan viselkedjen az V8 motorral. Ez az oldal azokat a pontokat sorolja fel, ahol a gyakorlatban megszűnik ez az azonosság — jellemzően a faalapú PHP értelmező és a JIT-fordítású C++ motor alapvető különbségei miatt.

## Teljesítménykorlát

A motor faalapú értelmezőt, alkalomszerűen használt bytecode VM-et és JsToPhp transzpílert alkalmaz, amely a számításigényes, illetve sok lokális változót használó függvénytörzseket (köztük a `obj.method()`, `new Ctor()` és `this.member` alakzatokat) natív PHP lezárásokká alakítja, amelyeket a PHP 8.5 nyomkövető JIT-je gépi kóddá fordíthat. A legtöbb forró diszpécselés a VM kapcsolóhurkán belül vagy közvetlenül a JIT által fordított PHP kódban zajlik — nem az AST bejárásával —, de minden VM-opkódra jut PHP diszpécselési költség, a JsToPhp által még nem kezelt alakzatok pedig visszaesnek a lassabb VM-re. A diszpécselés által korlátozott munkaterhelések felső határa nagyjából **100× lassabb, mint a V8**.

Beágyazási munkaterheléseknél — például felhasználó által megadott logika futtatásakor PHP adatokon, tartalomátalakítási folyamatokban vagy érvényesítési szabályoknál — a korlát ritkán számít. A V8 ideje 100 ms; a Phasis ideje 10 s; mindkettő jóval a kérések időkorlátja alatt marad. A különbség további csökkentéséhez a JsToPhp-nak több alakzatot kellene kezelnie (paramétertípus-következtetés, `await` / `yield*` alakra hozás), vagy közvetlenül opcache-opkódokat kellene kibocsátania a `eval()` útján történő kibocsátás helyett. Lásd: [Benchmarks § Roadmap](https://phasis.inline0.dev/hu/docs/advanced/benchmarks#roadmap).

## Több ügynök egyidejű futtatása

Az JavaScript `SharedArrayBuffer` + `Atomics.wait` + `postMessage` modellje feltételezi, hogy a host valódi operációsrendszer-szálakat tud futtatni. Az PHP erre nem képes (`pcntl_fork` nélkül, amely nem minden hoston érhető el).

Az Phasis egyetlen ügynököt szimulál — az `Atomics.wait` azonnal „not-equal” vagy „timed-out” értéket ad vissza, az `notify` pedig mindig 0-t. Ez átmegy minden olyan test262 teszten, amely egyetlen ügynököt futtat (bemenet-ellenőrzés, hibautak, üres értesítés), ami az 376 Atomics-tesztek 376 részét fedi le.

A két egyidejű ügynök egymás megfigyelését igénylő teszteket a rendszer nem támogatja. Valódi párhuzamossághoz használjon munkafeldolgozó sort az PHP szintjén (Redis, Beanstalkd, …).

## Realm-szemantika

`ShadowRealm` megvalósult, de minden gyermekrealm ugyanabban a PHP folyamatban fut, mint a gazdagép. A gazdagép függvényei hivatkozásokat szivárogtathatnak át a realmek között, hacsak nem ügyel arra, hogy a PHP kódot elszigetelje. A specifikáció ezt megengedi; a V8 szigorúbb elszigetelést biztosít különálló v8::Isolate-példányokkal.

A `createRealm()` (test262 gazdagépi hook) belsőleg létrehoz egy új `Phasis\Engine`-t, és áthidalja a standard könyvtárat.

## A regexmotor kiválasztása

A Phasis elsődleges regex-háttérmotorként a PHP PCRE2-jét használja, olyan esetekre pedig, amelyeket a PCRE2 nem tud pontosan kezelni, egyéni illesztőt alkalmaz (capture-öket tartalmazó lookbehind, resetet tartalmazó kvantifikált csoportok, bizonyos `/v`-jelzőszemantikák). Az egyéni illesztő lassabb a PCRE2-nél, és csak akkor használja, ha az elosztó inkompatibilis mintát észlel.

Ennek fontos következménye, hogy a PCRE2 esetleg más kis- és nagybetű-összehasonlítási táblát használ, mint a V8 ICU-verziója, különösen régebbi Linux-disztribúciókon (az Ubuntu 22.04-es verziója ICU 70-et szállít; a Phasis egy ICU 76+-os kis- és nagybetű-összehasonlítási táblát csomagol, amely felülírja a gazdagépen tapasztalható eltéréseket a `/iu` mintáinál).

## Memóriamodell

A PHP hivatkozásszámláló GC-je eltér a V8 nyomkövető szemétgyűjtőjétől. A gazdagép lezárásai által rögzített PHP-objektumok addig maradnak életben, amíg a motor megőrzi ezeket a lezárásokat; a köztük lévő ciklusok pedig nem gyűjtődnek be a `Engine` megsemmisítéséig. A nem életben tartandó gyorsítótárakhoz használja a `WeakMap` / `WeakRef` megoldást.

A `process.memoryUsage()` és a hasonló, V8-specifikus introspekciós API-k nincsenek megvalósítva.

## Modultöltő

Az ES-modultöltő a fájlrendszerben oldja fel a relatív importokat, de nem ismeri a csomagolóeszközök konvencióit:

- Nincs `node_modules`-feloldás.
- Nincs `package.json` `exports`-térkép.
- Nincs fájlkiterjesztés-következtetés (a `import './foo.mjs'` formát kell írni, nem a `import './foo'` formát).
- Nincsenek HTTP-importok.

Ez megfelel a csupasz ECMAScript-specifikációnak, de nem a Node viselkedésének. Nincs hook egyéni modulfeloldóhoz. npm-csomagok használatához csomagolja őket egy eszközzel, például az esbuilddel, egyetlen szkriptbe vagy modulba, mielőtt átadja a Phasis-nek.

## Wasm

A `WebAssembly` nincs megvalósítva. Nincs hozzá kapcsolható PHP wasm-futtatókörnyezet.

## Kihagyott, csak böngészőben elérhető Web API-k

A Phasis a teljes **Web Platform Pack** csomagot szállítja (`URL`, `TextEncoder`/`TextDecoder`, `atob`/`btoa`, `structuredClone`, `performance`, `DOMException`), a teljes **Fetch Pack** csomagot (`fetch`, `Request`, `Response`, `Headers`, `Body`, `AbortController`/`AbortSignal`, `Blob`/`File`, `FormData`, `EventTarget`/`Event`, a teljes WHATWG Streams csomagot, `navigator`), továbbá a `crypto` csomagot (`getRandomValues`, `randomUUID`, teljes `SubtleCrypto`: digest, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2), a `WebSocket` csomagot (konstruktor + RFC 6455-keretkódoló, cserélhető transzport), a `XMLHttpRequest` csomagot (a fetch-transzportra építve), valamint egy valódi eseményhurkot (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `queueMicrotask`, `AsyncContext`). Lásd: [Web API-k](https://phasis.inline0.dev/hu/docs/compatibility/web-apis).

Amit *nem* szállít:

- `window`, `document` és a DOM-fa — a Phasis nem böngésző.
- `localStorage`, `sessionStorage`, `IndexedDB` — gazdagépoldali feladatok; az állandó tárolásról a beágyazó gondoskodik.
- `Worker`, `SharedWorker`, `MessageChannel` — valódi operációsrendszer-szálakat igényelnek, amelyeket a PHP nem kínál.
- Service Workers, Push API, értesítések, BroadcastChannel — böngészőn kívül irrelevánsak.

## Node globális változói

A `process`, `Buffer`, `__dirname`, `__filename`, `require()` sem létezik. Ezek a Node gazdagépi konvenciói, nem a nyelv részei.

Ha Node-kódot portol, cserélje le a `require('foo')`-t erre: `import 'foo'`; a `process.env.X` helyett használjon gazdagéphez kötött `env.X`-t; és adja át a `__dirname`-nek megfelelő útvonalakat a PHP-ből.

## Tizedes pontosság

Az ECMAScript-számok IEEE 754 típusú dupla pontosságú lebegőpontos számok. A 15-nél több értékes jegyet tartalmazó decimális műveletek ugyanúgy veszítenek a pontosságukból, mint bármely más JS-motorban. Pontos egész számokkal végzett matematikához használja a `BigInt`-t, pontos törtszámításokhoz pedig egy JS decimális könyvtárat.

A PHP `bcmath`-ja belsőleg a `BigInt` céljára szolgál; a V8-hez képest az egyetlen valódi különbség, hogy a nagyon nagy bigint-műveletek lassabbak a PHP-ban, mint a V8 C++-implementációjában. A numerikus helyesség azonos.
