Do hlubin implementací JavaScriptu: 4. díl – implementace v prohlížečích

Dnešním dílem opouštíme teorii a začínáme se věnovat konkrétním implementacím JavaScriptu. Dnes stručně projdeme ty, které jsou k nalezení uvnitř webových prohlížečů Internet Explorer, Firefox, Safari, Opera, Google Chrome a několika dalších. Ukážeme si, co je pro ně charakteristické.

Seriál: Do hlubin implementací JavaScriptu (14 dílů)

  1. Do hlubin implementací JavaScriptu: 1. díl – úvod 30.10.2008
  2. Do hlubin implementací JavaScriptu: 2. díl – dynamičnost a výkon 6.11.2008
  3. Do hlubin implementací JavaScriptu: 3. díl – výkonnostně nepříjemné konstrukce 13.11.2008
  4. Do hlubin implementací JavaScriptu: 4. díl – implementace v prohlížečích 20.11.2008
  5. Do hlubin implementací JavaScriptu: 5. díl – implementace mimo prohlížeče 27.11.2008
  6. SquirrelFish: reprezentace hodnot JavaScriptu a virtuální stroj 4.12.2008
  7. SquirrelFish: optimalizace vykonávání instrukcí a nativní kód 11.12.2008
  8. SquirrelFish: regulární výrazy, vlastnosti objektů a budoucnost 18.12.2008
  9. SpiderMonkey: zpracování JavaScriptu ve Firefoxu 8.1.2009
  10. SpiderMonkey: rychlá kompilace JavaScriptu do nativního kódu 15.1.2009
  11. V8: JavaScript uvnitř Google Chrome 22.1.2009
  12. Rhino: na rozhraní JavaScriptu a Javy 29.1.2009
  13. Velký test rychlosti JavaScriptu v prohlížečích 5.2.2009
  14. Javascriptové novinky: souboj o nejrychlejší engine pokračuje 19.3.2009

Implementací JavaScriptu je velké množství – jde o jeden z nejimplemen­tovanějších mainstreamových programovacích jazyků dneška. Cílem tohoto a následujícího dílu bude podstatnou část z těchto implementací stručně přiblížit. Dnes se zaměříme na implementace uvnitř webových prohlížečů, a to jak těch známých, tak relativně neznámých.

Vztah implementací JavaScriptu a prohlížečů není 1:1 – jedna implementace je totiž často sdílena více prohlížeči, které jsou odvozeny ze stejného renderovacího jádra (např. Firefox a Camino, které jsou oba založeny na Gecku). Ani použité jádro ale neurčuje javascriptový engine jednoznačně – viz třeba Google Chrome, který sice používá WebKit, ale jeho interpret JavaScriptu nahrazuje vlastním enginem V8. V přehledu proto budeme (až na sekci „Další prohlížeče“) používat přímo názvy javascriptových implementací a pro srozumitelnost bude vždy v závorce uveden nejpoužívanější prohlížeč, který danou implementaci využívá. Jednotlivé implementace projdeme v pořadí, které přibližně odpovídá podílu těchto prohlížečů na trhu.

Výčet implementací používaných prohlížeči by dle mých znalostí měl být úplný. Je ale docela možné, že jsem některou implementaci přehlédl – přece jen, svět prohlížečů a JavaScriptu je velmi bohatý. Pokud se tak stalo, budu rád, když mě doplníte v komentářích.

Všechny níže uvedené implementace jsou napsány v jazyce C nebo C++.

JScript (Internet Explorer)

Microsoftí prohlížeč implementuje dialekt JavaScriptu zvaný JScript, který se od JavaScriptu liší jen v drobnostech (pokud nepočítáme různá rozšíření jako třeba podmíněnou kompilaci). Tomu se není co divit – JScript vznikl jako reakce na JavaScript v Netscape Navigatoru 2.0 a snahou Microsoftu byla maximální kompatibilita s tehdy dominantním prohlížečem.

Technicky je javascriptové jádro Internet Exploreru od prohlížeče úplně odděleno – jedná se o samostatnou DLL knihovnu. Internet Explorer totiž implementuje architekturu jazykových pluginů, díky čemuž je po dodání potřebné knihovny možné ve stránkách používat prakticky libovolný skriptovací jazyk. Microsoft sám toho využívá u VBScriptu. Zvolená architektura umožňuje také použití implementace jazyka mimo prohlížeč – JScript i VBcript se tak využívají například ke skriptování Windows nebo na serverech v rámci technologie ASP.

