BT

lua.vm.js: Rodando a Lua VM em uma VM JavaScript

por Abel Avram , traduzido por Marcelo Cenerino em 16 Jul 2013 |

A Mozilla está mostrando a força do asm.js ao rodar a Lua VM completa em uma VM JavaScript, inclusive com capacidade de invocar código JS. O lua.vm.js é um projeto criado por Alon Zakai, um pesquisador da Mozilla que trabalha nos projetos Emscripten e asm.js. Tem como objetivo tornar possível a execução total da máquina virtual Lua (inclusive com garbage collection) em uma VM JavaScript. A Lua VM é escrita em ANSI C puro, o que a torna boa candidata para compilação no asm.js com Emscripten, "bastando apenas pequenos ajustes no arquivo Makefile", de acordo com Zakai.

A biblioteca é surpreendentemente pequena: 200KB compactada com gzip. Existe também um REPL (read-eval-print loop) para testar o código escrito em Lua diretamente no navegador. Além de rodar o código Lua puro, o REPL mostra que é possível invocar código JavaScript, interagir com o DOM ou configurar callbacks por meio do objeto js.global, como mostrado no exemplo a seguir:

print('hello' .. ' ' .. 'world!') -- Isso é Lua!
print(js.run('[0,1,2,3,4,5][3]')) -- Executa JS a partir do código Lua
-- Interage com a página usando Lua
local screen = js.global.screen
print("you haz " .. (screen.width*screen.height) .. " pixels")
local window = js.global -- window é o objeto global no JS
window.alert("hello from lua!")
window.setTimeout(function() print('hello from lua callback') end, 2500)
local document = js.global.document
print("this window has title '" .. document.title .. "'")

O desempenho, como de esperar, é um dos aspectos mais importantes ao rodar uma VM dentro de outra. Testes de benchmark indicam um desempenho de 50% em relação ao código nativo, o que deixa a linguagem Lua no mesmo nível de outros códigos C compilados para o asm.js, suficiente para alguns cenários:

A performance é muito baixa para certos casos de uso, mas é certamente aceitável para outros. Em particular, a Lua VM muitas vezes é mais rápida que outras linguagens dinâmicas como Python e Ruby. E embora essas linguagens não sejam super-rápidas, ainda assim são úteis em muitas situações.

Mas, conforme explica Zakai, existem outras dificuldades para lidar ao executar uma VM dentro de outra:

Há questões complexas, como por exemplo a impossibilidade de realizar a coleta de lixo entre diferentes VMs (cross-VM collection). Se não existir uma referência apontando para um objeto Lua ou JavaScript mas houver apenas referência de um para outro, será necessário percorrer todo o heap em ambos os lados e realizar nossa própria coleta (em substituição ao garbage collection do navegador) para liberá-los da memória.

A VM do JS não permite fazer isso, por motivos relacionados a segurança e desempenho. O que se pode fazer é permitir que a Lua VM mantenha referências fortes dentro do mundo JavaScript e libere-as automaticamente quando seu GC coletar tais referências. Isso gera limitações, mas é importante lembrar que o garbage collection entre VMs é um problema complexo na ciência da computação em geral.

O único caso simples ocorre quando um objeto de uma VM pode ser implementado inteiramente em outra; mas isso não é possível na maioria dos casos, tampouco nesse. Por exemplo, alguns objetos Lua podem ter métodos finalizer ("__gc") que não podem ser implementados em JavaScript. E mesmo quando é possível fazer o GC cruzando as VMs, o desempenho é uma preocupação. E note que esse tipo de problema também estaria presente se tivéssemos duas VMs separadas nos navegadores web.

O projeto parece ter como objetivo mostrar a força do Emscripten e do asm.js. Atualmente ambos disputam uma batalha de igual para igual com o Google PNaCl, outra tentativa de rodar código nativo no navegador (mais detalhes podem ser encontrados neste post do InfoQ.com: Debate: Do We Need a Universal Web Bytecode?).

O problema é que tanto o asm.js quanto o PNaCl não são suportados por outros navegadores. Teoricamente, o Chrome pode rodar código asm.js, mas o desempenho é baixo. Por exemplo, benchmarks da Lua VM rodando no Chrome apontam cerca de 30% do desempenho obtido no Firefox Nightly (no momento de escrita), que por sua vez é de 50% em relação ao desempenho da execução nativa. Sendo assim, ninguém vai querer rodar o asm.js no Chrome a menos que o Google otimize seu navegador para a solução de código nativo do Firefox. Tudo vai depender da parcela do mercado de navegadores e da habilidade de cada um em melhorar o desempenho de suas respectivas soluções.

Avalie esse artigo

Relevância
Estilo/Redação

Olá visitante

Você precisa cadastrar-se no InfoQ Brasil ou para enviar comentários. Há muitas vantagens em se cadastrar.

Obtenha o máximo da experiência do InfoQ Brasil.

Dê sua opinião

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão
Comentários da comunidade

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

HTML é permitido: a,b,br,blockquote,i,li,pre,u,ul,p

Receber mensagens dessa discussão

Dê sua opinião
Feedback geral
Bugs
Publicidade
Editorial
Marketing
InfoQ Brasil e todo o seu conteúdo: todos os direitos reservados. © 2006-2016 C4Media Inc.
Política de privacidade
BT

We notice you’re using an ad blocker

We understand why you use ad blockers. However to keep InfoQ free we need your support. InfoQ will not provide your data to third parties without individual opt-in consent. We only work with advertisers relevant to our readers. Please consider whitelisting us.