
# Kända begränsningar

Phasis strävar efter att bete sig identiskt med V8 i alla observerbara specifikationstester. Den här sidan beskriver var identiteten upphör i praktiken — vanligtvis på grund av grundläggande skillnader mellan en PHP-tolk som går igenom trädet och en JIT-kompilerad C++-motor.

## Prestandatak

Motorn går igenom syntaxträdet med en opportunistisk bytekod-VM och en JsToPhp-transpilerare som sänker numeriktunga kroppar och kroppar med många lokala variabler (inklusive formerna `obj.method()`, `new Ctor()` och `this.member`) till inbyggda PHP-closures som PHP 8.5:s spårande JIT kan kompilera till maskinkod. Större delen av den aktiva exekveringen sker i VM:ens switch-loop eller direkt i JIT-kompilerad PHP — inte genom att syntaxträdet gås igenom — men varje VM-opkod medför fortfarande en dispatchkostnad för PHP, och former som JsToPhp ännu inte hanterar faller tillbaka till den långsammare VM:en. Taket för arbetsbelastningar som begränsas av dispatch är ungefär **~100× långsammare än V8**.

För inbäddningsfall — att köra användartillhandahållen logik på PHP-data, innehållsomvandlingspipelines och valideringsregler — spelar taket sällan någon roll. V8 är 100 ms; Phasis är 10 s; båda ligger långt under tidsgränsen för begäran. För att minska återstående skillnad behöver JsToPhp lära sig fler former (inferens av parametertyper, sänkning av `await` / `yield*`) eller generera opkoder för opcache direkt i stället för via `eval()`. Se [Benchmarks § Roadmap](https://phasis.inline0.dev/sv/docs/advanced/benchmarks#roadmap).

## Samtidighet mellan flera agenter

JavaScripts modell med `SharedArrayBuffer` + `Atomics.wait` + `postMessage` förutsätter att värden kan köra riktiga OS-trådar. PHP kan inte det utan `pcntl_fork`, som inte finns på alla värdar.

Phasis simulerar en enda agent — `Atomics.wait` returnerar omedelbart "not-equal" eller "timed-out", och `notify` returnerar alltid 0. Det klarar alla test262-tester som körs med en enda agent (indatavalidering, felvägar, no-op notify), vilket omfattar 376 av 376-testerna för Atomics.

Tester som faktiskt kräver att två samtidiga agenter observerar varandra stöds inte. Använd en arbetskö på PHP-nivå (Redis, Beanstalkd, …) för verklig parallellism.

## Realm-semantik

`ShadowRealm` är implementerat, men varje underordnad realm körs i samma PHP-process som värden. Värdfunktioner kan läcka referenser mellan realms om du inte är noga med att hålla PHP-kod isolerad. Specifikationen tillåter detta; V8 upprätthåller striktare isolering genom separata v8::Isolate-instanser.

`createRealm()` (test262-hook för värdmiljön) skapar en ny `Phasis\Engine` internt och kopplar standardbiblioteket över.

## Val av regexmotor

Phasis använder PCRE2 från PHP som primär regexbackend och en anpassad matchare för fall som PCRE2 inte kan hantera exakt (lookbehind med captures, kvantifierade grupper med reset, vissa semantiker för flaggan `/v`). Den anpassade matcharen är långsammare än PCRE2 och används bara när dispatch upptäcker ett inkompatibelt mönster.

En märkbar följd är att PCRE2 kan ha en annan tabell för skiftlägesvikning än ICU-versionen i V8, särskilt i äldre Linux-distributioner (Ubuntu 22.04 levereras med ICU 70; Phasis paketerar en ICU 76+-tabell för skiftlägesvikning som åsidosätter skillnader i värdmiljön för `/iu`-mönster).

## Minnesmodell

PHPs referensräknande GC skiljer sig från den spårande insamlaren i V8. PHP-objekt som fångas av closures i värdmiljön hålls vid liv så länge motorn behåller dessa closures, och cykler mellan dem samlas inte in förrän `Engine` förstörs. Använd `WeakMap` / `WeakRef` för cachar som du inte vill hålla vid liv.

`process.memoryUsage()` och liknande introspektions-API:er som är specifika för V8 är inte implementerade.

## Modulhanterare

ES-modulhanteraren löser relativa importer mot filsystemet men förstår inte bundlarens konventioner:

- Ingen `node_modules`-upplösning.
- Ingen `package.json`-karta för `exports`.
- Ingen inferens av filändelser (du måste skriva `import './foo.mjs'`, inte `import './foo'`).
- Inga HTTP-importer.

Detta följer den rena ECMAScript-specifikationen men inte Nodes beteende. Det finns ingen hook för en anpassad modulresolver. Om du vill använda npm-paket paketerar du dem till ett enda skript eller en enda modul med ett verktyg som esbuild innan du skickar dem till Phasis.

## Wasm

`WebAssembly` är inte implementerat. Det finns ingen PHP-körtid för wasm att koppla till.

## Web-API:er som bara finns i webbläsare och som vi utelämnar

Phasis innehåller hela **Web Platform Pack** (`URL`, `TextEncoder`/`TextDecoder`, `atob`/`btoa`, `structuredClone`, `performance`, `DOMException`), hela **Fetch Pack** (`fetch`, `Request`, `Response`, `Headers`, `Body`, `AbortController`/`AbortSignal`, `Blob`/`File`, `FormData`, `EventTarget`/`Event`, hela WHATWG Streams och `navigator`), samt `crypto` (`getRandomValues`, `randomUUID`, hela `SubtleCrypto`: digest, HMAC, AES-GCM/CBC/CTR, RSA-OAEP/PSS/PKCS1, ECDSA, ECDH, HKDF, PBKDF2), `WebSocket` (konstruktor + RFC 6455-ramkodare, utbytbart transportlager), `XMLHttpRequest` (byggt ovanpå fetch-transporten) och en riktig händelseslinga (`setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `queueMicrotask`, `AsyncContext`). Se [Webb-API:er](https://phasis.inline0.dev/sv/docs/compatibility/web-apis).

Det här ingår *inte*:

- `window`, `document` och DOM-trädet — Phasis är ingen webbläsare.
- `localStorage`, `sessionStorage`, `IndexedDB` — ansvar som ligger hos värdmiljön; den som bäddar in hanterar beständig lagring.
- `Worker`, `SharedWorker`, `MessageChannel` — kräver riktiga OS-trådar, vilket PHP inte erbjuder.
- Service Workers, Push API, aviseringar och BroadcastChannel — irrelevanta utanför en webbläsare.

## Globala objekt i Node

`process`, `Buffer`, `__dirname`, `__filename`, `require()` — inget av detta finns heller. Det är konventioner för Nodes värdmiljö, inte språkfunktioner.

Om du portar Node-kod ersätter du `require('foo')` med `import 'foo'`, byter ut `process.env.X` mot en värdbunden `env.X` och skickar in sökvägar som motsvarar `__dirname` från PHP.

## Decimalprecision

ECMAScript-tal är IEEE 754-dubbelprecisionstal. Decimala beräkningar med fler än 15 signifikanta siffror tappar precision precis som i alla andra JS-motorer. Använd `BigInt` för exakt heltalsmatematik eller ett decimalt bibliotek för JS om du behöver exakta bråktalsberäkningar.

PHPs `bcmath` används internt för `BigInt`; den enda faktiska skillnaden mot V8 är att mycket stora bigint-operationer är långsammare i PHP än i V8s C++-implementation. Den numeriska korrektheten är densamma.