O implementaci samotné toho není mnoho známo, což je důsledek uzavřenosti jejího kódu a toho, že Microsoft (pokud vím) nikde nezveřejnil žádně podrobnější informace. Dojem si tak lze utvořit jen z vnějších projevů, z nichž některé nejsou příliš pozitivní – třeba sklony Internet Exploreru k memory leakům při manipulaci s objekty DOM (což je ale spíš vlastnost propojení implementace s prohlížečem) a nepříliš oslňující rychlost zpracování skriptů.

SpiderMonkey (Firefox)

SpiderMonkey vychází z kódu používaného v Netscape Navigatoru, je tedy přímým potomkem úplně první implementace JavaScriptu. Stejně jako zbytek kódu Navigatoru byl v roce 1998 zveřejněn jako open source a nyní je k dispozici pod trojlicencí MPL/GPL/LGPL.

Za vývojem tohoto enginu stojí tvůrce JavaScriptu Brendan Eich. I díky tomu je SpiderMonkey jednou z nejinovativ­nějších implementací JavaScriptu – zatímco většina implementací je většinou co do funkcí na úrovni JavaScriptu verze 1.3 (přibližně odpovídá třetí edici normy ECMA-262) či 1.5, SpiderMonkey přidává např. podporu E4X a mnoha dalších užitečných vlastností.

