Olá Habr! Apresento a você a tradução do artigo
"De Volta ao Futuro com o WebAssembly", de Attila Vágó.
Esta postagem é uma tradução de um artigo que fala sobre as propriedades do WebAssemly e Emscripten. Artigo original em inglês.
A autora do artigo, Attila Vago, é desenvolvedora de software sênior da HMH. Escreve código, blogs e outras coisas na Internet. Uma poliglota de linguagens de programação, uma figura pragmática, apaixonada por JavaScript e de fácil acesso. Pessoa facilmente inspirada e inspiradora, com uma forte dependência de coisas para nerds, boa comida, cerveja artesanal e Lego. Usado pelo Mac. Ele se exercita às 6 da manhã.Em 2011, escrevi minha primeira linha independente de código não HTML (trabalhei com ele em 2007) e foi escrita no muito bom e velho C ensinado pelo professor David J. Malan da Universidade de Harvard. Ele permanecerá para sempre minha inspiração não apenas para o estudo da programação, mas também para o pensamento sobre software. Também me lembrei de que fazer um sanduíche de manteiga de amendoim é apenas para mim, mas é uma tarefa incrivelmente difícil para um computador e igualmente difícil para uma pessoa que finge ser um computador.
Se você assistiu ao vídeo, pelo menos nos primeiros 18 minutos (eu sei que leva muito tempo, mas a programação leva tempo), então você entenderá por que até hoje C está perto do meu coração. Para minha decepção, nunca aprendi isso, porque, convenhamos, para um desenvolvedor web, C é a menor das prioridades. Eu nunca tive um motivo real para me aprofundar nesse idioma, apesar de comprar inúmeros cursos da Udemy e livros em C, nunca os toquei (mantenha seu olhar crítico para você, você também) ou minta para mim mesmo que, se eu comprar smart watch Pebble, que funciona em C, não deixe de escrever um código para eles. Sim, com certeza! Nenhuma dessas razões foi boa o suficiente.
O que é o WebAssembly e como ele supera o JS?
O WebAssembly (Wasm para abreviar) é um formato de instrução binário para uma máquina virtual empilhada.
“O Wasm foi desenvolvido como uma plataforma portátil para compilar linguagens de alto nível, como C / C ++ / Rust, que permite implantar aplicativos de cliente e servidor na Internet”
- gentilmente explica webassembly.org
Em outras palavras, o que precede significa que você pode escrever módulos que funcionam na Internet em um navegador / servidor, mas são escritos em linguagens como C, compiladas em um arquivo binário e, portanto, incrivelmente rápido, porque funcionam diretamente no hardware da máquina. Comparadas a elas, linguagens de script como JavaScript têm vários níveis de abstração entre código e hardware, o que, entre outras coisas, as torna lentas. Obviamente, isso nem sempre importa, e cada um deles tem seu próprio lugar no programa ou mesmo no ecossistema da web.
Com base nisso, o Wasm by structure (inicialmente) suporta apenas números inteiros e de ponto flutuante, o que fornece grande poder de computação e, portanto, é frequentemente usado para implementações do tipo canvas. É importante entender que o WebAssembly não é uma ameaça ao JavaScript - pelo menos ainda não - e, como você verá mais adiante neste artigo, C e JavaScript podem realmente viver muito felizes no mesmo projeto e executar o código um do outro. Sim, algo assim.
Emscripten "cola" C e JS
Agora espere! Eu sei o que estou dizendo. Você não pode dizer coisas como "executar C em JS e vice-versa" e esperar que o mundo não reaja. Por mais estranho que pareça, não estou enganando. Acontece que o Emscripten é uma cadeia de ferramentas para compilar no asm.js e no WebAssembly, projetado usando LLVM (meu Deus, aprendi metade dessas coisas ao digitar o texto do artigo), que permite executar C e C ++ na Internet na velocidade quase nativa, sem plug-ins.
Bem, aqui está o que você precisa destacar disso para si mesmo. O Emscripten ajuda a compilar o código C no WebAssembly, fornecendo ferramentas adicionais para facilitar a carga do desenvolvedor no que diz respeito à comunicação entre os dois idiomas e ajuda a iniciar o Wasm em seu projeto da web. O comando básico de compilação para o Emscripten é o seguinte:
emcc lib/strings.c -s WASM=1 -o public/strings.js
Enquanto um comando não básico é executado assim:
emcc lib/imports.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_getNum', '_main', '_getDoubleNum', '_greet']" -o public/imports.js
Configurar o Emscripten não é a coisa mais fácil, mas não o lançamento de um foguete. A única coisa que complica a instalação é que ela tem muitas dependências como Python, Node, xCode, Git e cMake. Todas as instruções podem ser encontradas na página de instalação e são fáceis de seguir.
Portanto, Emscripten:
- é uma ótima ferramenta para portabilidade, permitindo compilar projetos existentes escritos em C ou C ++ e executá-los em todos os navegadores modernos. Saia daqui, Internet Explorer!
- ótimo para APIs porque converte OpenGL em WebGL e permite que você use APIs familiares, como SDL ou diretamente HTML5. Ah sim!
- E é extremamente rápido: graças ao LLVM, Emscripten, asm.js e WebAssembly, o código é executado quase na sua própria velocidade. Corra, coelho, corra!
Nota: Você não precisa do Emscripten para gerar o Wasm, pois todos os novos navegadores têm uma API para oferecer suporte ao Wasm na mesma janela, que executa o Emscripten como a camada superior, o que facilita a vida do desenvolvedor. Por exemplo, o Emscripten ajustará a quantidade de memória para você, que pode ser entediante através de C.
Exemplos ... exemplos estão por toda parte!
Você sabe, como se costuma dizer, "uma linha de código vale mais que mil palavras" ; - OK, essa é uma prerrogativa do narrador e tudo isso; portanto, sem mais delongas, vamos dar uma olhada em algum código real. Comentário fora do tópico: naquele dia, não consegui superar a sintaxe C. Não compilou metade do tempo, porque meu código seria instável. E depois de oito anos, fico assim: "Sim, parece JavaScript . "
Gente, se alguém começa a ver o código C no meu React, apenas me traga de volta à realidade, ok?
Um pouco fora de tópico, aqui está o código C atual:

