Go: todos: suporte WebAssembly ("wasm")

Criado em 2 fev. 2017  ·  147Comentários  ·  Fonte: golang/go

WebAssembly ("wasm") é semelhante ao Native Client, mas diferente principalmente porque outros navegadores planejam implementá-lo.

http://webassembly.org/

Isso foi perguntado algumas vezes, então este é um bug de rastreamento para isso.

Seja por cmd/compile, gccgo ou llvm-go, podemos postar atualizações aqui.

Arch-Wasm NeedsFix

Comentários muito úteis

Olá a todos. Aqui está uma atualização do meu trabalho: Estou fazendo um progresso muito bom, o que se deve muito ao ótimo trabalho da equipe Go e dos colaboradores até agora. A maior parte do código é compartilhada entre arquiteturas/plataformas, então não havia tanto quanto eu esperava que precisasse ser implementado.

Aqui está uma lista de algumas coisas que já estão funcionando bem:

  • executando o código wasm gerado em navegadores e em Node.js
  • operações básicas, conversões, etc.
  • interfaces
  • goroutines e canais
  • adiar/pânico/resgatar
  • lendo arquivos do disco ao usar Node.js
  • testes dos seguintes pacotes estão passando: bytes, container/heap, container/list, container/ring, encoding/ascii85, encoding/asn1, encoding/base32, encoding/binary, encoding/csv, encoding/hex, errors, flag, hash/adler32, hash/crc32, hash/crc64, hash/fnv, html, image, image/color, index/suffixarray, math, math/bits, path, sort, strconv, strings, text/scanner, text/tabwriter, unicode, unicode/utf8, unicode/utf16

Algumas coisas que ainda precisam ser trabalhadas:

  • reflexão
  • aumentando a pilha de goroutines
  • coleta de lixo
  • otimizações de desempenho
  • otimizações de tamanho de arquivo wasm
  • uma boa camada de interoperabilidade JS
  • muitos outros problemas para fazer mais testes de pacotes passarem

Estou muito feliz com o progresso em um mês e meio, e apenas no meu tempo livre. Acho que há uma boa chance de colocarmos isso no Go 1.11. Espere minha próxima atualização em janeiro, já que estarei de férias e depois há os feriados.

Todos 147 comentários

@cherrymui e eu discutimos longamente a possibilidade de uma porta wasm GC em
Nos últimos dias:

Nossa conclusão atual é que não existe uma maneira eficiente de implementar
funcionalidade setjmp/longjmp atualmente, portanto, não é um alvo viável
de uma porta gc. Precisamos esperar até que a pilha se desfaça de verdade e
suporte ao tratamento de exceções.

Todos os outros aspectos pareciam bem, e até projetamos um Go ABI sob o wasm
(passar g e SP na pilha wasm e tudo mais na pilha Go emulada) e
uma maneira de modificar o back-end atual do MIPS para oferecer suporte ao wasm emulando o MIPS
registradores como variáveis ​​locais wasm.

Talvez o GopherJS possa suportar o wasm mais facilmente.

De gopherjs/gopherjs#432:

No entanto, não é uma tecnologia que o GopherJS possa usar. GopherJS compila no nível AST, não no nível do código de máquina.

WebAssembly pode ser usado como backend para o compilador Go normal

@minux A falta de threads ou e/s assíncrona parece ser um problema maior do que as soluções alternativas da ABI que teríamos que fazer por causa de peculiaridades do wasm.

@minux , @cherrymui
você poderia postar em algum lugar com mais detalhes o que você fez e alcançou?
como você deve saber, a comunidade go-interpreter está considerando escrever um interpretador baseado em bytecode LLVM ou wasm.
(podemos até ter um aluno do GSoC trabalhando no interpretador wasm bytecode [1] , então, apenas a parte do "consumo de bytecode", não a "produção de bytecode por meio de alguma cadeia de ferramentas baseada em Go")

minimizar a quantidade de esforços duplicados e incompatibilidade de impedância entre vários componentes seria ótimo.

Eu recomendo isso como um recurso estratégico. Considere que em apenas alguns anos os programadores da web se reunirão em hordas para escolher sua linguagem de escolha para ser compilada em montagem da web. Quanto mais cedo nos juntarmos à corrida, melhor. A Mozilla está forçando o Rust como a linguagem de montagem da Web de escolha ...

Eu apoio o que @RaananHadar disse. Seria uma pena se a especificação não atendesse às necessidades do Go, especialmente considerando como o tempo de execução do Go pode ser único.

EDIT: Desculpas pela natureza MeToo deste comentário :) Obrigado pela indicação Brad.

O contexto da máquina de pilha do WebAssembly consiste em memória linear e uma pilha de operação. IIUC, salvar o contexto da VM pode ser feito salvando o:

  1. PC atual, string de bytecode
  2. A memória linear e o
  3. Pilha de Operação

Para uma lista global de contextos salvos na estrutura de contexto da VM, se houver.

