asm.js é um subconjunto de JavaScript projetado para permitir que software de computador escrito em linguagens como C sejam executados como aplicativos da web, enquanto mantém características de desempenho consideravelmente melhores do que o JavaScript padrão, que é a linguagem típica usada para tais aplicativos.

o asm.js consiste em um subconjunto estrito de JavaScript, para o qual o código escrito em linguagens estaticamente tipadas com gerenciamento de memória manual (como C) é traduzido por um compilador de fonte para fonte como o Emscripten (baseado em LLVM). O desempenho é melhorado ao limitar os recursos da linguagem àqueles que podem ser otimizados com antecedência e outras melhorias de desempenho.

O Mozilla Firefox foi o primeiro navegador da web a implementar otimizações específicas para o asm.js, a partir da versão 22.

O asm.js foi substituído por WebAssembly. Consulte abaixo.

Design O asm.js permite melhorias significativas de desempenho para aplicativos da web, mas não tem como objetivo melhorar o desempenho do código JavaScript escrito à mão, nem permite nada além do desempenho aprimorado.

Destina-se a ter características de desempenho mais próximas das do código nativo do que o JavaScript padrão, limitando os recursos da linguagem àqueles passíveis de otimização antecipada e outras melhorias de desempenho. Ao usar um subconjunto de JavaScript, o asm.js é amplamente compatível com todos os principais navegadores da web, ao contrário de abordagens alternativas como o Google Native Client.

Geração de código O asm.js normalmente não é escrito diretamente: em vez disso, como uma linguagem intermediária, ele é gerado por meio do uso de um compilador que pega o código-fonte em uma linguagem como C++ e gera asm.js.

Por exemplo, dado o seguinte código em C:

int f(int i) { return i + 1; }

Emscripten produziria o seguinte código em JS: function f(i) { i = i|0; return (i + 1)|0; }

Observe a adição de |0 e a falta de especificadores de tipo. Em JavaScript, os operadores bit a bit convertem seus operandos em inteiros assinados de 32 bits e fornecem resultados inteiros. Isso significa que um OR bit a bit com zero converte um valor em um inteiro (uma apresentação "conceitual" muito simples de operadores bit a bit pode não lidar com a conversão de tipo, mas toda linguagem de programação define operadores para sua própria conveniência, como o Javascript faz aqui) . Ao fazer isso para cada parâmetro, isso garante que, se a função for chamada de um código externo, o valor será convertido para o tipo correto. Isso também é usado no valor de retorno, neste caso, para garantir que o resultado da adição de 1 a i seja um número inteiro (caso contrário, ele poderia se tornar muito grande) e para marcar o tipo de retorno da função. Essas conversões são exigidas pelo asm.js, para que um compilador otimizador possa produzir código nativo ahead-of-time altamente eficiente. Nesse compilador otimizador, nenhuma conversão é executada quando o código asm.js chama outro código asm.js, pois os especificadores de tipo necessários significam que é garantido que os valores já terão o tipo correto. Além disso, em vez de realizar uma adição de ponto flutuante e converter para um número inteiro, ele pode simplesmente fazer uma operação de número inteiro nativo. Juntos, isso leva a benefícios em desempenho significativos.

Aqui está outro exemplo para calcular o comprimento de uma string:

