
# Kendte begrænsninger

Phasis sigter mod at opføre sig identisk med V8 i alle observerbare specifikationstests. Denne side beskriver, hvor denne identitet i praksis ophører — typisk på grund af grundlæggende forskelle mellem en trævandret PHP-fortolker og en JIT-kompileret C++-motor.

## Ydeevneloft

Motoren er en trævandrer med en opportunistisk bytecode-VM og en JsToPhp-transpiler, der omsætter numerisk kode og kode med mange lokale variabler (herunder formerne `obj.method()`, `new Ctor()` og `this.member`) til native PHP-closures, som tracing-JIT'en i PHP 8.5 kan kompilere til maskinkode. Det meste varm dispatch foregår i VM'ens switch-løkke eller direkte i JIT-kompileret PHP — ikke ved at gennemløbe AST'et — men hver VM-opkode koster stadig en PHP-dispatchomkostning, og former, som JsToPhp endnu ikke håndterer, falder tilbage til den langsommere VM. Loftet for dispatchbegrænsede arbejdsbelastninger er cirka **~100× langsommere end V8**.

For indlejringsarbejdsbelastninger — kørsel af brugerleveret logik på PHP-data, indholdstransformationspipelines og valideringsregler — har loftet sjældent betydning. V8 tager 100 ms; Phasis tager 10 s; begge dele ligger langt under anmodningens timeout. Hvis afstanden skal mindskes yderligere, kræver det, at JsToPhp lærer flere former (inferens af parametertyper, omsætning af `await` / `yield*`) eller udsender opcodes til opcache direkte i stedet for via `eval()`. Se [Benchmarks § Roadmap](https://phasis.inline0.dev/da/docs/advanced/benchmarks#roadmap).

## Samtidighed mellem flere agenter

JavaScripts model med `SharedArrayBuffer` + `Atomics.wait` + `postMessage` forudsætter, at værten kan køre rigtige OS-tråde. Det kan PHP ikke (uden `pcntl_fork`, som ikke er tilgængelig på alle værter).

Phasis simulerer én agent — `Atomics.wait` returnerer straks "not-equal" eller "timed-out", og `notify` returnerer altid 0. Det består alle test262-tests, der kører med én agent (inputvalidering, fejlforløb, no-op notify), hvilket dækker 376 af 376 Atomics-tests.

Tests, der kræver, at to samtidige agenter observerer hinanden, understøttes ikke. Brug en worker-kø på PHP-niveau (Redis, Beanstalkd, …) for ægte parallelisme.

## Realm-semantik

`ShadowRealm` er implementeret, men hvert child realm kører i samme PHP-proces som værten. Værtsfunktioner kan lække referencer på tværs af realms, medmindre du sørger for at holde PHP-kode isoleret. Specifikationen tillader dette; V8 håndhæver strengere isolation via separate v8::Isolate-instanser.

`createRealm()` (test262-værtskrog) opretter internt en ny `Phasis\Engine` og bygger bro mellem standardbibliotekerne.

## Valg af regex-motor

Phasis bruger PHPs PCRE2 som primær regex-backend med en tilpasset matcher til tilfælde, som PCRE2 ikke kan håndtere præcist (lookbehind med captures, kvantificerede grupper med nulstilling, visse semantikker for `/v`-flag). Den tilpassede matcher er langsommere end PCRE2 og bruges kun, når dispatch registrerer et inkompatibelt mønster.

Den bemærkelsesværdige konsekvens: PCRE2 kan have en anden case-folding-tabel end V8s ICU-version, især på ældre Linux-distributioner (Ubuntu 22.04 leveres med ICU 70; Phasis medfølger en ICU 76+-foldingstabel, der tilsidesætter forskelle på værtsystemet for `/iu`-mønstre).

## Hukommelsesmodel

PHPs referenceoptællende GC adskiller sig fra V8s sporende garbage collector. PHP-objekter, der indfanges af værtslukninger, forbliver i live, så længe motoren holder fast i disse lukninger, og cyklusser mellem dem indsamles ikke, før `Engine` destrueres. Brug `WeakMap` / `WeakRef` til caches, du ikke vil holde i live.

`process.memoryUsage()` og lignende introspektions-API'er, der er specifikke for V8, er ikke implementeret.

## Modulindlæser

ES-modulindlæseren løser relative imports i forhold til filsystemet, men forstår ikke bundlerkonventioner:

- Ingen løsning af `node_modules`.
- Intet `package.json`-`exports`-kort.
- Ingen automatisk udledning af filtypenavn (du skal skrive `import './foo.mjs'`, ikke `import './foo'`).
- Ingen HTTP-imports.

Det svarer til den rene ECMAScript-specifikation, men ikke til Nodes adfærd. Der findes intet hook til en brugerdefineret modulresolver. Hvis du vil bruge npm-pakker, skal du bundle dem med et værktøj som esbuild til ét script eller modul, før du giver det videre til Phasis.

## Wasm

`WebAssembly` er ikke implementeret. Der findes ingen PHP-wasm-runtime at binde til.

## Web-API'er, der kun findes i browsere, og som vi udelader

Phasis leveres med den fulde **Web Platform Pack** (`URL`, `TextEncoder`/`TextDecoder`, `atob`/`btoa`, `structuredClone`, `performance`, `DOMException`), den fulde **Fetch Pack** (`fetch`, `Request`, `Response`, `Headers`, `Body`, `AbortController`/`AbortSignal`, `Blob`/`File`, `FormData`, `EventTarget`/`Event`, fuld WHATWG Streams, `navigator`), samt `crypto` (`getRandomValues`, `randomUUID`, fuld `SubtleCrypto`: digest, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2), `WebSocket` (constructor + RFC 6455 frame-codec, udskiftelig transport), `XMLHttpRequest` (bygget oven på fetch-transporten) og en ægte event loop (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `queueMicrotask`, `AsyncContext`). Se [Web-API'er](https://phasis.inline0.dev/da/docs/compatibility/web-apis).

Dette følger ikke med:

- `window`, `document`, DOM-træet — Phasis er ikke en browser.
- `localStorage`, `sessionStorage`, `IndexedDB` — forhold på værtsiden; embedderen står for persistens.
- `Worker`, `SharedWorker`, `MessageChannel` — kræver ægte OS-tråde, som PHP ikke tilbyder.
- Service Workers, Push API, Notifications, BroadcastChannel — irrelevante uden for en browser.

## Node-globale variabler

`process`, `Buffer`, `__dirname`, `__filename`, `require()` — ingen af dem findes heller. De er Node-værtskonventioner, ikke sprogegenskaber.

Hvis du porter Node-kode, skal du erstatte `require('foo')` med `import 'foo'`, udskifte `process.env.X` med en `env.X`, der er knyttet til værten, og sende stier svarende til `__dirname` ind fra PHP.

## Decimalpræcision

ECMAScript-tal er IEEE 754-doubles. Decimale beregninger med mere end 15 betydende cifre mister præcision, præcis som i enhver anden JS-motor. Brug `BigInt` til præcis heltalsregning, eller brug et JS-decimalt bibliotek, hvis du har brug for præcise brøkberegninger.

PHPs `bcmath` bruges internt til `BigInt`; den eneste reelle forskel i forhold til V8 er, at meget store bigint-operationer er langsommere i PHP end i V8s C++-implementering. Den numeriske korrekthed er identisk.