Assim, um setjump deve simplesmente restaurar esses valores e continuar com o loop do interpretador como de costume (isso é semelhante a como a VM de bytecode do emacs implementa sinais: https://github.com/emacs-mirror/emacs/blob/master/src /bytecode.c#L785). Um sistema de exceção pode ser implementado em cima disso, embora eu não tenha certeza de qual seria o desempenho disso.

Além disso, a especificação do webassembly menciona que a altura da pilha em qualquer momento no bytecode é conhecida estaticamente , tornando todas as operações de pilha equivalentes a operações em registros exclusivos para cada posição na pilha. Este artigo descreve uma maneira de obter esse mapeamento de pilha -> registro para converter código de máquina de pilha em código nativo, permitindo usar setjmp/longjmp como de costume.

Edit: Que tal usar panic() e recover() com valores especiais de WasmException{} para sinalizar uma exceção? recover já faz o trabalho difícil de desenrolar a pilha, não deve ser difícil restaurar o loop do interpretador após a recuperação de uma exceção capturada.

Sim, basicamente a discussão com @cherrymui resultou em descobertas semelhantes.

O design inicial com @cherrymui é este:
(este estágio se concentra em fazer $GOROOT/test/sieve.go funcionar, nenhum IO assíncrono é
considerado.)
reutilizamos a porta MIPS, mapeando os 31 registros MIPS como WASM local
variáveis ​​e use apenas a pilha WASM
para resultados intermediários. Não podemos usar o mecanismo de chamada de função do WASM para
a maioria das funções Go porque
a falta de suporte de desenrolamento de pilha.
altere o mips objlink (cmd/internal/obj) para emular cada instrução MIPS
com as respectivas instruções WASM.
Isso torna a implementação do setjmp/longjmp (aka runtime.gogo) trivial e
reutiliza muito do esforço existente.

Go já precisa implementar sua própria pilha, separada da pilha WASM,
porque o Go precisa ser copiado
pilha, mapas de ponteiro de pilha e suporte de desenrolamento de pilha, que não são
disponível na WASM.
(Esta estratégia também se alinha com a porta LLVM, não podemos usar a pilha LLVM para
quase os mesmos motivos
(a menos que adicionemos um passe de backend personalizado ao LLVM adequado para codificar o ponteiro de pilha
mapas).)

Provavelmente precisaremos usar um grande switch para encadear saltos indiretos? Isto é
semelhante à abordagem do NestedVM.
http://nestedvm.ibex.org/

Se decidirmos implementar um backend WASM nativo, podemos fazer isso:
o Go ABI é:
todos os parâmetros (incluindo resultados) na pilha Go (emulada),
na entrada da função, o seguinte está na pilha WASM:
SP emulado, g.

A discussão aconteceu há mais de um mês, e eu provavelmente esqueci alguns
detalhes neste momento.

IIUC, você pode descartar completamente a pilha WASM (de acordo com a especificação). Uma pilha go extensível e copiável ainda é algo que precisa ser investigado.

Sim, o design inicial que mencionei usa apenas a pilha WASM para
intermediários usados ​​na computação. Todos os dados estão no heap Go (linear
memória) ou pseudo registradores em variáveis ​​locais WASM.

Não espero que a especificação WASM incorpore a pilha de movimentação/segmentação e cópia.
Raramente é usado por linguagens convencionais visadas pelo WASM.

@bradfitz @minux @vibhavp Qual é o estado atual do wasm em Golang? Nada aconteceu desde 13 de março! será possível transformar golang em wasm no futuro? existe talvez algum mapa de rota disso?

se alguém decidir implementar o suporte wasm, posso oferecer meu tempo para tarefas não globais

@SerkanSipahi , ninguém está trabalhando nisso. Este bug é marcado como LongTerm. Se algo começar a acontecer, você verá atualizações aqui.

Um bom roteiro?

Temos DELVE e GDLV para depurar golang com uma GUI. Funciona bem também em todos os Desktops e o Perf é excelente.
https://github.com/derekparker/delve
https://github.com/aarzilli/gdlv

Agora, GDLV é baseado em NUCULAR que é brilhante com algumas boas abstrações.
https://github.com/aarzilli/nucular

Então eu estava pensando que isso seria uma boa base para fazer o que já foi feito aqui:

Existem 5 bibliotecas WASM go agora também:
https://github.com/search?l=Go&q=webassembly&ref=simplesearch&type=Repositories&utf8=%E2%9C%93

Acredito que o NaCl seja usado por várias partes do ecossistema Go. Ou seja, não é usado apenas pelo Chrome. E, de qualquer forma, esse anúncio do blog é sobre o PNaCl, que, embora forneça funcionalidade semelhante ao NaCl, é na verdade um produto completamente diferente, baseado em uma tecnologia diferente. Portanto, remover o suporte de NaCl do Go é prematuro no momento.

Em qualquer caso, remover ou não o NaCl do Go não tem nada a ver com a adição de suporte ao Web Assembly.

Eu diria que o PNaCl é apenas uma extensão do NaCl para fornecer código independente da plataforma https://developer.chrome.com/native-client/nacl-and-pnacl Perguntei sobre a depreciação do NaCl aqui - https://groups.google. com/d/topic/native-client-discuss/wgN2ketXybQ/discussion

Se é possível obter uma lista dessas várias partes do ecossistema Go onde o NaCl ainda é usado?
Passar por um por um tornará a transição para o WebAssembly mais interessante.

Eu diria que PNaCl é apenas uma extensão sobre NaCl

Você pode dizer o que quiser, mas isso não significa que você está certo. Eles são ISAs completamente diferentes, NaCL é apenas o ISA alvo (x86/arm) com algumas restrições, enquanto PNaCl é um ISA completamente diferente para uma máquina abstrata.

Go nunca foi compatível com PNaCL, e a porta Go NaCL nunca foi adequada para o Chrome. Não tinha nada a ver com o Chrome, não era utilizável no navegador. Se o Chrome abandona o NaCL ou o PNaCL não tem qualquer relevância para o Go. Nada, zero, sem relevância . Quantas vezes mais isso deve ser dito? Obviamente, se o NaCL for completamente abandonado, o Go será forçado em algum momento a abandoná-lo também.

O suporte a WebAssembly em Go não tem absolutamente nada a ver com NaCL. Go pode ou não ter suporte para WebAssembly. Se ou quando pode obter tal suporte não tem relevância para o estado da porta NaCL.

Aqui está uma parte muito importante do ecossistema onde usamos nacl: https://play.golang.org/p/MfJIq8wb5-

(que roda no lado do servidor, não nacl-in-a-browser)

Se o Chrome abandona o NaCL ou o PNaCL não tem qualquer relevância para o Go. Nada, zero, sem relevância.

E quem dará suporte ao carregador de sandbox e à cadeia de ferramentas então? Ele é importado do projeto Chrome, que mudou os esforços para o WebAssembly. Não seria sensato seguir e ver se o Go playground já pode ser portado do sandbox NaCl para o sandbox WebAssembly? Também pode ser executado no lado do servidor.

Acho que todo mundo é a favor do suporte ao WebAssembly.

A hora de discutir o afastamento do NaCl é depois que o WebAssembly estiver funcionando totalmente. Não adianta discutir antes disso.

@ianlancetaylor , você pode esclarecer "depois que o WebAssembly estiver funcionando totalmente"?

À primeira vista, parece que o webassembly.org diz que "a versão inicial do WebAssembly atingiu um consenso entre navegadores" e o wasm está disponível em versões de navegador atuais ou futuras de todos os fornecedores de navegadores .

@vine77 Quero dizer, depois que o WebAssembly estiver funcionando totalmente para programas Go, pelo menos tão bem quanto o NaCl funciona hoje.

Então, qual é o próximo teste que deve passar para que o WebAssembly funcione para programas Go?

@techtonik Sinto que há alguma confusão aqui. Quando dizemos que o WebAssembly deve funcionar para programas Go, o que queremos dizer é que o compilador Go deve gerar um código WebAssembly que possa ser executado no navegador. Queremos dizer que você deve ser capaz de escrever algo como GOOS=wasm go build hello.go e obter um programa que possa ser executado dentro de um navegador. Não estamos nem remotamente perto disso. Nós nem começamos. Portanto, não há "próximo teste". Há muito trabalho a ser feito. E, até onde eu sei, ninguém está trabalhando ativamente nisso.

@ianlancetaylor
Existem 4 implementações para golang. Um seriamente impressionante. Veja meu comentário anterior para os links.

Rapaz, esse tópico é como o carro Chevy Chase visto com as crianças no banco de trás gritando "já chegamos" :)

@ joeblew99 : nenhum desses links são coisas que podem compilar Go to WebAssembly.
São coisas como um compilador WebAssembly -> amd64 escrito em Go.

Eu estava com medo que você dissesse isso. Justo.
Então, o que é necessário para o "criar"? Então todo mundo sabe...
Gopherjs cometeu o mesmo erro de não estar no nível certo na arquitetura da cadeia de ferramentas do compilador/geração de código?

Há uma longa lista. A maioria tem a ver com coleta de lixo, de uma forma ou de outra.

  • Gere código WebAssembly no back-end SSA. O backend é usado para registrar máquinas, adaptar-se à máquina de pilha do WebAssembly vai dar algum trabalho.
  • O que é um ponteiro? WebAssembly não tem um tipo de ponteiro.
  • Como fazemos a introspecção da pilha? Nós precisaríamos disso para coleta de lixo, certamente, mas também pânico/recuperação, impressão de rastreamento, etc.
  • Como suspendemos/retomamos uma goroutine?
  • Como podemos colocar a pilha? O WebAssembly fornece apenas essencialmente sbrk. Precisamos de um layout de espaço de endereço mais geral. Onde armazenamos informações sobre spans, bits ptr/nonptr, etc.?
  • Multithreading. O WebAssembly não tem noção de threads no momento, o que precisaríamos, por exemplo, fazer GC concorrente. Também precisaríamos de bloqueios e talvez operações atômicas.
  • Como fornecemos acesso ao mundo exterior para pacotes como os e net?
  • WebAssembly não tem suporte para "goto".

Isso provavelmente não é uma lista completa.

Quando dizemos que o WebAssembly deve funcionar para programas Go, o que queremos dizer é que o compilador Go deve gerar um código WebAssembly que possa ser executado no navegador.