SpiderMonkey donedávna fungoval jako čistý bajtkódový interpret, ale tlak konkurence způsobil, že současné vývojové verze zvládají i částečnou kompilaci do nativního kódu – zatím na platformě x86 (více o způsobech implementace interpretů viz minulý díl.

Příjemnou vlastností SpiderMonkey je jeho embeddabilita – bohaté a dobře navržené API umožňuje snadné použití JavaScriptu jako skriptovacího jazyka pro aplikace napsané v C/C++. Toho využila například firma Adobe pro svou implementaci JavaScriptu v produktech Adobe Acrobat a Adobe Reader. Projekt Wine zas využívá části SpiderMonkey ve své emulaci JScriptu.

V některém z příštích dílů se na SpiderMonkey podíváme podrobněji. Nedočkavci najdou dokumentaci SpiderMonkey včetně popisu API a pohledu pod kapotu na vývojářském wiki Mozilly.

KJS/JavaScrip­tCore/Squirrel­Fish/Squirrel­Fish Extreme (Safari)

Když Apple začínal s vývojem prohlížeče Safari, použil již existující jádro KHTML prohlížeče Konqueror. Zároveň s tím převzal i jeho implementaci JavaScriptu – KJS. Z KHTML se v rukou Apple stal WebKit a z KJS JavaScriptCore.

Původní implementace byla založená na procházení AST a tedy v principu relativně pomalá. Byť vývojáři provedli mnoho optimalizací, které interpret podstatně urychlily, nakonec se nevyhnuli jeho přepsání na generátor bajtkódu a virtuální stroj. Výsledný engine nazvali SquirrelFish a představili ho v červnu letošního roku.

SquirrelFish a s ním související zrychlení bylo jedním z důvodů, který přiměl vývojáře SpiderMonkey zabývat se kompilací do nativního kódu. Poté, co představili verzi svého interpretu, která to umožňovala, zareagoval vývojový tým WebKitu oznámením SquirrelFish Extreme. Tato verze interpretu umí na platformně x86 generovat nativní kód a oproti předchozí verzi obsahuje další optimalizace.

SquirrelFish je v současnosti jedna z nejaktivněji se vyvíjejících implementací. Vzhledem k tomu, že je také open source a je o ní dostupných poměrně hodně informací, budeme se jí ještě věnovat.

linear_b/futhark (Opera)

Podivně znějící slova v nadpisu jsou opravdu názvy implementací JavaScriptu používaných v Opeře. Engine linear_b se používal ve verzích 7.0–9.27, od verze 9.50 se používá zbrusu nový interpret futhark, se kterým se počítá i v Opeře 10.

Bohužel při hledání informací o futharku jsem zjistil jediné: že futhark je germánské runové písmo. Jestli jím lze zapisovat JavaScript, není známo…

Čtenářům tedy můžu nabídnou jen srovnání obou interpretů pomocí benchmarku SunSpider. Plyne z něj, že na Windows je JavaScript v Opeře 9.50b (futhark) přibližně 2× rychlejší než v Opeře 9.25 (linear_b). Ve srovnání s implementacemi v dalších prohlížečích je futhark přibližně stejně rychlý.

V8 (Google Chrome)

Když Google před dvěma lety začínal vyvíjet svůj prohlížeč, rozhodl se v něm využít renderovací jádro WebKit, protože bylo dobře napsané, efektivní a snadno upravitelné. Jeho implementace JavaScriptu se ale Googlu nelíbila, čemuž se není co divit, pokud uvážíme závislost aplikací Googlu na tomto jazyce a fakt, že před dvěma lety byl ještě JavaScriptCore implementován pomocí procházení AST. Google se rozhodl napsat implementaci vlastní, a tak se zrodil engine V8.

Cílem V8 je maximálně urychlit spouštění JavaScriptu. Dosahuje toho především kombinací kompilace JavaScriptu do nativního kódu (na rozdíl od ostatních implementací nemá V8 žádný bajtkód a jeho interpret – všechen kód je rovnou kompilován), optimalizacemi přístupu k atributům a metodám objektů a efektivním garbage collectorem.

V8, který je stejně jako celý prohlížeč open source, si v budoucnu popíšeme podrobněji. Pokud nechcete čekat, můžete si přečíst popis designu V8 a nebo zhlédnout přednášku z Google Developer Day 2008 v Praze (video, slajdy).

Další prohlížeče

Ostatní současné prohlížeče používají některou z implementací uvedených výše, vesměs kvůli sdílení renderovacích jáder. Existují ale dvě výjimky: iCab a Links.

iCab

Prohlížeč iCab je určen pro Mac OS a do verzí řady 3.x disponoval vlastním renderovacím jádrem, které podporovalo i dialekt JavaScriptu zvaný InScript (jádro už ale nepodporovalo DOM, takže využití jazyka bylo omezené). Od čtyřkové řady přešel iCab na jádro WebKit.

Bohužel k implementaci InScriptu v iCabu není dostupný zdrojový kód a nepodařilo se mi o ní najít žádné užitečné informace. Tento prohlížeč je tedy ve výčtu spíše pro úplnost.

Links

Jak někteří čtenáři možná vědí, Links je český prohlížeč, jehož vývoj probíhal z velké části v rámci softwarového projektu na MFF UK. Má velmi „zajímavý“ zdrojový kód a jeho autoři mají poněkud svérázný pohled na svět – pro získání lepší představy doporučuji přečíst článek o Linksu na Rootu.

Proč se zde o Linksu zmiňujeme? Protože obsahuje interpret JavaScriptu (byť jen ve verzi 1.1) napsaný na zelené louce. Byť je technicky poměrně jednoduchý (přímo prochází AST), dokumentace k němu je napsaná v češtině a při jejím čtení se nejen poučíte o návrhu interpretu jazyka, ale dost možná se i pobavíte nad některými názory autorů. Na dlouhé (pod)zimní večery tedy doporučuji sekce 7.3 a 8.1 z projektové dokumentace a sekce 4.9–4.13 a 6.4 z vývojové dokumentace (v tomto pořadí).

Jedna úsměvná citace za všechny:

Nepodporujeme atribut prototype, který je u všech objektů. Tento atribut je normou povolen a přidává do objektu nové metody a atributy (případně s danou hodnotou). Tento atribut jsme neimplementovali, protože by byl problém ho implementovat a jsme toho názoru, že je k ničemu.

Citací o nepochopení prototypové dědičnosti dnešní díl uzavíráme a příště se ponoříme do implementací JavaScriptu mimo prohlížeče.

Autor je vývojář se zájmem o programovací jazyky, webové aplikace a problémy programování jako takového. Vystudoval informatiku na MFF UK a během studií zde i trochu učil. Aktuálně pracuje v SUSE.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 11

Přehled komentářů

Dlouhán Lobo Browser
David Majda Re: Lobo Browser
Radek Super
Jaga Re: Super
jachhym links
Jaga Re: links vyvijí se?
BLEK. Re: links vyvijí se?
Anonymní RE: Do hlubin implementací JavaScriptu: 4. díl - implementace v prohlížečích
Jakub RE: Do hlubin implementací JavaScriptu: 4. díl - implementace v prohlížečích
Kvakor RE: Do hlubin implementací JavaScriptu: 4. díl - implementace v prohlížečích
jos RE: Do hlubin implementací JavaScriptu: 4. díl - implementace v prohlížečích
Zdroj: https://www.zdrojak.cz/?p=2874