Silnik JavaScript SpiderMonkey stosowany w Firefoxie do wykorzystania zaktualizowanej implementacji wyrażeń regularnych, opartej na aktualnym kodzie z silnika JavaScript V8, stosowanego w przeglądarkach opartych na projekcie Chromium. Nowa implementacja RegExp zostanie zaproponowana w wersji Firefox 78, planowanej na 30 czerwca, i umożliwi implementację wszystkich brakujących elementów ECMAScript związanych z wyrażeniami regularnymi w przeglądarce.
Zauważono, że silnik RegExp w SpiderMonkey jest zorganizowany jako oddzielny komponent, co czyni go stosunkowo niezależnym i łatwym do wymiany bez konieczności wprowadzania znacznych zmian w kodzie. Modularność umożliwiła w 2014 roku zastąpienie pierwotnie stosowanego w Firefoxie silnika RegExp YARR forkíem silnika Irregexp z V8. Irregexp jest zintegrowany z API V8, powiązany z mechanizmem zbierania śmieci, używa specyficznej dla V8 reprezentacji stringów i modelu obiektowego. W trakcie dostosowywania do wewnętrznego API SpiderMonkey w 2014 roku silnik Irregexp został częściowo przepisany, a pojawiające się zmiany, takie jak flaga ‘\u’, w miarę możliwości do odgałęzienia wspieranego przez Mozillę.
Niestety, utrzymanie zsynchronizowanego forka jest trudnym zadaniem i jego wsparcie wymaga dużych zasobów. Wraz z wprowadzeniem nowych możliwości związanych z wyrażeniami regularnymi w standardzie ECMAScript 2018, programiści Mozilli zaczęli myśleć o sposobach uproszczenia przenoszenia zmian z Irregexp. Jako rozwiązanie zaproponowano koncepcję opakowania, która umożliwia wykorzystanie w SpiderMonkey prawie niezmienionego silnika Irregexp (zmiany ograniczają się tylko do automatycznej zamiany bloków «#include»).
Opakowanie dostarcza dla Irregexp niezbędne specyficzne funkcje V8, w tym funkcje zarządzania pamięcią i generowania kodu, a także struktury danych, które są realizowane na podstawie mechanizmów zarządzania pamięcią, generatorów kodu i struktur SpiderMonkey.
Aktualizacja silnika RegExp pozwoli na wsparcie w Firefoxie takich możliwości jak grupy nazwane (named captures), eskaping klas symboli Unicode, flaga dotAll oraz tryb Lookbehind:
- Pozwalają na dopasowanie części ciągu, które są zgodne z wyrażeniem regularnym, do określonych nazw zamiast numerów porządkowych dopasowań (na przykład zamiast „/(\d{4})-(\d{2})-(\d{2})/” można użyć „/(?\d{4})-(?\d{2})-(?\d{2})/” i uzyskać dostęp do roku nie przez result[1], ale przez result.groups.year).
- Unicode-znaków dodaje konstrukcje \p{…} i \P{…}, na przykład \p{Number} definiuje wszystkie możliwe znaki z obrazem cyfr (w tym symbole typu ①), \p{Alphabetic} — litery (łącznie z hieroglifami), \p{Math} — symbole matematyczne itd.
- Flaga powoduje, że maska „.” działa także na znaki nowej linii.
- Tryb pozwala na określenie w wyrażeniu regularnym, że jeden wzór poprzedza inny (na przykład dopasować kwotę w dolarach bez wychwytywania znaku dolara).
Projekt został zrealizowany przy współpracy programistów V8, którzy z kolei podjęli działania w celu zmniejszenia zależności Irregexp od V8 i przenieśli niektóre cechy, które nie mogą być zrealizowane na bazie SpiderMonkey, do wyłączanych bloków „#ifdef”. Współpraca okazała się obustronnie korzystna. Ze swojej strony programiści Mozilli przekazali do Irregexp zmiany, które eliminują niektóre z wymaganiami standardu JavaScript i jakość kodu. Również w trakcie testów fuzzingowych Firefox zidentyfikował i naprawił wcześniej nieodnotowane błędy w kodzie Irregexp, prowadzące do awarii.
Źródło: opennet.ru