@ianlancetaylor seria mais fácil segmentar não-web primeiro? O NaCl também foi projetado para ser executado primeiro no navegador, mas depois recebeu o carregador independente do navegador, que o Go usa atualmente. WebAseembly sem navegador - http://webassembly.org/docs/non-web/ - e fala sobre shells mínimos para teste.

@ Randall77 é possível trazer uma lista de verificação acionável desta lista? Como uma questão principal com links para questões que pesquisam cada aspecto mais detalhadamente?

@techtonik wrt non-web: @vibhavp está trabalhando nisso no contexto do estágio GSoC que eu estava fazendo alusão a alguns posts acima.
está ali: https://github.com/go-interpreter/wagon

@techtonik : Acho que o lugar certo para essa lista de verificação é um documento de proposta sobre suporte ao wasm. Uma vez que tal proposta seja aceita e/ou as pessoas estejam trabalhando ativamente nela, elas podem usar questões para tarefas individuais, com certeza. Isso é prematuro neste momento - não conheço ninguém trabalhando ativamente (uma proposta ou código).

Concordo com uma proposta doc.
Tudo o que eu faço/contradições estão neste tópico e só precisam dele embrulhados, com um roteiro que permita etapas o equilíbrio risco/recompensa.

Eu também gostaria de vê-lo abordar os gráficos também, pois está se destacando como um polegar dolorido para mim.

Sou o autor de GopherJS , um compilador de Go to JavaScript. Eu escrevi esse projeto porque acredito fortemente que deve haver alternativas ao uso de JavaScript no navegador, alternativas como Go e outras. Eu tenho um conhecimento decente sobre compiladores, SSA, arquitetura de máquina etc., mas provavelmente estou perdendo muitos detalhes, já que ainda não escrevi um backend de compilador para código de máquina. É por isso que não me sinto qualificado para escrever um documento de proposta completo. Ainda assim, adoraria receber alguns comentários críticos sobre meus pensamentos sobre Go e WebAssembly.

Ao olhar para o WebAssembly, parece-me muito diferente dos alvos usuais de código de máquina, como x86 ou arm. Por exemplo, sua arquitetura é uma máquina de pilha em vez de uma máquina de registradores. Isso significa que não é imediatamente adequado como apenas mais um alvo no último estágio do compilador Go ao lado de x86 e amigos. Uma solução pode ser não colocá-lo lá, mas ter uma abordagem significativamente diferente na geração do WebAssembly. O código para essa abordagem precisaria viver além dos estágios do compilador existentes, o que não seria nada bom. Pode-se até considerar uma bifurcação do compilador neste cenário. Resumindo: não vejo isso acontecendo.

Pode haver uma alternativa: emular o que precisamos. Podemos usar a máquina de pilha para emular uma máquina de registradores e esperamos fazê-lo de uma maneira razoavelmente eficiente. O WebAssembly tem memória linear com instruções load e store, o que é bom. Nós não usaríamos a instrução call do WebAssembly e, em vez disso, rolamos nosso próprio gerenciamento de pilha e mecanismo de chamada. As pilhas viveriam nessa memória linear e seriam gerenciadas pelo tempo de execução do Go. O stackpointer seria uma variável global. Todo o código viveria em uma única função WebAssembly. O nível superior seria uma instrução switch gigante (ou equivalente baseado em br_table do WebAssembly) com uma ramificação para cada função. Cada função teria outra instrução switch com uma ramificação por bloco básico SSA. Há alguns detalhes que estou omitindo aqui, mas no quadro geral isso parece uma máquina de registro decente para mim. É claro que o desempenho disso depende muito de quão bem o WebAssembly pode transformar essas construções em código de máquina real.

Então, por favor, me diga: eu sou completamente ingênuo e maluco? Então fico feliz em adiar meus pensamentos até aprender mais. Caso contrário, isso pode servir como ponto de partida para algum documento de proposta real. Obrigado.

Além de todo o trabalho necessário no lado Go, há algumas coisas que o WebAssembly pode precisar antes que o runtime Go possa direcioná-lo.

O WebAssembly ainda não possui threads, mas está no roteiro e há uma especificação. https://github.com/WebAssembly/threads

Em relação à coleta de lixo, parece que pode haver várias opções no futuro, com base na palestra de Lin Clark https://youtu.be/HktWin_LPf4?t=28m31s

28:31
Então, hoje, você pode enviar seu próprio coletor de lixo com código se quiser, mas é
lento por alguns motivos e o grupo da comunidade está tornando possível o código WebAssembly
para ser usado apenas com o GC embutido, que é altamente otimizado que os navegadores
vem trabalhando, então ele rodará rápido e você terá essa integração.

Tal como acontece com o gomobile, há a ponte de linguagem para descobrir.

@randall77 também mencionou threads como um requisito para o GC. Este é realmente um requisito difícil para a primeira versão? A simultaneidade também pode ser feita em um único thread.

Em relação à implementação do CG, minha opinião pessoal é que não acredito em um único CG para governar todos. Prefiro que Go tenha um GC específico para Go e que Python tenha um GC específico para Python. Ao gerenciar completamente nosso próprio heap e pilhas na memória linear do WebAssembly, devemos ser capazes de usar o GC que o Go já possui, até onde posso ver atualmente.

@neelance Sim, vários threads reais do WebAssembly são agradáveis, não um requisito estrito.

A proposta do GC para WebAssembly ainda é um trabalho em andamento. Os interessados ​​podem participar aqui:

https://github.com/WebAssembly/gc

@neelance , não sei nada sobre compiladores, SSA, arquitetura de máquina, etc. Você pode dizer como o que você descreveu afetaria o tamanho binário? Se estou entendendo corretamente a eficiência do tamanho era um dos objetivos de alto nível do WebAssembly . Deve ser uma das prioridades para este compilador Go->WebAssembly também, certo?

@alxkchr Minha experiência é que a repetição devido ao clichê de geração de código pode ser muito compensada aplicando gzip. Ainda assim, minha proposta não é a solução mais eficiente em relação ao tamanho binário. Ainda assim, alguma solução que possa ser implementada em um tempo razoável é melhor do que nenhuma solução, certo? ;-) Também para mim, o tamanho binário não é uma das primeiras prioridades.

fyi: Eu comecei a implementar isso.

@neelance melhor notícia de todos os tempos :) você segue as especificações? (Espero)

A especificação Go? É um novo backend/destino para o compilador Go normal, então a especificação já está lá. ;)

quero dizer wasm spec :)

@neelance

fyi: Eu comecei a implementar isso.

Você pode, por favor, compartilhar qual abordagem será usada para abordar

Nossa conclusão atual é que não existe uma maneira eficiente de implementar
funcionalidade setjmp/longjmp atualmente, portanto, não é um alvo viável
de uma porta gc. Precisamos esperar até que a pilha se desfaça de verdade e
suporte ao tratamento de exceções.

