
# Znane omejitve

Phasis si prizadeva, da bi se pri vseh opazljivih testih specifikacije vedel enako kot V8. Ta stran opisuje primere, kjer se ta enakost v praksi konča — običajno zaradi temeljnih razlik med tolmačem PHP, ki obhaja drevo, in pogonom C++, prevedenim z JIT.

## Omejitve zmogljivosti

Pogon uporablja obhod drevesa, priložnostni VM za bajtno kodo in transpajler JsToPhp, ki telesa z veliko števili ali lokalnimi spremenljivkami (vključno z oblikami `obj.method()`, `new Ctor()` in `this.member`) prevede v izvorna zaprtja PHP, ki jih lahko JIT sledenja v različici PHP 8.5 prevede v strojno kodo. Večina pogostih odpremljanj poteka znotraj zanke switch VM ali neposredno v kodi PHP, prevedeni z JIT — ne z obhodom AST — vendar vsaka operacija VM še vedno plača strošek odpremljanja PHP, vsaka oblika, ki je JsToPhp še ne podpira, pa preide na počasnejši VM. Zgornja meja za delovne obremenitve, omejene z odpremljanjem, je približno **100× počasnejša kot V8**.

Pri vgradnih delovnih obremenitvah — izvajanju logike, ki jo posreduje uporabnik, nad podatki PHP, cevovodih za pretvorbo vsebine in pravilih za preverjanje veljavnosti — ta omejitev redko vpliva. V8 traja 100 ms; Phasis traja 10 s; oboje je precej pod časovno omejitvijo zahteve. Za dodatno zmanjšanje razlike bi bilo treba JsToPhp naučiti podpirati več oblik (sklepanje o vrstah parametrov, prevajanje `await` / `yield*`) ali neposredno ustvarjati ukaze opcache namesto prek `eval()`. Glejte [Merila zmogljivosti § Načrt](https://phasis.inline0.dev/sl/docs/advanced/benchmarks#roadmap).

## Sočasnost več agentov

Model JavaScript `SharedArrayBuffer` + `Atomics.wait` + `postMessage` predpostavlja, da lahko gostitelj izvaja prave niti operacijskega sistema. PHP tega ne zmore (brez `pcntl_fork`, ki ni na voljo v vseh gostiteljih).

Phasis simulira enega agenta — `Atomics.wait` takoj vrne »not-equal« ali »timed-out«, `notify` pa vedno vrne 0. S tem uspejo vsi testi test262, ki se izvajajo z enim agentom (preverjanje vhodnih podatkov, poti napak, prazno notify); to zajema 376 testov Atomics od skupno 376.

Testi, ki zahtevajo, da se dva sočasna agenta medsebojno opazujeta, niso podprti. Za pravo vzporednost uporabite čakalno vrsto za delovne procese na ravni PHP (Redis, Beanstalkd, …).

## Semantika okolij

`ShadowRealm` je implementiran, vendar se vsako podrejeno okolje izvaja v istem procesu PHP kot gostitelj. Funkcije gostitelja lahko prenesejo sklice med okolji, če ne poskrbite, da je koda PHP ustrezno izolirana. Specifikacija to dovoljuje; V8 zagotavlja strožjo izolacijo z ločenimi primerki v8::Isolate.

`createRealm()` (kavelj gostitelja test262) interno ustvari novo okolje `Phasis\Engine` in vanj prenese standardno knjižnico.

## Izbira pogona za regularne izraze

Phasis kot glavno zaledje za regularne izraze uporablja PCRE2, ki je del PHP, za primere, ki jih PCRE2 ne obravnava povsem natančno, pa uporablja lastni ujemalnik (pogled nazaj z zajemi, kvantificirane skupine s ponastavitvijo, določena semantika zastavice `/v`). Lastni ujemalnik je počasnejši od PCRE2 in se uporablja samo, kadar pošiljanje zazna nezdružljiv vzorec.

Pomembna posledica: tabela za pretvorbo velikosti črk v PCRE2 se lahko razlikuje od tabele v različici ICU, ki jo uporablja V8, zlasti v starejših distribucijah Linux (Ubuntu 22.04 vključuje ICU 70; Phasis priloži tabelo za pretvorbo velikosti črk ICU 76+ in tako prepreči odstopanja gostitelja pri vzorcih `/iu`).

## Pomnilniški model

Zbiralnik smeti s štetjem sklicev v PHP se razlikuje od sledilnega zbiralnika v V8. Objekti PHP, ki jih zajamejo zaprtja gostitelja, ostanejo živi, dokler pogon ohranja ta zaprtja; cikli med njimi se ne zberejo, dokler ni uničen `Engine`. Za predpomnilnike, ki jih ne želite ohranjati v pomnilniku, uporabite `WeakMap` / `WeakRef`.

Introspekcijski API-ji `process.memoryUsage()` in podobni API-ji, specifični za V8, niso implementirani.

## Nalagalnik modulov

Nalagalnik modulov ES razreši relativne uvoze glede na datotečni sistem, vendar ne podpira konvencij za povezovalnike paketov:

- Brez razreševanja `node_modules`.
- Brez preslikave `package.json` `exports`.
- Brez sklepanja o končnici datoteke (zapisati morate `import './foo.mjs'`, ne `import './foo'`).
- Brez uvozov HTTP.

To ustreza osnovni specifikaciji ECMAScript, ne pa vedenju Node. Kavelj za lastni razreševalnik modulov ne obstaja. Če želite uporabljati pakete npm, jih z orodjem, kot je esbuild, združite v en skript ali modul, preden ga posredujete Phasis.

## Wasm

`WebAssembly` ni implementiran. Ni izvajalnika wasm PHP, na katerega bi ga bilo mogoče povezati.

## Spletni API-ji, ki so na voljo samo v brskalniku

Phasis vključuje celoten **Web Platform Pack** (`URL`, `TextEncoder`/`TextDecoder`, `atob`/`btoa`, `structuredClone`, `performance`, `DOMException`), celoten **Fetch Pack** (`fetch`, `Request`, `Response`, `Headers`, `Body`, `AbortController`/`AbortSignal`, `Blob`/`File`, `FormData`, `EventTarget`/`Event`, celoten WHATWG Streams, `navigator`), poleg tega še `crypto` (`getRandomValues`, `randomUUID`, celoten `SubtleCrypto`: digest, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2), `WebSocket` (konstruktor + kodirnik okvirjev RFC 6455, zamenljiv prenosni sloj), `XMLHttpRequest` (zgrajen na prenosnem sloju fetch) in pravo zanko dogodkov (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `queueMicrotask`, `AsyncContext`). Glejte [Spletni API-ji](https://phasis.inline0.dev/sl/docs/compatibility/web-apis).

Česa ne vključuje:

- `window`, `document` in drevesa DOM — Phasis ni brskalnik.
- `localStorage`, `sessionStorage`, `IndexedDB` — zadevajo gostiteljsko okolje; vgrajevalnik skrbi za trajno shranjevanje.
- `Worker`, `SharedWorker`, `MessageChannel` — zahtevajo prave niti operacijskega sistema, ki jih PHP ne ponuja.
- Service Workers, Push API, Notifications, BroadcastChannel — zunaj brskalnika niso uporabni.

## Globalni objekti Node

`process`, `Buffer`, `__dirname`, `__filename`, `require()` — nič od tega ni na voljo. Gre za konvencije gostiteljskega okolja Node, ne za jezikovne funkcije.

Če prenašate kodo Node, zamenjajte `require('foo')` z `import 'foo'`, `process.env.X` nadomestite z `env.X`, vezanim na gostitelja, in v PHP posredujte poti, enakovredne `__dirname`.

## Decimalna natančnost

Števila ECMAScript so 64-bitna števila z dvojno natančnostjo IEEE 754. Decimalna aritmetika z več kot 15 pomembnimi števkami izgubi natančnost, enako kot v vsakem drugem pogonu JS. Za natančno računanje s celimi števili uporabite `BigInt`, za natančno računanje z decimalnimi ulomki pa knjižnico za decimalna števila JS.

PHP interno uporablja `bcmath` za `BigInt`; edina prava razlika v primerjavi z V8 je počasnejše izvajanje zelo velikih operacij bigint v PHP kot v implementaciji C++ v V8. Številska pravilnost je enaka.
