
# Bekende beperkingen

Phasis streeft ernaar zich bij elke waarneembare specificatietest identiek te gedragen aan V8. Op deze pagina staan de situaties waarin die overeenkomst in de praktijk ophoudt — meestal door fundamentele verschillen tussen een tree-walking-PHP-interpreter en een JIT-gecompileerde C++-engine.

## Prestatieplafond

De engine is een tree-walker met een bytecode-VM die waar mogelijk wordt gebruikt en een JsToPhp-transpiler die rekenintensieve en lokale variabelen bevattende code (waaronder patronen als `obj.method()`, `new Ctor()` en `this.member`) omzet in native PHP-closures, die de tracing-JIT van PHP 8.5 kan compileren naar machinecode. De meeste intensieve dispatch vindt plaats binnen de switch-loop van de VM of rechtstreeks in JIT-gecompileerde PHP — niet door de AST te doorlopen — maar elke VM-opcode kost nog steeds extra tijd voor dispatch via PHP, en codepatronen die JsToPhp nog niet ondersteunt, vallen terug op de tragere VM. Bij workloads die vooral door dispatch worden beperkt, ligt het plafond op ongeveer **~100× langzamer dan V8**.

Voor workloads waarbij logica van gebruikers wordt uitgevoerd op PHP-gegevens, zoals inhoudstransformatiepijplijnen en validatieregels, is dit plafond zelden van belang. V8 duurt 100 ms; Phasis duurt 10 s; beide vallen ruim binnen de time-out voor verzoeken. Om het verschil verder te verkleinen, moet JsToPhp meer patronen leren verwerken (inferentie van parametertypen, omzetting van `await` / `yield*`) of rechtstreeks opcache-opcodes genereren in plaats van via `eval()`. Zie [Benchmarks § Roadmap](https://phasis.inline0.dev/nl/docs/advanced/benchmarks#roadmap).

## Gelijktijdigheid van meerdere agents

Het model van JavaScript met `SharedArrayBuffer` + `Atomics.wait` + `postMessage` gaat ervan uit dat de host echte OS-threads kan uitvoeren. PHP kan dat niet (zonder `pcntl_fork`, dat niet op elke host beschikbaar is).

Phasis simuleert één agent — `Atomics.wait` retourneert onmiddellijk "not-equal" of "timed-out" en `notify` retourneert altijd 0. Zo slagen alle test262-tests die met één agent worden uitgevoerd (invoervalidatie, foutpaden, lege notify-aanroep), wat 376 van de 376 Atomics-tests omvat.

Tests waarvoor twee gelijktijdige agents elkaar moeten waarnemen, worden niet ondersteund. Gebruik voor echte parallelle verwerking een workerrij op PHP-niveau (Redis, Beanstalkd, …).

## Realm-semantiek

`ShadowRealm` is geïmplementeerd, maar elke child realm draait in hetzelfde PHP-proces als de host. Hostfuncties kunnen verwijzingen tussen realms laten lekken als je niet zorgvuldig voorkomt dat PHP-code er toegang toe krijgt. De specificatie staat dit toe; V8 dwingt strengere isolatie af met afzonderlijke v8::Isolate-instanties.

`createRealm()` (test262-hosthook) maakt intern een nieuwe `Phasis\Engine` aan en koppelt de standaardbibliotheek hieraan.

## Keuze van regex-engine

Phasis gebruikt PCRE2 van PHP als primaire regex-backend, met een aangepaste matcher voor gevallen die PCRE2 niet exact aankan (lookbehind met captures, gekwantificeerde groepen met reset en bepaalde semantieken van `/v`-vlaggen). De aangepaste matcher is trager dan PCRE2 en wordt alleen gebruikt wanneer de dispatch een incompatibel patroon detecteert.

Het opvallende gevolg: PCRE2 kan een andere tabel voor hoofdletterconversie hebben dan de ICU-versie van V8, vooral op oudere distributies van Linux (Ubuntu 22.04 wordt geleverd met ICU 70; Phasis bevat een conversietabel van ICU 76+ om afwijkingen op de host bij `/iu`-patronen te ondervangen).

## Geheugenmodel

De garbagecollector met referentietelling van PHP verschilt van de tracing garbagecollector van V8. PHP-objecten die door closures van de host worden vastgehouden, blijven bestaan zolang de engine die closures vasthoudt, en cycli ertussen worden pas opgeruimd wanneer `Engine` wordt vernietigd. Gebruik `WeakMap` / `WeakRef` voor caches die u niet in leven wilt houden.

`process.memoryUsage()` en vergelijkbare introspectie-API's die specifiek zijn voor V8 zijn niet geïmplementeerd.

## Modulelader

De ES-modulelader lost relatieve imports op aan de hand van het bestandssysteem, maar begrijpt de conventies van bundlers niet:

- Geen `node_modules`-resolutie.
- Geen `package.json`-`exports`-map.
- Geen afleiding van bestandsextensies (u moet `import './foo.mjs'` schrijven, niet `import './foo'`).
- Geen HTTP-imports.

Dit volgt de kale ECMAScript-specificatie, maar niet het gedrag van Node. Er is geen hook voor een aangepaste module-resolver. Om npm-pakketten te gebruiken, bundelt u ze met een tool zoals esbuild in één script of module voordat u die aan Phasis doorgeeft.

## Wasm

`WebAssembly` is niet geïmplementeerd. Er is geen PHP-runtime voor wasm om aan te koppelen.

## Overgeslagen browser-API's

Phasis bevat het volledige **Web Platform Pack** (`URL`, `TextEncoder`/`TextDecoder`, `atob`/`btoa`, `structuredClone`, `performance`, `DOMException`), het volledige **Fetch Pack** (`fetch`, `Request`, `Response`, `Headers`, `Body`, `AbortController`/`AbortSignal`, `Blob`/`File`, `FormData`, `EventTarget`/`Event`, volledige WHATWG Streams, `navigator`), plus `crypto` (`getRandomValues`, `randomUUID`, volledige `SubtleCrypto`: digest, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2), `WebSocket` (constructor + RFC 6455-framecodec, verwisselbaar transport), `XMLHttpRequest` (gebouwd op het fetch-transport) en een echte eventloop (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `queueMicrotask`, `AsyncContext`). Zie [Web-API's](https://phasis.inline0.dev/nl/docs/compatibility/web-apis).

Wat niet wordt meegeleverd:

- `window`, `document`, de DOM-tree — Phasis is geen browser.
- `localStorage`, `sessionStorage`, `IndexedDB` — zaken aan de hostzijde; de embedder beheert de persistentie.
- `Worker`, `SharedWorker`, `MessageChannel` — hiervoor zijn echte OS-threads nodig, die PHP niet biedt.
- Service Workers, Push API, meldingen, BroadcastChannel — niet relevant buiten een browser.

## Globale variabelen van Node

`process`, `Buffer`, `__dirname`, `__filename`, `require()` — ook deze bestaan niet. Het zijn conventies van de Node-host, geen taalfuncties.

Als u Node-code overzet, vervangt u `require('foo')` door `import 'foo'`, vervangt u `process.env.X` door een aan de host gebonden `env.X` en geeft u equivalente paden aan `__dirname` door vanuit PHP.

## Decimale precisie

ECMAScript-getallen zijn IEEE 754-doubles. Decimale berekeningen met meer dan 15 significante cijfers verliezen precisie, net als in elke andere JS-engine. Gebruik `BigInt` voor exacte berekeningen met gehele getallen of een decimale bibliotheek van JS als u exacte berekeningen met breuken nodig hebt.

De `bcmath` van PHP wordt intern gebruikt voor `BigInt`; het enige echte verschil met V8 is dat zeer grote bigint-bewerkingen trager zijn in PHP dan in de C++-implementatie van V8. De numerieke correctheid is identiek.