(https://github.com/golang/go/issues/18892#issuecomment-276858667)

@neelance : Eu sei que ainda é cedo, mas acho que seria mais sensato nomear o wasm GOARCH wasm32 (idem para os pacotes)

@sbinet Vale a pena considerar que as arquiteturas/pacotes ARM são nomeados arm e arm64 (da mesma forma mips e mips64 ) em vez de arm32 e arm64 . No entanto, não sei se isso deve ser considerado um bom ou mau exemplo.

@SerkanSipahi Estou inicialmente visando o V8 (nodejs/chrome) e usando https://webassembly.github.io/spec/ como documentação sobre o que fazer.

@stuart-warren Sim, meu WIP está nesse ramo. No entanto, não tente usá-lo ainda, ele não pode ser facilmente construído agora e está cheio de código copiado e stubs/hacks. Vou anunciá-lo aqui quando atingir algum estado alfa.

@cznic Como escrito acima, não estou usando a instrução call do wasm, estou gerenciando minha própria pilha na memória linear. Assim setjmp/longjmp pode ser implementado.

@sbinet Na verdade, será uma arquitetura de 64 bits, pois o wasm possui operações de 64 bits.

@neelance não inteiramente. A especificação WebAssembly suporta apenas espaços de endereço de 32 bits por enquanto, uma especificação wasm64 está planejada para mais tarde .

Interessante, obrigado pelo link. Podemos querer revisitar isso mais tarde. Atualmente eu armazeno tudo em variáveis ​​de 64 bits, então int , uint e uintptr todos têm um tamanho de 64 bits. No entanto, apenas os primeiros 32 bits são usados ​​para endereçar a memória. Isso é mais fácil de implementar no início.

Parece wasm64p32 então (para seguir a nomenclatura nacl), ou algo assim
semelhante.

Em 4 de novembro de 2017 05:28, "Richard Musiol" [email protected] escreveu:

Interessante, obrigado pelo link. Podemos querer revisitar isso mais tarde.
Atualmente eu armazeno tudo em variáveis ​​de 64 bits, então int, uint e uintptr
todos têm um tamanho de 64 bits. No entanto, apenas os primeiros 32 bits são usados ​​para
memória de endereçamento. Isso é mais fácil de implementar no início.


Você está recebendo isso porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/golang/go/issues/18892#issuecomment-341889653 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AAgwpPTbfHRmoYNXLQfcPMVnARxb0UGrks5szEpjgaJpZM4L0o7D
.

Parece wasm64p32 então (para seguir a nomenclatura nacl), ou algo assim
semelhante.

Eu não acho que faça sentido ter dois números, porque haverá apenas uma arquitetura (com a escolha do tamanho do espaço de endereço). De webassembly.org :

wasm32 e wasm64 são apenas modos de WebAssembly, a serem selecionados por um sinalizador em um cabeçalho de módulo e não implicam diferenças semânticas fora de como a memória linear é tratada.

Eu não acho que faça sentido ter dois números, porque haverá apenas uma arquitetura (com a escolha do tamanho do espaço de endereço). De webassembly.org:

wasm32 e wasm64 são apenas modos de WebAssembly, a serem selecionados por um sinalizador em um cabeçalho de módulo e não implicam diferenças semânticas fora de como a memória linear é tratada.

Essa é uma declaração de aspiração. Pode ser verdade, mas o WebAssembly CG / WG não explorou o wasm64 o suficiente para que eu tenha certeza de que a afirmação é precisa.

Vamos deixar o @neelance trabalhar. Os nomes são fáceis de mudar mais tarde.

Eu sei que Go é compilado diretamente para instruções de máquina (AFAIK), mas estou me perguntando se alguém já compilou Go para C. Seria interessante tentar Go --> C --> wasm (embora não muito eficiente).

@TomerHeber pode ser possível em forma de tradução para C++, não compilação, mas provavelmente isso será mais trabalhoso do que compilação para o próprio wasm

Olá a todos. Aqui está uma atualização do meu trabalho: Estou fazendo um progresso muito bom, o que se deve muito ao ótimo trabalho da equipe Go e dos colaboradores até agora. A maior parte do código é compartilhada entre arquiteturas/plataformas, então não havia tanto quanto eu esperava que precisasse ser implementado.

Aqui está uma lista de algumas coisas que já estão funcionando bem:

  • executando o código wasm gerado em navegadores e em Node.js
  • operações básicas, conversões, etc.
  • interfaces
  • goroutines e canais
  • adiar/pânico/resgatar
  • lendo arquivos do disco ao usar Node.js
  • testes dos seguintes pacotes estão passando: bytes, container/heap, container/list, container/ring, encoding/ascii85, encoding/asn1, encoding/base32, encoding/binary, encoding/csv, encoding/hex, errors, flag, hash/adler32, hash/crc32, hash/crc64, hash/fnv, html, image, image/color, index/suffixarray, math, math/bits, path, sort, strconv, strings, text/scanner, text/tabwriter, unicode, unicode/utf8, unicode/utf16

Algumas coisas que ainda precisam ser trabalhadas:

  • reflexão
  • aumentando a pilha de goroutines
  • coleta de lixo
  • otimizações de desempenho
  • otimizações de tamanho de arquivo wasm
  • uma boa camada de interoperabilidade JS
  • muitos outros problemas para fazer mais testes de pacotes passarem

Estou muito feliz com o progresso em um mês e meio, e apenas no meu tempo livre. Acho que há uma boa chance de colocarmos isso no Go 1.11. Espere minha próxima atualização em janeiro, já que estarei de férias e depois há os feriados.

Algumas dessas tarefas podem ser paralelizadas? Alguns bits parecem interessantes para hack de férias.

Sinta-se à vontade para pesquisar e criar um PR no meu fork. Você também pode me encontrar no Gophers Slack.

Uma área de investigação pode ser otimizar o uso da pilha. Neste momento, a fase de alocação de registradores aloca registradores (variáveis ​​locais no wasm) para cada operação. get_local e set_local são sempre usados ​​antes e depois de cada operação. Isso é desnecessário se o valor puder simplesmente permanecer na pilha para ser usado por alguma operação posterior. Sugiro adicionar um pseudo registrador REG_STACK e fazer o gerador de instruções pular get_local e set_local se este registrador for usado. Então faça regalloc usar este registro quando apropriado.

Ré:

uma boa camada de interoperabilidade JS

Existe uma maneira sã de implementar isso para o wasm atualmente? Eu pensei que a interoperabilidade do Dom / js era uma saída com o wasm ainda. Se isso for possível, isso seria enorme!

Você pode importar e exportar funções que podem ter argumentos float64 e int32 e você tem a memória linear compartilhada. Todo o resto pode ser construído em torno disso. Apenas a coleta de lixo não seria tão legal.

(Eu tenho tentado postar isso no seu repositório (@neelance), mas não consegui descobrir como postar problemas ...)

seria possível usar a cadeia de ferramentas wabt em vez de chamar/importar js.foo ?
Achei mais fácil interagir com wabt em vez de uma instalação completa de nodejs :)

(Também estou tentando interpretar um programa simples main.go , traduzido para a.wasm aqui: go-interpreter/wagon#36...)

Habilitei problemas no meu fork, sinta-se à vontade para postar lá.

Eu realmente não entendo sua pergunta. Você está falando de wasm-interp ? Algo precisa compilar e executar o bytecode wasm e você precisa de algum ambiente JS para interagir com o resto do sistema, por exemplo, para imprimir no console.

Isso é ótimo. Para aqueles que desejam tentar compilar e executar Go to wasm -

  1. Crie um programa simples hello world que imprime no console.
  2. GOOS=js GOARCH=wasm ./bin/go build -o out.wasm wasm.go
  3. ./misc/wasm/go_js_wasm_exec out.wasm

Aproveitar !

Se você vincular go_js_wasm_exec ao seu PATH, poderá usar go run . ;-)

Olá pessoal, como está a situação da coleta de lixo com o Go for WASM? Começamos a falar sobre trazer Crystal e parece que Crystal provavelmente compartilha os mesmos problemas que Go tem atualmente com GC. Haveria alguma forma de colaborarmos ou ajudarmos o grupo de trabalho do WebAssembly com essa situação?

Sinta-se à vontade para entrar em contato com o tópico mencionado acima ou nos informar onde talvez possamos conversar / possivelmente colaborar sobre esse problema.

