V8 é o interpretador JavaScript, também chamado de máquina virtual Javascript, desenvolvido pela Google e utilizado em seu navegador Google Chrome. Com o peso de seus criadores e a quase onipresença do navegador, foi apenas uma questão de tempo para essa implementação do JavaScritp se tornar dominante no mercado.
Entretanto, um bom desenvolvedor sabe que não existe uma única solução para todos os problemas. Muitas vezes nem mesmo existe uma solução única para um problema bastante específica. Ter a mente aberta para um arsenal de possibilidades e cenários é fundamental para se encontrar respostas para desafios.
Phil Eaton é um desenvolvedor de Queens, Nova York, que está trabalhando em um IDE open source batizado de DataStation. Em um artigo publicado na internet, ele mostra que existem muito mais implementações de JavaScript do que imagina nossa vã filosofia e que não dependem do motor V8.
Com sua autorização, traduzimos e reproduzimos o artigo na íntegra:
“V8 é, tenho certeza, a implementação de JavaScript mais usada atualmente. Usado no Chrome, (e por extensão) Microsoft Edge, Node.js, etc. JavaScriptCore do Safari e SpiderMonkey do Firefox também são candidatos a implementações extremamente populares.
Mas o que mais existe? E se eu quiser incorporar JavaScript em um programa C, ou um programa Go, ou um programa Rust, ou um programa Java (e assim por diante)? Ou e se eu quiser executar JavaScript em um microcontrolador? Ou usá-lo como base para pesquisas linguísticas? Acontece que existem muitas implementações de alta qualidade por aí.
Esta postagem descreve várias delas e suas opções de implementação. Não vou cobrir V8, JavaScriptCore ou SpiderMonkey porque eles são enormes e escondem vários interpretadores e compiladores dentro deles. Além disso, você já sabe sobre eles.
Vou perder algumas implementações e errar alguns detalhes. Por favor, tweet ou me mande um email com suas correções! Eu estaria particularmente interessado em ouvir sobre pesquisa pura; e implementações comerciais de código fechado de JavaScript.
Apoiadas por empresas
Essas são implementações que fariam sentido para seus próprios aplicativos comerciais de produção.
Em JVM
- GraalJS da Oracle: compila JavaScript para bytecode JVM ou GraalVM
- Suporte: compatibilidade total com a especificação ECMAScript mais recente
- Linguagem de implementação: Java
- Runtime: GraalVM ou JDK básico
- Parser: escrito à mão
- Primeiro lançamento: 2019?
- Notas: Substituiu o Nashorn como a implementação JavaScript padrão no JDK.
- Rhino da Mozilla: interpreta e compila JavaScript para bytecode JVM
- Suporte: ES6
- Linguagem de implementação: Java
- Runtime: ambos interpretados por meio de VM de bytecode personalizado e depois de compilados para bytecode de JVM como uma otimização
- Parser: escrito à mão
- Primeiro lançamento: 1998?
- Notas: Foi substituído pelo Nashorn como a implementação JavaScript padrão na JVM, mas permanece desenvolvido ativamente.
- Nashorn da Oracle: compila JavaScript para bytecode JVM
- Suporte: ES5
- Linguagem de implementação: Java
- Runtime: compila para bytecode JVM
- Parser: escrito à mão
- Primeiro lançamento: 2012?
- Notas: Substituiu o Rhino como implementação JavaScript padrão na JVM. Foi substituído pelo GraalJS mais recentemente, mas permanece ativamente desenvolvido.
Embarcáveis
- Njs da Nginx
- Suporte: ES5
- Linguagem de implementação: C
- Runtime: Bytecode VM
- Parser: escrito à mão
- ChowJS: compilador AOT proprietário baseado em QuickJS para desenvolvedores de jogos
- Suporte: tudo o que QuickJS faz presumivelmente (veja mais abaixo para QuickJS)
- Linguagem de implementação: C presumivelmente
- Runtime: interpretador de bytecode do QuickJS, mas também um compilador AOT
- Parser: presumivelmente do QuickJS
- Primeiro lançamento: 2021
- Notas: O código não está disponível, portanto, uma análise exata desses pontos não é possível no momento.
- Mujs da Artifex
- Suporte: ES5, provavelmente
- Linguagem de implementação: C
- Runtime: VM orientada a pilha de bytecode
- Parser: escrito à mão
- Primeiro lançamento: 2017?
- Notas: Originalmente parte do visualizador MuPDF, mas agora quebrado. Obrigado a @rwoodsmalljs por mencionar!
Em sistemas embarcados
- Escargot da Samsung
- Suporte: ES2020
- Linguagem de implementação: C ++
- Runtime: Bytecode VM
- Parser: escrito à mão
- Primeiro lançamento: 2017?
- Espruino
- Suporte: partes do ES5, ES6, ES7 / 8
- Linguagem de implementação: C
- Runtime: parece interpretação recursiva direta sem uma forma AST / intermediária
- Parser: escrito à mão
- Primeiro lançamento: 2012?
- Elk da Cesanta
- Suporte: subconjunto de ES6
- Linguagem de implementação: C
- Runtime: intérprete recursivo direto sem AST ou VM de bytecode
- Parser: escrito à mão
- Primeiro lançamento: 2019?
- Observações: ele faz tudo isso com um GC e FFI em <1400 linhas de código C legível. Caramba.
- MJS da Cesanta
- Suporte: subconjunto de ES6
- Linguagem de implementação: C
- Runtime: Bytecode VM
- Parser: escrito à mão
- Primeiro lançamento: 2017?
- XS da Moddable
- Suporte: ES2018
- Linguagem de implementação: C
- Runtime: Bytecode VM
- Parser: escrito à mão
- Primeiro lançamento: 2017?
- Observações: Mais detalhes em https://www.moddable.com/XS7-TC-39 e https://www.moddable.com/faq#what-is-xs.
Outras
- Hermes do Facebook
- Suporte: ES6 com exceções
- Linguagem de implementação: C ++
- Runtime: Bytecode VM
- Parser: escrito à mão
- Primeiro lançamento: 2019?
- V4 da Qt
- Suporte: ES5
- Linguagem de implementação: C ++
- Runtime: Bytecode VM e compilador JIT
- Parser: gerador de parser personalizado qlalr
- Primeiro lançamento: 2013
- Notas: Não está claro se pode ser executado autônomo fora do ambiente Qt.
Não sei se devo colocar o ChakraCore da Microsoft nesta lista ou na próxima. Vou colocá-lo aqui, mas observe que, a partir deste ano de 2021, eles estão fazendo a transição para se tornar um projeto voltado para a comunidade.
- ChakraCore da Microsoft
- Suporte: ES6, provavelmente mais
- Linguagem de implementação: C ++
- Runtime: Bytecode VM e JIT em x86 / ARM
- Parser: escrito à mão
- Primeiro lançamento: 2015?
Maduras, criadas pela comunidade
As implementações no topo da lista a seguir são mais confiáveis e comprovadas. Implementações em direção ao final nem tanto.
Se você deseja se envolver no desenvolvimento de linguagens, as implementaões mais abaixo na lista podem ser um ótimo lugar para começar, já que normalmente precisam trabalhar em documentação, teste e recursos de linguagem.
- QuickJS de Fabrice Bellard
- Suporte: ES2020
- Linguagem de implementação: C
- Runtime: Bytecode VM (este é um único arquivo grande)
- Parser: escrito à mão (este é um único arquivo grande)
- Primeiro lançamento: 2019
- DuktapeJS
- Suporte: ES5, algumas partes de ES6 / ES7
- Linguagem de implementação: C
- Runtime: Bytecode VM
- Parser: Escrito à mão, notavelmente sem AST. Ele apenas compila diretamente para seu próprio bytecode.
- Primeiro lançamento: 2013
- engine 262
- Suporte: 100% de conformidade com as especificações
- Linguagem de implementação: JavaScript
- Runtime: interpretador AST
- Parser: escrito à mão
- JerryScript
- Suporte: ES5
- Linguagem de implementação: C
- Runtime: Bytecode VM
- Parser: escrito à mão
- Primeiro lançamento: 2016?
- LibJS para Serenity
- Suporte: Progredindo em direção à conformidade
- Linguagem de implementação: C ++
- Runtime: Bytecode VM
- Parser: escrito à mão
- Observações: também pode funcionar fora do Serenity, mas a documentação sobre como construí-lo / executá-lo no Linux é difícil de encontrar.
- goja: interpretador de JavaScript para Go
- Suporte: ES5
- Linguagem de implementação: Go
- Runtime: Bytecode VM
- Parser: escrito à mão
- Primeiro lançamento: 2017?
- otto: interpretador de JavaScript para Go
- Suporte: ES5
- Linguagem de implementação: Go
- Runtime: interpretador AST
- Parser: escrito à mão
- Primeiro lançamento: 2012?
- Observações: A implementação somente do interpretador AST pode sugerir que esta implementação é mais lenta do que Goja. Não tenho benchmarks para isso.
- Jurassic: parser e interpretador de JavaScript para .NET
- Suporte: ES5
- Linguagem de implementação: C#
- Runtime: compila para .NET
- Parser: escrito à mão
- Primeiro lançamento: 2011?
- Jint
- Suporte: ES5, a maioria de ES6 / 7/8
- Linguagem de implementação: C#
- Runtime: interpretador AST
- Parser: escrito à mão via Esprima.NET
- Primeiro lançamento: 2014?
- Notas: Obrigado fowl2 por mencionar!
- NiL.JS
- Suporte: ES6
- Linguagem de implementação: C#
- Runtime: interpretador AST
- Parser: escrito à mão
- Primeiro lançamento: 2014?
- JS-interpreter de Neil Fraser
- Suporte: ES5
- Linguagem de implementação: JavaScript
- Runtime: interpretador AST
- Parser: escrito à mão, usa Acorn
- Primeiro lançamento: 2014?
- BESEN: Bytecode VM e compilador JIT em Object Pascal
- Suporte: ES5
- Linguagem de implementação: Object Pascal
- Runtime: Bytecode VM com JIT para x86 e x86_64
- Parser: escrito à mão
- Primeiro lançamento: 2015?
Esses últimos não são brinquedos, mas também são mais experimentais ou, no caso do AssemblyScript, não são JavaScript.
- boa: interpretador de JavaScript para Rust
- Suporte: pouco claro
- Linguagem de implementação: Rust
- Runtime: Bytecode VM
- Parser: escrito à mão
- Primeiro lançamento: 2019?
- AssemblyScript
- Suporte: Subconjunto de TypeScript
- Linguagem de implementação: subconjunto AssemblyScript do TypeScript
- Runtime: webassembly
- Parser: escrito à mão
- JavaScript no Kawa Scheme
- JavaScript no GNU Guile Scheme
Implementações de pesquisa
- Higgs
- Suporte: pouco claro
- Linguagem de implementação: D
- Runtime: Bytecode VM e compilador JIT em x64
- Parser: escrito à mão
- eJS
- Suporte: pouco claro
- Linguagem de implementação: Java
- Runtime: Bytecode VM
- Parser: ANTLR
- Observações: eJS é uma estrutura para gerar VMs JavaScript especializadas para aplicativos.
- Jessie: subconjunto seguro de contratos inteligentes não exploráveis de JavaScript
- Suporte: algum subconjunto do ES2017
- ???
- Veja https://github.com/agoric-labs/jessica para mais informações.
- https://github.com/b9org/b9
- https://www.defensivejs.com/
Obrigado a @smarr por contribuir com eJS, Higgs e b9!
Notáveis abandonadas
- DMDScript
- Suporte: pouco claro
- Linguagem de implementação: D
- Runtime: Bytecode VM
- Parser: escrito à mão
- Observações: É possível que isso seja mantido comercialmente pela DigitalMars, mas não tenho certeza. Também há referências neste repositório a outra implementação C ++ do DMDScript que pode ser comercial. Obrigado a @moon_chilled por mencionar!
- EchoJS
- Suporte: pouco claro
- Linguagem de implementação: JavaScript
- Runtime: nativo por meio de LLVM
- Parser: escrito à mão via Esprima
- twostroke
- Suporte: pouco claro
- Linguagem de implementação: Ruby
- Runtime: Bytecode VM
- Parser: escrito à mão
- PyPy-JS
- Suporte: pouco claro
- Linguagem de implementação: RPython
- Runtime: RPython
- Parser: gerador de Parser EBNF
- js.js
- Suporte: pouco claro
- Linguagem de implementação: JavaScript
- Runtime: Muito medo de olhar para os arquivos gigantes neste repositório.
- Parser: Idem.
- IronJS
- Suporte: ES3
- Linguagem de implementação: F#
- Runtime: .NET por DLR, eu acho.
- Parser: escrito à mão
- jispy
- Suporte: pouco claro
- Linguagem de implementação: Python
- Runtime: interpretador AST
- Parser: incerto
- JE: Pure-Perl JavaScript Engine
- JavaScript de Dave Herman para PLT Scheme
Implementações notáveis para brincar
Ótimo para se inspirar se você nunca implementou uma linguagem antes.
- js-to-c: um compilador de JavaScript para C, escrito em C
- mjs: interpretador AST não apenas para ES5 ou mesmo ES3, mas também ES1
- gojis: interpretador AST em Go
- tojs: Bytecode VM in Rust
- v2: Bytecode VM em Go
- SparrowJS: interpretador AST em C ++
- jsc: Meu próprio experimento compilando JavaScript para C ++ / libV8″
Publicado originalmente como “Enumerating and analyzing 40+ non-V8 JavaScript implementations” em 21 de setembro de 2021. Traduzido e republicado com autorização do autor.