size_t strlen(char *ptr) { char *curr = ptr; while (*curr != 0) { curr++;

return (curr - ptr); }

Isso resultaria no seguinte código em asm.js:

function strlen(ptr) { ptr = ptr|0; var curr = 0; curr = ptr; while ((MEM8[curr>>0]|0) != 0) { curr = (curr + 1)|0;

return (curr - ptr)|0; }

No código gerado, a variável MEM8 é na verdade uma "visualização" byte a byte de um buffer tipado, que serve como o "heap" do código em asm.js.

Desempenho Como o asm.js é executado em um navegador, o desempenho depende muito do navegador e do hardware. Os benchmarks preliminares de programas C compilados para asm.js estão geralmente em um fator de lentidão de 2 em relação à compilação nativa com Clang.

Muito desse ganho de desempenho em relação ao JavaScript normal é devido a 100% de consistência de tipo e virtualmente nenhuma coleta de lixo (a memória é gerenciada manualmente em uma grande matriz tipada). Este modelo mais simples, sem comportamento dinâmico, sem alocação ou desalocação de memória, apenas um conjunto estreito de inteiros bem definidos e operações de ponto flutuante permite um desempenho muito maior e potencial de otimização.

O benchmark da Mozilla de dezembro de 2013 mostrou melhorias significativas: "Firefox com otimizações float32 pode rodar todos esses benchmarks em cerca de 1,5× mais lento do que o nativo, ou melhor." A Mozilla aponta que o desempenho do código compilado nativamente não é uma medida única, mas sim um intervalo, com diferentes compiladores nativos (neste caso Clang e GCC) entregando código de desempenho diferente. "Na verdade, em alguns benchmarks, como Box2D, FASTA e cópia, asm.js é tão próximo ou mais próximo do Clang do que o Clang está do GCC. Em um caso, o asm.js até supera o Clang por pouco no Box2D."

Implementações O projeto Emscripten fornece ferramentas que podem ser usadas para compilar bases de código C e C ++ (ou qualquer outra linguagem que possa ser convertida para LLVM IR) em asm.js.

Todos os navegadores com suporte para ECMAScript 6 devem ser capazes de executar o código asm.js, pois é um subconjunto dessa especificação. No entanto, como os recursos foram adicionados nessa edição para habilitar o suporte completo para asm.js (Math.fround()), navegadores mais antigos sem esses recursos podem encontrar problemas.

Algumas implementações de navegador são especialmente otimizadas para asm.js:

Mozilla Firefox foi o primeiro navegador da web a implementar otimizações específicas do asm.js, começando com o Firefox 22. OdinMonkey, o compilador asm.js da Mozilla usado no Firefox, é um componente do IonMonkey, o compilador JIT do SpiderMonkey. A Microsoft está implementando suporte para asm.js em Chakra, o mecanismo JavaScript usado pelo Microsoft Edge, realizando validação para produzir código JIT altamente otimizado. As otimizações do motor JavaScript V8 do Google Chrome no Chrome 28 fizeram benchmarks do asm.js mais de duas vezes mais rápido do que as versões anteriores do Chrome, embora o V8 do Chrome não use compilação antecipada.

Adoção Quase todos os aplicativos atuais baseados em asm.js são aplicativos C/C++ compilados em asm.js usando Emscripten ou Mandreel. Com isso em mente, o tipo de aplicativo que terá como alvo o asm.js em um futuro próximo são aqueles que se beneficiarão da portabilidade de execução em um navegador, mas que têm um nível de complexidade para o qual um porte direto para JavaScript seria inviável.

Até agora, uma série de linguagens de programação, frameworks de aplicativos, programas, bibliotecas, jogos, motores de jogos e outros softwares já foram portados. Alguns deles são listados abaixo.

Linguagens de programação C/C++: Clang e LLVM Rust: tem como alvo o Emscripten Lua VM: Máquina virtual Lua Perl: porte de (micro)perl-5.16.3 Python – porte de CPython Ruby – porte de Ruby

Frameworks de aplicativos pepper.js: Portes de diversos apps PNaCl (earth, voronoi, bullet, etc.) Qt: portes de vários demos da Qt, mais os aplicativos do KDE, como o Kate

Programas e bibliotecas OpenGL, SDL, e SDL2 Vim (Vi IMproved) FreeType: renderização de fontes TrueType em JavaScript, usando FreeType SQLite GNU Privacy Guard ctags gnuplot Graphviz zlib

Motores de jogo Unreal Engine 3: foi portado em 4 dias Unreal Engine 4 Unity ScummVM, que suporta vários jogos clássicos de aventura Godot

Jogos Doom: os ativos do jogo em código aberto Freedoom em execução no PrBoom, que é baseado no código em código aberto Doom SuperTux Dune II via OpenDune BananaBread baseado em Cube 2 Todos os jogos do Humble Mozilla Bundle (Super Hexagon, AaAaAA! for the Awesome, Osmos, Zen Bound 2, Dustforce DX, Voxatron, FTL: Advanced Edition and Democracy 3)

Emuladores EM-DOSBox: um porte do DOSBox para o Emscripten Start9.io: uma plataforma de emulação da web visando múltiplas arquiteturas de jogos JSMESS: um porte do emulador MESS para muitos consoles de jogos e sistemas de computadores

Matemática HTML5 Fractal Playground – desenha fractais gerados por função iterativa, como o conjunto de Mandelbrot.

Deprecação O asm.js se tornou obsoleto principalmente com a introdução do WebAssembly (wasm), que tem um formato de bytecode que é mais rápido de analisar. Os esforços para estender o JavaScript com mais recursos de baixo nível, como SIMD.js, também foram suspensos desde 2017.

o asm.js permanece útil principalmente como um "substituto" para o wasm, por meio de um programa escrito pela organização WebAssembly que converte o wasm em asm.js. Não há um conversor dedicado de asm.js para wasm, mas os compiladores TypeScript-para-wasm podem ser usados parcialmente. O emissor WebAssembly de referência binaryen costumava conter um módulo asm2wasm, mas foi removido depois que o Emscripten parou de usá-lo. (Ver também PR#3042.)

Ver também Alchemy Emscripten Google Native Client (NaCl) PyPy WebAssembly - um bytecode para navegadores, destinado a ser mais rápido de analisar do que asm.js

Ligações externas

Categoria:JavaScript Categoria:Mozilla Categoria:Programação web