Pode ser que o caminho Opal seja a abordagem mais sensata por enquanto até que o WASM amadureça nessa área, mas seria bom saber disso com certeza antes de seguir esse caminho.

Ei pessoal, eu queria compartilhar o que tenho trabalhado nos últimos meses, pois acho que muito do código subjacente é relevante: https://github.com/matthewmueller/joy

Estou direcionando JS (ES3) agora, mas o compilador implementa um gráfico de dependência para todas as declarações (funcs, variáveis, etc.). Em seguida, ele classifica o gráfico e traduz apenas as declarações usadas no programa.

Eu não acho que seria muito difícil usar esse gráfico e direcionar o WebAssembly. Estou ansioso para ajudar e colaborar de qualquer maneira que eu puder.

Para mais informações aqui estão alguns links relevantes:

Em relação ao problema de GC para Crystal acima, isso também pode ter aplicação para Go, observe os comentários de @kripken e a seguinte discussão aqui: https://github.com/WebAssembly/binaryen/issues/1312#issuecomment -348409211

Potencialmente, vamos querer atualizar https://github.com/AppCypher/webassemblylanguages?

Espero que todos tenham tido boas férias. Aqui está a atualização prometida:

Desde minha última atualização, consegui colocar a reflexão, o crescimento da pilha e a coleta de lixo em funcionamento. Melhorias adicionais chegaram ao ponto em que os testes de 104 dos 136 pacotes stdlib estão passando agora. Além disso, muitos dos testes do compilador são verdes. Bom progresso!

Por favor, tenha em mente que estou me concentrando no suporte e correção de recursos. Ainda não fiz nenhuma otimização para desempenho ou tamanho de saída.

Eu aplaudo o experimento (e @neelance ty tanto para GopherJS para as goroutines superiores em comparação com Promise , você provavelmente me resgatou do C++ !), então o seguinte é apenas uma tentativa de adicionar informações potencialmente úteis e talvez até talvez para aumentar a conscientização sobre a incongruência entre Go e um alvo WASM. Também potencialmente para esclarecer a questão para alguns leitores. Também porque eu queria um lugar apropriado para despejar a seguinte citação de @rossberg que encontrei quando estava pensando independentemente em como compilar algo como gorountines para WASM.

@neelance respondeu :

@cznic respondeu :

@neelance escreveu :

Nós não usaríamos a instrução call do WebAssembly e, em vez disso, rolamos nosso próprio gerenciamento de pilha e mecanismo de chamada. As pilhas viveriam nessa memória linear e seriam gerenciadas pelo tempo de execução do Go. O stackpointer seria uma variável global. Todo o código viveria em uma única função WebAssembly. O nível superior seria uma declaração switch gigante (ou equivalente baseado em br_table do WebAssembly) com uma ramificação para cada função. Cada função teria outra instrução switch com uma ramificação por bloco básico SSA.

Você pode compartilhar qual abordagem será usada para abordar:

@minux escreveu :

Nossa conclusão atual é que não existe uma maneira eficiente de implementar
funcionalidade setjmp/longjmp atualmente, portanto, não é um alvo viável
de uma porta gc. Precisamos esperar até que a pilha se desfaça de verdade e
suporte ao tratamento de exceções.

@cznic Como escrito acima, não estou usando a instrução call do wasm, estou gerenciando minha própria pilha na memória linear. Assim setjmp/longjmp pode ser implementado.

De acordo com o “co-designer” e “autor de especificações” do WASM, as limitações de call , que o tornam inadequado para Go, têm algo a ver com segurança:

@rossberg escreveu :

Você não pode facilmente "substituir" a pilha de chamadas, pois não há como reificar endereços de retorno (*). No entanto, você pode implementar uma pilha de sombra para suas variáveis ​​locais na memória linear, se necessário.

Na verdade, o WebAssembly atualmente não expõe nenhuma noção de "pilha" interna. Como várias outras decisões de design, isso é importante: como o Wasm está sendo executado na Web, ele precisa ser "seguro". É por isso que é digitado, não tem comportamento indefinido, o código é separado da memória (e não endereçável), as conversões sobre os tipos de função são verificadas, etc. compilação, ferramentas úteis de depuração, etc.

O fluxo de controle de fato é semi-estruturado: as ramificações são apenas quebras e continuações, de modo que você não pode construir um fluxo de controle irredutível. Essa é uma característica também.

[…]

(*) Você presumivelmente poderia emular endereços de retorno explícitos com índices em um salto de tabela gigante, compilando todo o seu programa em uma única função de loop. Mas isso provavelmente seria muito lento e derrotaria muito do ecossistema WebAssembly .

Portanto, o desempenho e a interoperabilidade com o ecossistema WASM do que @neelance está tentando provavelmente não serão ideais?

Citando a habilidade de @neelance otimizando o desempenho do GopherJS .

Não sei o que você quer dizer com "interoperabilidade com o ecossistema WASM", então não posso comentar sobre isso. Em relação ao desempenho, posso dizer o seguinte:

Sim, a abordagem atual não é a maneira mais ideal de expressar o fluxo de controle no WebAssembly, mas funciona hoje . Talvez no futuro seja possível usar mais a instrução call do WebAssembly, mas para isso, o WebAssembly precisaria adicionar mais alguns recursos e precisaria de muito mais trabalho no lado Go para ser compatível com isso. Eu prefiro ter algo com 80% do desempenho que realmente funcione do que algo que tenha 100%, mas seja apenas hipotético. ;-)

Se você estiver interessado em mais detalhes técnicos, fale comigo no #webassembly em https://invite.slack.golangbridge.org/.

Não sei o que você quer dizer com "interoperabilidade com o ecossistema WASM", então não posso comentar sobre isso.

Talvez o que @rossberg esteja se referindo com _“derrotar grande parte do ecossistema WebAssembly”_, é a interoperabilidade com ferramentas e outras linguagens no ecossistema que não estão desviando call e a pilha de chamadas protegidas essencialmente emulando seu próprias continuações empregando tabelas switch ?

mas para isso, o WebAssembly precisaria adicionar mais alguns recursos

Espero que o WASM acomode melhor as linguagens com goroutines (threads verdes), porque afaics eles são indiscutivelmente superiores ao modelo JavaScript Promise desenrolamento de pilha.

Eu prefiro ter algo com 80% do desempenho que realmente funcione do que algo que tenha 100%, mas seja apenas hipotético. ;-)

Oh, eu concordo inteiramente, e é por isso que me certifiquei de prefaciar meu post anterior com meus aplausos por seus esforços prolíficos.

Quanto mais popular na web/WASM, podemos fazer Go ou outras linguagens que tenham threads verdes, então talvez a melhor chance que temos de obter melhores primitivas WASM (por exemplo, análogo ao -fsplit-stack do gcc ?) .

Se sua implementação realmente atingir 80% do desempenho ideal dentro das limitações atuais do WASM, ficarei agradavelmente surpreso. Se o resultado do desempenho for excessivamente ruim, isso pode limitar a demonstração da popularidade de threads verdes versus o modelo baseado em callback JavaScript Promise (o potencial da ironia de "derrotar grande parte do ecossistema WebAssembly" se presumirmos que é design foi orientado por uma prioridade na otimização do JavaScript :-).

Observe também que estou contemplando (sem decisão firme ainda) adicionar genéricos typeclass ao Go como um transpilador (e fornecendo minha análise da proposta de genéricos para Go 2), então também estou potencialmente envolvido em fazer minha parte para tentar aumentar popularidade.