E, consequentemente, em JavaScript:

OK, o que exatamente acontece nesses arquivos? Na verdade, bastante, então vou listar.
- É importante entender que main () , a menos que seja especificado de outra forma, sempre inicia primeiro e também compila por padrão. Se você deseja compilar outra função, precisará defini-la especificamente no sinalizador da matriz EXPORTED_FUNCTIONS , conforme mostrado na seção anterior.
- Você escreve seu código C, como sempre, importando suas bibliotecas regulares, mas, além disso, você obtém o açúcar sintático do Emscripten, além de mais métodos / funções do que com qualquer outra ferramenta.
- O arquivo imports.js (o nome é arbitrário, mas sempre o mesmo que o arquivo C) referenciado pelo HTML nada mais é do que o Emscripten "cola", que é gerado automaticamente na compilação. Não precisa se preocupar com isso, apenas verifique se ele está realmente relacionado.
- Printf é apenas uma instrução C comum que registra uma string no console. Nada de especial, siga em frente.
- As linhas 14 e 17 são um anti-padrão, mas um bom exemplo de execução de JS no seu código C. A única diferença real entre emscripten_run_script e emscripten_async_run_script é que o último permite executar JS em C de forma assíncrona. Principalmente com setTimeout () . A razão pela qual eu disse que isso é um anti-padrão é porque é. Toda a idéia do WebAssembly é executar C em JS, não JS em C e, portanto, ...
- As linhas 20 e 24 e suas funções JS associadas em index.html representam o modelo correto, declarando seu JS em seu JS e retornando algo para C.
- O EM_JS , que lança o jsFunction , é simplesmente uma maneira mais fácil - de atingir o mesmo objetivo dos pontos 4 e 5.
O resultado previsto do exposto acima é o seguinte:

Senhoras adiante!
Como em qualquer código, o WebAssembly também tem uma ordem de execução. Não mexa com a fila! A ordem neste caso é padrão para a ordem C. Tudo começa em Main () e sempre que main () está pronto, Wasm está pronto. No entanto, o que acontece se você precisar de uma função estática para chamar em tempo de execução? Bem, apenas um pouco de açúcar sintático Emscripten, e tudo corre como um relógio:

Coletamos moscas do bolo
Este é um código bem escrito, especialmente as coisas simples ilustradas nas seções anteriores, mas todos sabemos que o mundo real é muito maior que o "Hello World", e metade do tempo de cada desenvolvedor é gasta para descobrir por que o código não está fazendo o que deveria. Os erros são simplesmente inevitáveis e, em certo sentido, fazem parte da vida.
Quando você executa C em JS ou em qualquer Wasm, tudo pode se tornar ainda mais deprimente. Felizmente, o Emscripten vem ao resgate novamente, fornecendo dois métodos de depuração muito úteis:
// browser debugger gets triggered emscripten_debugger(); // browser console warning with stack-trace emscripten_log(EM_LOG_WARN, “'param' your message”);
Gonzalez rápido se apressa para ajudar
Acredite ou não, os criadores do Emscripten pensaram em tudo. Um grande recurso - e o último que mencionarei neste artigo, já que existem muitos deles para colocar todos em um - é a base para o desenvolvimento e teste rápidos. Você pode compilar seu Wasm, criar um projeto e iniciar o servidor de uma só vez:
emrun --port 7777 --no_browser public/index.html Now listening at http://localhost:7777/
A página html que você está executando não é compatível com emrun. As capturas stdout, stderr e exit (returncode) não funcionarão. Recompile o aplicativo com o sinalizador --emrun linker para habilitar isso, ou passe --no_emrun_detect para emrun para ocultar essa verificação.
Ok, em dois colegas ... o exemplo acima funciona, mas o próximo funciona melhor, o que explica o erro mostrado.
<b>// compile as emrun project emcc lib/strings.c -s WASM=1 --emrun -o public/index.html // run the emrun server again emrun --port 7777 --no_browser public/index.html</b>
Eu apenas deixo assim. Estudando o WebAssembly, comemorei o Dia de São Patrício e o dia seguinte. Não tenho muita certeza do que acontecerá a seguir, mas me emocionou o suficiente ficar sentado na frente do monitor por dois dias, tentando entender o básico do WebAssebly, e isso deveria significar algo, certo? Este é o código C que eu escrevi desde 2011 e é ótimo. Eu acho que o WebAssembly tem um futuro real, mas não tenho certeza se ele assumirá completamente a rede e matará o JS, como alguns pregam. O que você acha?