@shelby3 Por favor, pare de usar a formatação que torna seu texto tão pequeno que não é legível. Se você considera que algo não vale a pena para as pessoas lerem, não escreva em primeiro lugar. Torná-lo ilegível sem dar uma dica do que está oculto faz com que os leitores gastem duas vezes (ou mais) tempo tentando decifrá-lo. Acho que é o oposto da sua intenção original.

@ shelby3 Editei suas postagens para parar de usar a formatação de texto pequeno. Por favor, pare de fazer isso.

Alterar https://golang.org/cl/102835 menciona este problema: go/build, cmd/dist: add js/wasm architecture

Alterar https://golang.org/cl/103255 menciona este problema: wasm: add scripts for running WebAssembly binaries

Alterar https://golang.org/cl/103256 menciona este problema: cmd/compile: add SSA config options noAvg and noHmul

Alterar https://golang.org/cl/103275 menciona este problema: cmd/compile/internal/gc: factor out beginning of SSAGenState.Call

Alterar https://golang.org/cl/103295 menciona este problema: cmd/compile: add wasm architecture

Alterar https://golang.org/cl/103535 menciona este problema: cmd/compile: wasm stack optimization

Alterar https://golang.org/cl/103795 menciona este problema: cmd/link: add wasm architecture

Alterar https://golang.org/cl/103877 menciona este problema: runtime: add js/wasm architecture

Alterar https://golang.org/cl/103915 menciona este problema: internal/bytealg: add wasm architecture

Ok, parece que muitos CLs estão começando a voar.
Como estamos em relação à política de portabilidade: https://github.com/golang/go/wiki/PortingPolicy ?
Em particular, como serão os construtores?
Presumo @neelance que você está se inscrevendo para manter a porta?
(Minhas desculpas se um dos CLs soletrar tudo isso, eu não li todos eles.)

Sim, vou manter o porto. @bradfitz está atualmente procurando configurar o construtor.

Alterar https://golang.org/cl/106995 menciona este problema: sync/atomic: add wasm architecture

Alterar https://golang.org/cl/106996 menciona este problema: math: add wasm architecture

Alterar https://golang.org/cl/106997 menciona este problema: time: add wasm architecture

Alterar https://golang.org/cl/106998 menciona este problema: mime: add wasm architecture

Alterar https://golang.org/cl/109195 menciona este problema: syscall/js: add package

Alterar https://golang.org/cl/109976 menciona este problema: syscall: enable some nacl code to be shared with js/wasm

Alterar https://golang.org/cl/109977 menciona este problema: os: add js/wasm architecture

Alterar https://golang.org/cl/109995 menciona este problema: net: add js/wasm architecture

Alterar https://golang.org/cl/110095 menciona este problema: crypto: add js/wasm architecture

Alterar https://golang.org/cl/110096 menciona este problema: all: skip unsupported tests for js/wasm

Alterar https://golang.org/cl/112736 menciona este problema: env/js-wasm, dashboard: add start of a js-wasm builder

Alterar https://golang.org/cl/113515 menciona este problema: misc/wasm: make wasm_exec.js more flexible

Depois de ler a arquitetura de webassembly para o documento Go , especificamente para a implementação de syscall JavaScript sendo construída no módulo 'fs' do Node e sendo amplamente não implementada para o lado do navegador, fiquei imaginando se poderíamos ou gostaríamos de tentar implementá-los usando as _novas_ APIs do navegador? Especificamente, a especificação da API FileSystem parece suportar pelo menos algumas das chamadas do sistema. (FileSystem ainda é um rascunho do editor e é implementado apenas no FireFox, Chrome e Opera. Além disso, é 'webkit-' prefixado nos dois últimos.)
Eu poderia tentar fazer uma prova de conceito, se você acha que isso pode ser uma abordagem decente.

Alterar https://golang.org/cl/114197 menciona este problema: runtime, sycall/js: add support for callbacks from JavaScript

Olá a todos, estou adorando o trabalho feito pela @neelance , e queria saber se com essa implementação do WASM (digamos, a primeira versão dele), será possível fazer uso de cgo também. Incorporar código C, compilar para GO, compilar para WASM. Isso seria uma maldita superpotência. Vocês todos estão fazendo um trabalho incrível. Impressionante.

@cmaster11 Feliz em saber que você gostou. :) Sobre sua pergunta: cgo não compila C to Go, em vez disso, compila ambas as linguagens em código de máquina com seus respectivos compiladores e depois mescla os resultados em um único binário. Você já pode usar emscripten para compilar código C para WebAssembly. Em teoria, deve ser possível carregar ambos os binários do WebAssembly em tempo de execução e fazê-los interagir. No entanto, acho improvável que o projeto Go gaste tempo facilitando esse caso de uso em um futuro próximo.

aparentemente principalmente Millennials

@ shelby3 Provavelmente sou mais velho que você e votei negativamente em você. O problema aqui é simplesmente sua incapacidade de se comunicar.

Não é uma questão de poder. @andybons realmente fez um favor editando sua postagem para que possa ser lida por outras pessoas.

js/wasm sem o webidl implica que não podemos interoperar muito com outras linguagens de dentro do navegador da web. A arquitetura wasm não parecia mencionar nada sobre o webidl.

Dei uma boa olhada na ferramenta python emscripten webidl quando aplicada à classe c++ Foo da seguinte maneira.
Eu adoraria ver um tipo de pato golang exposto via webidl da mesma maneira que a classe Foo.
Essa lógica seria interoperar com outros módulos wasm que são carregados ao mesmo tempo, mas precisamos dos idl's disponíveis para poder incluir e chamar seus stubs de marshalling. Caso contrário, precisamos de algum tipo de visualizador de objetos para determinar quais assinaturas de chamada estão disponíveis nos diferentes arquivos wasm.

python /usr/lib/emscripten/tools/webidl_binder.py Foo.idl glue
This generates:
glue.cpp
glue.js
WebIDLGrammar.pkl

emcc -v Foo.cpp my_glue_wrapper.cpp --post-js glue.js -o output.js
This generates:
output.js
output.wasm

emrun --list_browsers
emrun --browser chrome handcrafted_Foo.html 
emrun --browser firefox handcrafted_Foo.html 
firefox handcrafted_Foo.html &
chrome handcrafted_Foo.html &

$ cat Foo.h

#ifndef FOO_H
#define FOO_H (1)

class Foo {
public:
  int getVal();
  void setVal(int v);
 private:
  int nValue;
};

#endif

$ cat Foo.cpp

#include "Foo.h"

int Foo::getVal() {
  return nValue;
}

void Foo::setVal(int v) {
  nValue = v;
}

$ cat my_glue_wrapper.cpp

#include "Foo.h"
#include "glue.cpp"

$ cat Foo.idl

interface Foo {
        void Foo();
        long getVal();
        void setVal(long v);
};

$ cat handcrafted_Foo.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>WebAssembly Sample</title>
  </head>

  <body>
    <h1>Web Assembly</h1>

    <div class="output">
        <pre id="log"></pre>
    </div>

    <script src="output.js"></script>
    <script>      
      "use strict";


    function log() {
        document.querySelector('#log').textContent += Array.prototype.join.call(arguments, '') + '\n';
    }

    Module.onRuntimeInitialized = _ => {
      log(`blah `);
      var f = new Module.Foo();
      f.setVal(200);
      alert(f.getVal());
      log(`blah `);
    };

    </script>

  </body>
</html>

@omac777 , a interoperabilidade com outras linguagens não é uma meta para o suporte inicial do WebAssembly 1.11 do Go.

OK. Posso entender que o webidl não é um objetivo de curto prazo, mas tenho dúvidas sobre como tornar a saída do wasm útil. Em primeiro lugar, voltando para a classe Foo acima definida acima para uso com emscripten c++ junto com seu idl. Digamos que eu criei um tipo de pato golang que combinasse com ele. Então diga que eu exporto essas funções como funções C para que possam ser chamadas das implementações C++ Foo SetVal e GetVal. Eu sei que seria mais lento como resultado, mas tentar obter toda a implementação construída dentro do go seria o objetivo de longo prazo.

Como crio foo.go.wasm.a's e foo.go.wasm.so's? Cada foo.wasm precisa de seu próprio foo.go.js?
Se uma biblioteca cheia de foos diferentes fosse gerada, haveria um otherfoos.go.a.js gerado também?

Como faço para vincular go.wasm.a e go.wasm.so ao output.wasm emcc gerado conforme especificado em:
emcc -v Foo.cpp my_glue_wrapper.cpp --post-js glue.js -o output.js foo.go.wasm otherfoos.go.wasm.a

Como vincular funções sdl que o emcc suporta do wasm dentro do go, por exemplo.

Quando vai aparecer o suporte para goroutines completos, MAXCPUCores, canais para wasm?
Obrigado novamente.

@omac777 , o que está no escopo do Go 1.11 é o seguinte:

O código Go compila para um módulo WebAssembly e é executado em um navegador, e podemos chamar de volta e para trás entre JavaScript.

Ignore qualquer coisa sobre arquivos *.a ou *.so ou interoperabilidade com C ou GCC ou emcc ou SDL. Nada disso está no escopo e não funcionará.

Quando vai aparecer o suporte para goroutines completos, MAXCPUCores, canais para wasm?

Ele suporta totalmente goroutines e canais (isso faz parte do Go e é necessário). O WebAssembly suporta apenas um único núcleo, se é isso que você quer dizer com MAXCPUCores . Isso não é uma limitação do suporte do Go ou do WebAssembly do Go.

Então o que você está dizendo é que eu não vou ver nada assim tão cedo?
GOARCH=wasm GOOS=js go build -o awesome.wasm.so -buildmode=c-shared foo.go

Então, se tivermos navegadores da Web com 4 núcleos ou 20 núcleos, o wasm gerado pelo go usará apenas um desses núcleos no navegador da Web? Não entendo como você afirma que não é uma limitação do suporte a webassembly go ou go. Você está afirmando que é uma limitação da própria especificação do WEBASSEMBLY.org?

@omac777 - Sim, acredito que atualmente seja uma limitação do próprio WebAssembly, não da implementação do Go.

@omac777 O suporte a multithreading no WASM é um trabalho em andamento e levará um tempo até que seja lançado nos navegadores.

https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md

Então o que você está dizendo é que eu não vou ver nada assim tão cedo?
GOARCH=wasm GOOS=js go build -o awesome.wasm.so -buildmode=c-shared foo.go

Provavelmente em Go 1.12.

Para Go chamando C/C++, acho que provavelmente é possível encapsular funções C com JavaScript e, em seguida, chamar o wrapper JavaScript de Go, com Go 1.11.

eu sei que isso não é parte (talvez) do segmento, mas existe alguma documentação/tutoriais como usar WebAssembly (compilação, etc) em go v1.11?

@SerkanSipahi , ainda não. Mas haverá documentos antes do lançamento.

@SerkanSipahi Anotei as etapas que tomei para fazê-lo funcionar em https://blog.lazyhacker.com/2018/05/webassembly-wasm-with-go.html.

Há também este post, ainda relevante:
https://blog.gopheracademy.com/advent-2017/go-wasm/

ocorreu-me que não especificamos exatamente o mapeamento (nem o mecanismo) para o que vai para a seção export de um módulo wasm.

Eu arquivei # 25612.

Usando o alvo wasm, por favor esclareça/documente de go how to:
-use go para exportar/importar uma função go de e para wasm para outros idiomas usarem.
-link sdl2/webgl/qt para um binário golang
-catch todos os eventos sdl2/webgl/qt
-renunciar temporariamente o tempo de CPU de volta ao sistema operacional com um sono se estivermos em um loop. por exemplo
em scripten emscripten_sleep(10)

O arquivo output.html da ferramenta go não parece ter sucesso consistentemente com o firefox/chrome mesmo se houver um output.html construído com sucesso. Mais deve ser feito para garantir que output.html funcione. antes de apresentá-lo como um sucesso.

@omac777 , analisamos a maior parte disso acima. Mas para outros apenas sintonizando:

Usando o alvo wasm, por favor esclareça/documente de go how to:
-use go para exportar/importar uma função go de e para wasm para outros idiomas usarem.
-link sdl2/webgl/qt para um binário golang
-catch todos os eventos sdl2/webgl/qt

Por cima, nada disso está no escopo do Go 1.11. Não será suportado, documentado ou provavelmente até possível.

-renunciar temporariamente o tempo de CPU de volta ao sistema operacional com um sono se estivermos em um loop. por exemplo

@neelance obteve retornos de chamada e interoperabilidade entre JS e o agendador Go funcionando, então time.Sleep regular e amigos devem funcionar conforme o esperado.

Entendo que o Go 1.11 não terá nenhum desses, mas até que ponto/tempo qualquer um dos itens acima será considerado para ir. Existem pessoas que gostariam de ver o qt integrado de forma limpa com o go e atualmente a situação é que estamos contando com um terceiro para essa receita/qt que é tudo de bom mas existem limitações (atualmente não há wasm qt e nenhum alvo de arm de 64 bits do qt suportado). autocad tem uma solução webassembly para windows e macos usando emscripten, c++ e react. Ainda estou sentindo que o golang ainda está restrito a certas áreas de uso, em oposição a onde o c++ pode ser usado.

Há muito poder a ser obtido é a abordagem do c++:
emcc --clear-cache --clear-ports
em++ -v -std=c++1y hello_world_sdl.cpp -s USE_SDL=2 -s USE_SDL_IMAGE=2 EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s WASM=1 -o hello_world_sdl.html

Por que o golang não pode ter um comportamento semelhante?
ATUALIZAÇÃO: Estou corrigido. Golang não precisa de opções "-s" por causa das diretivas de compilação cgo incorporadas ao código go.

O cache limpo e as portas limpas, no entanto, são uma boa idéia, pois pode haver erros introduzidos ao migrar para diferentes versões de compilação do golang, ou seja, go1.9 para go1.10. go1.10.3 para go1.11 (quando migramos para o estilo de vida vgo). Recentemente, tive que fazer um "go build -a" entre as versões de compilação.
GOARCH=wasm GOOS=js go --clear-cache --clear-ports

Por que o golang não pode ter um comportamento semelhante?
GOARCH=wasm GOOS=js go --clear-cache --clear-ports

FWIW, o cache do Go não requer limpeza explícita para correção.

@neelance - Agora que os retornos de chamada chegaram, acredito que o suporte básico está completo. Vamos fechar esse bug ou você tinha outra coisa em mente?

Sim, acho que podemos fechar isso agora. 🎉

Ótimo trabalho!!! @neelance

Isso é incrível, ótimo trabalho @neelance!

Alterar https://golang.org/cl/120057 menciona este problema: doc/go1.11: mention GOOS/GOARCH values of WebAssembly port explicitly

Alterar https://golang.org/cl/120575 menciona este problema: cmd/dist: skip non-std tests on js/wasm

É apropriado abrir um problema para reduzir o tamanho do arquivo (se isso for possível)? Ou isso está sendo rastreado em outro lugar?

@matthewp , sinta-se à vontade para abrir um bug de tamanho específico do webassembly, se desejar. O geral é #6853.

Alterar https://golang.org/cl/120958 menciona este problema: net: re-implement built-in simulated network on JS and NaCl

O compilador golang possui integridade de fluxo de controle integrada (CFI)? Recentemente, examinei o seguinte sobre vulnerabilidades no WASM impedidas com CFI embutido no compilador clang:
https://www.fastly.com/blog/hijacking-control-flow-webassembly-program
https://github.com/trailofbits/clang-cfi-showcase/blob/master/cfi_vcall.cpp

Apenas dei uma olhada, mas parece-me que o post diz "WebAssembly não é uma linguagem de alto nível, como JavaScript, mas uma linguagem de baixo nível, portanto, certas classes de bugs podem ser aplicadas se a linguagem de origem (C ou Go) permitir ." Nenhuma surpresa. Isso significa que, se o Go tivesse esses problemas, eles também se aplicariam a outras arquiteturas, não apenas ao WebAssembly.

O WebAssembly trata principalmente de defender o navegador do código nefasto do WebAssembly. Não se trata tanto de fornecer garantias dentro da instância do WebAssembly (embora haja um pouco disso). Como @neelance disse, cabe aos compiladores LanguageX->WebAssembly fornecer quaisquer garantias de segurança necessárias.
Go não tem CFI. Eu não acho que seria fácil - no ponto em que um método é iniciado, já perdemos o vtable. Nós até perdemos o fato de que uma vtable foi usada.
Go é vulnerável a esse exploit, nos casos em que há algum paralelismo. Por enquanto, pelo menos, a porta WebAssembly Go (e WebAssembly, ponto final) não tem paralelismo, então esse exploit é apenas teórico. O pessoal do WebAssembly planeja implementar o paralelismo em algum momento.

@randall77 Como isso afeta linux/amd64 simples? O risco é de alguma forma maior para o WebAssembly?

O risco é o mesmo, independentemente da arquitetura (com a exceção de que o WebAssembly ainda não possui threads, portanto, na verdade, é zero para o WebAssembly no momento). Data races podem ser usadas para simular unsafe , sem importar unsafe .
Seria difícil explorar tal vulnerabilidade. Você precisa vincular um código não confiável ou, de alguma forma, encontrar e acionar um gadget em um binário existente que faz uma corrida de dados em um valor de interface e, em seguida, invoca um método no resultado.

Ok, então se o seu código Go não tem corridas de dados, então deve estar tudo bem. Além disso, ao executar código não confiável com o WebAssembly, você pode garantir que ele não possa escapar do ambiente WebAssembly, mesmo que seja capaz de ter corridas de dados ou simplesmente usar unsafe . Obrigado pelos insights interessantes e desculpe por estar um pouco fora do tópico para este problema.

Quanto mais eu examino esse uso de javascript de dentro do golang, mais eu percebo como uma infecção que degradará a qualidade e a manutenção a longo prazo do código golang. Deixe-me explicar. Aqui está um exemplo de um maravilhoso aplicativo wasm golang que faz uma mágica impressionante de colírio para os olhos.

https://github.com/stdiopt/gowasm-experiments/blob/master/bouncy/main.go

Os resultados são impressionantes. Aprofundar o código que realmente faz isso acontecer foi decepcionante porque exige que toda vez que você quiser chamar algo do lado do javascript, ele exija que você descreva o nome da função javascript ou o valor do javascript como uma string AT EVERY TURN . Como resultado, não há como o compilador golang verificar a correção do javascript em tempo de compilação. É "voar pela oração" em tempo de execução. Eu preferiria ver funções/variáveis/tipos golang em todos os lugares para manutenção a longo prazo, caso contrário, isso anula o propósito de usar golang para wasm na minha humilde opinião. BTW eu detesto javascript e sempre detestei. É muito freestyle. Por que essa linguagem persistiu nos navegadores da web? A resposta me escapa.

Obrigado por ouvir.

Concordo que chamar JS usando strings não é a melhor experiência. Talvez pudéssemos gerar interfaces Go a partir de IDL's de especificação de plataforma web. A desvantagem é como acompanhar a especificação, pois dependendo do navegador que vai rodar, as API's não estão disponíveis, enquanto por outro lado, novas especificações vão surgindo a todo momento à medida que a plataforma web evolui.

@omac777 Eu concordo com você. É por isso que espero que haja boas bibliotecas Go em torno dos níveis baixos do JS, para que a maioria dos usuários nunca precise tocar em syscall/js diretamente. Semelhante ao pacote syscall , é feio e quase ninguém o usa diretamente. ;-)

@omac777 Para GopherJS, muitas pessoas usam ligações de alto nível para várias APIs de navegador em vez do pacote js de baixo nível diretamente. Suspeito que uma abordagem semelhante também seja mais popular com o Wasm. Espero que muitas das ligações GopherJS adicionem suporte para Wasm no mesmo pacote e novos pacotes sejam criados conforme necessário.

Para referência, consulte https://github.com/gopherjs/gopherjs/wiki/Bindings , https://dmitri.shuralyov.com/talks/2016/Go-in-the-browser/Go-in-the-browser. slide#11 (e os 4 slides seguintes) e https://github.com/dominikh/go-js-dom/issues/57.

Também devemos considerar que há um monte de coisas no roteiro da webassembly:

https://webassembly.org/docs/future-features/

que melhorará bastante a história syscall , a longo prazo, como

referenciar DOM e outros objetos de API da Web diretamente do código WebAssembly;
chamar APIs da Web (passando primitivas ou objetos DOM/GC/API da Web) diretamente do WebAssembly sem chamar por meio de JavaScript; e
alocar e manipular com eficiência objetos GC diretamente do código WebAssembly.

De qualquer forma, obrigado @neelance et. al. para implementar a versão inicial. Tão maravilhoso! 🥇

E se houvesse uma implementação Go do DOM?

Documentos e scripts podem ser escritos e executados em Go, fazendo uso do sistema de tipos.

Em seguida, o código pode ser gerado a partir do Go DOM.

@fractalbach : Se a ligação de host do WebAssembly for confirmada e implementada pelo grupo de trabalho, você poderá realmente fazer a manipulação do DOM por meio do WebAssembly. Então seria razoável ter bibliotecas de alto nível para abstrair DOM, Documentos e scripts.

Mas antes disso, não é tão atraente fazer.

Go WebAssembly: vinculando estruturas a referências JS

https://medium.com/@nlepage/go -webassembly-binding-structures-to-js-references-4eddd6fd4d23

A abordagem é atraente. O uso é semelhante ao json marshallling/unmarshalling dentro de structs. Isso a torna uma habilidade facilmente transferível.

A única coisa que falta é como aplicar a mesma abordagem à digitação de pato? Eu preferiria não ter as declarações de função dentro da estrutura, mas fora dela autônoma da mesma maneira que a digitação de pato. Se o serviço existir, ele poderá usá-lo. Dessa forma, é facilmente modificável sem afetar a estrutura principal que contém os diferentes valores de não função desejados. Pedras tipo pato!

Obrigado novamente @neelance por todo o seu trabalho. É muito apreciado.
Obrigado Sr. Nicolas Lepage por seus pontos de vista. Eles realmente ajudam a cristalizar o que poderia ser um caminho melhor para interoperar com todo esse ruído de javascript até que a interface direta do wasm seja concluída.

Olá a todos, este é um tópico de alto tráfego com muitas pessoas inscritas. Ter uma discussão geral como essa não é proveitoso para aqueles apenas preocupados com o problema original - que é ter suporte WebAssembly para Go.

Sinta-se à vontade para continuar a discussão nos fóruns apropriados - golang-nuts/golang-dev. Ou se você tiver algo específico em mente, abra um novo problema.

Obrigada.

Esta página foi útil?
0 / 5 - 0 avaliações