Go: todo: compatibilidad con WebAssembly ("wasm")

Creado en 2 feb. 2017  ·  147Comentarios  ·  Fuente: golang/go

WebAssembly ("wasm") es similar a Native Client, pero difiere notablemente en que otros navegadores planean implementarlo.

http://webassembly.org/

Esto se ha preguntado varias veces, por lo que se trata de un error de seguimiento.

Ya sea que lo obtengamos a través de cmd/compile, gccgo o llvm-go, podemos publicar actualizaciones aquí.

Arch-Wasm NeedsFix

Comentario más útil

Hola a todos. Aquí hay una actualización de mi trabajo: Estoy progresando muy bien, lo que se debe en gran medida al gran trabajo del equipo de Go y los colaboradores hasta ahora. La mayor parte del código se comparte entre arquitecturas/plataformas, por lo que no era necesario implementar tanto como esperaba.

Aquí hay una lista de algunas cosas que ya están funcionando bien:

  • ejecutando el código wasm generado en navegadores y en Node.js
  • operaciones básicas, conversiones, etc.
  • interfaces
  • rutinas y canales
  • aplazar/pánico/rescatar
  • leer archivos desde el disco cuando se usa Node.js
  • las pruebas de los siguientes paquetes están pasando: 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

Algunas cosas que todavía necesitan trabajo:

  • reflexión
  • haciendo crecer la pila de goroutines
  • recolección de basura
  • optimizaciones de rendimiento
  • optimizaciones de tamaño de archivo wasm
  • una buena capa de interoperabilidad JS
  • muchos otros problemas para hacer que pasen más pruebas de paquetes

Estoy muy contento con el progreso en un mes y medio, y solo en mi tiempo libre. Creo que hay una buena posibilidad de que podamos incluir esto en Go 1.11. Espere mi próxima actualización en enero, ya que estaré de vacaciones y luego están las vacaciones.

Todos 147 comentarios

@cherrymui y yo discutimos la posibilidad de un puerto wasm GC en detalle en
los últimos días:

Nuestra conclusión actual es que no existe una manera eficiente de implementar
funcionalidad setjmp/longjmp actualmente, por lo tanto, no es un objetivo viable
de un puerto gc. Tenemos que esperar hasta que se desenrolle la pila real y
soporte de manejo de excepciones.

Todos los demás aspectos se veían bien, e incluso diseñamos un Go ABI bajo wasm
(pasar g y SP en la pila wasm y todo lo demás en la pila Go emulada) y
una forma de modificar el backend MIPS actual para admitir wasm emulando MIPS
se registra como variables locales wasm.

Quizás GopherJS pueda admitir wasm más fácilmente.

De gopherjs/gopherjs#432:

Sin embargo, no es una tecnología que GopherJS pueda usar. GopherJS compila en el nivel AST, no en el nivel del código de máquina.

WebAssembly podría usarse como backend para el compilador Go normal

@minux La falta de subprocesos o E/S asíncrona parece ser un problema mayor que las soluciones ABI que tendríamos que hacer debido a las peculiaridades de wasm.

@minux , @cherrymui
¿Podría publicar en algún lugar con más detalles lo que hizo y logró?
como sabrá, la comunidad de intérpretes go está considerando escribir un intérprete basado en LLVM o código de bytes wasm.
(incluso podemos tener un estudiante de GSoC trabajando en el intérprete de código de bytes wasm [1] , por lo tanto, solo la parte de "consumo de código de bytes", no la "producción de código de bytes a través de alguna cadena de herramientas basada en Go")

Minimizar la cantidad de esfuerzos duplicados y el desajuste de impedancia entre varios componentes sería excelente.

Recomiendo encarecidamente esto como una característica estratégica. Considere que en solo unos pocos años los programadores web se reunirán en hordas para elegir el lenguaje de su elección para compilarlo en un ensamblador web. Cuanto antes nos unamos a la carrera, mejor. Mozilla está impulsando a Rust como el lenguaje ensamblador web preferido...

Secundo lo que dijo @RaananHadar . Sería una pena que la especificación no se ajustara a las necesidades de Go, especialmente dado que el tiempo de ejecución de Go puede ser único.

EDITAR: Disculpas por la naturaleza MeToo de este comentario :) Gracias por el indicador Brad.

El contexto de la máquina de pila de WebAssembly consiste en una memoria lineal y una pila de operaciones. IIUC, posiblemente se pueda guardar el contexto de la VM guardando:

  1. PC actual, cadena de código de bytes
  2. La memoria lineal y la
  3. Pila de operaciones

A una lista global de contextos guardados en la estructura de contexto de VM, si corresponde.

Por lo tanto, un setjump debería simplemente restaurar estos valores y continuar con el bucle del intérprete como de costumbre (esto es similar a cómo la VM de bytecode de emacs implementa las señales: https://github.com/emacs-mirror/emacs/blob/master/src /códigobyte.c#L785). Se puede implementar un sistema de excepción además de esto, aunque no estoy seguro de qué rendimiento tendría.

Además, la especificación webassembly menciona que la altura de la pila en cualquier momento en el código de bytes se conoce estáticamente , lo que hace que todas las operaciones de la pila sean equivalentes a las operaciones en los registros únicos para cada posición en la pila. Este documento describe una forma de lograr tal mapeo de pila -> registro para convertir código de máquina de pila a código nativo, permitiéndonos usar setjmp/longjmp como de costumbre.

Editar: ¿Qué pasa con el uso panic() y recover() con valores especiales WasmException{} para señalar una excepción? recover ya hace el trabajo duro de desenredar la pila, no debería ser difícil restaurar el bucle del intérprete después de recuperarse de una excepción detectada.

Sí, básicamente la discusión con @cherrymui resultó en hallazgos similares.

El diseño inicial con @cherrymui es este:
(esta etapa se enfoca en hacer que $GOROOT/test/sieve.go funcione, no hay E/S asíncrona
considerado.)
reutilizamos el puerto MIPS, mapeando los 31 registros MIPS como WASM local
variables y solo usa la pila WASM
para resultados intermedios. No podemos usar el mecanismo de llamada de función de WASM para
la mayoría de las funciones de Go porque
la falta de apoyo para desenrollar la pila.
cambie el mips objlink (cmd/internal/obj) para emular cada instrucción MIPS
con las respectivas instrucciones WASM.
Esto hace que la implementación de setjmp/longjmp (también conocido como runtime.gogo) sea trivial y
reutiliza mucho del esfuerzo existente.

Go ya necesita implementar su propia pila, separada de la pila WASM,
porque Go necesita copias
pila, mapas de puntero de pila y soporte de desenrollado de pila, que no son
disponible en WASM.
(Esta estrategia también se alinea con el puerto LLVM, no podemos usar la pila LLVM para
casi las mismas razones
(a menos que agreguemos un pase de back-end personalizado a LLVM adecuado para codificar el puntero de pila
mapas).)

¿Probablemente necesitaremos usar un interruptor grande para enhebrar saltos indirectos? Esto es
similar al enfoque de NestedVM.
http://nestedvm.ibex.org/

Si decidimos implementar un backend WASM nativo, entonces podemos hacer esto:
el Go ABI es:
todos los parámetros (incluidos los resultados) en (emulado) Go stack,
en la entrada de la función, lo siguiente está en la pila WASM:
SP emulado, g.

La discusión ocurrió hace más de un mes, y probablemente olvidé algunos
detalles en este punto.

IIUC, puede descartar completamente la pila WASM (según la especificación). Un go stack extensible y copiable es todavía algo que necesita ser investigado.

Sí, el diseño inicial que mencioné solo usa la pila WASM para
intermedios utilizados en computación. Todos los datos están en el montón Go (lineal
memoria) o pseudo registros en variables locales WASM.

No espero que la especificación WASM incorpore la pila de movimiento/segmentación y copia.
Rara vez se usa en los lenguajes principales a los que se dirige WASM.

@bradfitz @minux @vibhavp ¿Cuál es el estado actual de wasm en golang? ¡No ha pasado nada desde el 13 de marzo! ¿Será posible transformar golang a wasm en el futuro? ¿Hay tal vez algún mapa de ruta de eso?

si alguien decide implementar el soporte de wasm, puedo ofrecer mi tiempo para tareas no globales

@SerkanSipahi , nadie está trabajando en esto. Este error está marcado a largo plazo. Si algo comienza a suceder, verá actualizaciones aquí.

¿Una buena hoja de ruta?

Tenemos DELVE y GDLV para depurar golang con una GUI. También funciona bien en todos los escritorios y el rendimiento es excelente.
https://github.com/derekparker/delve
https://github.com/aarzilli/gdlv

Ahora, GDLV se basa en NUCULAR, que es brillante con algunas abstracciones agradables.
https://github.com/aarzilli/nuclear

Entonces, estaba pensando que esta sería una buena base para hacer lo que ya se ha hecho aquí:

Ahora también hay 5 bibliotecas WASM go:
https://github.com/search?l=Go&q=webassembly&ref=simplesearch&type=Repositories&utf8=%E2%9C%93

Creo que varias partes del ecosistema Go utilizan NaCl. Es decir, no lo usa solo Chrome. Y en cualquier caso, el anuncio del blog es sobre PNaCl, que, aunque proporciona una funcionalidad similar a NaCl, en realidad es un producto completamente diferente basado en una tecnología diferente. Por lo tanto, eliminar el soporte de NaCl de Go es prematuro en la actualidad.

En cualquier caso, si eliminamos o no NaCl de Go no tiene nada que ver con si agregamos soporte para Web Assembly.

Diría que PNaCl es solo una extensión sobre NaCl para proporcionar un código independiente de la plataforma https://developer.chrome.com/native-client/nacl-and-pnacl Pregunté sobre la desactivación de NaCl aquí: https://groups.google. com/d/topic/native-client-discuss/wgN2ketXybQ/discusión

¿Si es posible obtener una lista de las diversas partes del ecosistema Go donde todavía se usa NaCl?
Revisarlo uno por uno hará que la transición a WebAssembly sea más interesante.

Diría que PNaCl es solo una extensión sobre NaCl

Puedes decir lo que quieras, pero eso no significa que tengas razón. Son ISA completamente diferentes, NaCL es solo el ISA de destino (x86/brazo) con algunas restricciones, mientras que PNaCl es un ISA completamente diferente para una máquina abstracta.

Go nunca ha sido compatible con PNaCL, y el puerto Go NaCL nunca fue adecuado para Chrome de todos modos. No tenía nada que ver con Chrome, no se podía usar en el navegador. Que Chrome abandone NaCL o PNaCL no tiene ninguna relevancia para Go. Nada, nada, ninguna relevancia . ¿Cuántas veces más hay que decir esto? Por supuesto, si NaCL se abandona por completo, Go se verá obligado en algún momento a abandonarlo también.

El soporte de WebAssembly en Go no tiene absolutamente nada que ver con NaCL. Go podría o no obtener soporte de WebAssembly. Si, o cuándo, podría obtener dicho soporte no tiene relevancia para el estado del puerto NaCL.

Aquí hay una parte muy importante del ecosistema donde usamos nacl: https://play.golang.org/p/MfJIq8wb5-

(que se ejecuta del lado del servidor, no nacl-in-a-browser)

Que Chrome abandone NaCL o PNaCL no tiene ninguna relevancia para Go. Nada, cero, sin relevancia.

¿Y quién admitirá Sandbox Loader y Toolchain entonces? Se importa del proyecto Chrome, que cambió los esfuerzos a WebAssembly. ¿No sería prudente seguir y ver si el área de juegos de Go ya se puede migrar de la zona de pruebas de NaCl a la zona de pruebas de WebAssembly? También se puede ejecutar del lado del servidor.

Creo que todos están a favor de admitir WebAssembly.

El momento de discutir el abandono del NaCl es después de que WebAssembly esté funcionando por completo. No tiene sentido discutirlo antes de eso.

@ianlancetaylor , ¿puede aclarar "después de que WebAssembly esté funcionando completamente"?

De un vistazo, parece que webassembly.org dice "la versión inicial de WebAssembly ha llegado a un consenso entre navegadores" y wasm está disponible en las versiones actuales o futuras de todos los proveedores de navegadores .

@ vine77 Me refiero a que después de que WebAssembly funcione completamente para los programas Go, al menos tan bien como funciona NaCl hoy.

Entonces, ¿cuál es la siguiente prueba que debería pasar para que WebAssembly funcione para los programas Go?

@techtonik Siento que hay cierta confusión aquí. Cuando decimos que WebAssembly debería funcionar para los programas Go, lo que queremos decir es que el compilador Go debería generar código WebAssembly que pueda ejecutarse en el navegador. Queremos decir que debería poder escribir algo como GOOS=wasm go build hello.go y obtener un programa que pueda ejecutarse dentro de un navegador. No estamos ni remotamente cerca de eso. Ni siquiera hemos comenzado. Así que no hay "próxima prueba". Hay mucho trabajo por hacer. Y, que yo sepa, nadie está trabajando activamente en ello.

@ianlancetaylor
Hay 4 implementaciones para golang. Uno realmente impresionante. Ver mi comentario anterior para los enlaces.

Chico, este hilo es como el auto Chevy Chase visto con los niños en el asiento trasero gritando "¿ya llegamos?" :)

@ joeblew99 : ninguno de esos enlaces son cosas que pueden compilar Ir a WebAssembly.
Son cosas como un compilador WebAssembly -> amd64 escrito en Go.

Tenía miedo de que dijeras eso. Lo suficientemente justo.
Entonces, ¿qué se necesita para el "levantamiento"? Así todos saben...
¿Gopherjs cometió el mismo error de no estar en el nivel correcto en la arquitectura de la cadena de herramientas del compilador/generación de código?

Hay una larga lista. La mayoría tiene que ver con la recolección de basura, de una forma u otra.

  • Genere código WebAssembly en el backend de SSA. El backend se usa para registrar máquinas, la adaptación a la máquina de pila de WebAssembly requerirá algo de trabajo.
  • ¿Qué es un puntero? WebAssembly no tiene un tipo de puntero.
  • ¿Cómo hacemos una introspección de la pila? Necesitaríamos esto para la recolección de basura, sin duda, pero también pánico/recuperación, impresión de rastreo, etc.
  • ¿Cómo suspendemos/reanudamos una gorutina?
  • ¿Cómo podemos diseñar el montón? WebAssembly solo proporciona esencialmente sbrk. Necesitamos un diseño de espacio de direcciones más general. ¿Dónde almacenamos información sobre intervalos, bits ptr/nonptr, etc.?
  • Multiproceso. WebAssembly no tiene noción de subprocesos en este momento, lo que necesitaríamos, por ejemplo, para hacer GC concurrente. También necesitaríamos cerraduras y tal vez operaciones atómicas.
  • ¿Cómo brindamos acceso al mundo exterior para paquetes como os y net?
  • WebAssembly no tiene soporte para "goto".

Probablemente no sea una lista completa.

Cuando decimos que WebAssembly debería funcionar para los programas Go, lo que queremos decir es que el compilador Go debería generar código WebAssembly que pueda ejecutarse en el navegador.

@ianlancetaylor , ¿sería más fácil apuntar primero a sitios no web? NaCl también se diseñó para ejecutarse primero en el navegador, pero luego obtuvo un cargador independiente del navegador, que Go usa actualmente. WebAseembly sin navegador - http://webassembly.org/docs/non-web/ - y habla de shells mínimos para la prueba.

@ randall77 , ¿es posible sacar una lista de verificación accionable de esta lista? ¿Como un número maestro con enlaces a números que investigan cada aspecto en detalle?

@techtonik wrt non-web: @vibhavp está trabajando en eso en el contexto de la pasantía de GSoC a la que me refería en algunas publicaciones anteriores.
está por ahí: https://github.com/go-interpreter/wagon

@techtonik : Creo que el lugar correcto para una lista de verificación de este tipo es un documento de propuesta sobre el apoyo a wasm. Una vez que se acepta una propuesta de este tipo y/o las personas están trabajando activamente en ella, seguramente podrían usar problemas para tareas individuales. Eso es prematuro en este punto: no conozco a nadie que esté trabajando activamente en ninguno de los dos (una propuesta o código).

Acepto una propuesta doc.
Todas las contradicciones/sí, quiero están en este hilo y solo necesitan estar juntas, con una hoja de ruta que permita establecer el equilibrio riesgo/recompensa.

También me gustaría verlo abordar los gráficos, ya que sobresale como un pulgar dolorido para mí.

Soy el autor de GopherJS , un compilador de Go to JavaScript. He escrito ese proyecto porque creo firmemente que debería haber alternativas al uso de JavaScript en el navegador, alternativas como Go y otras. Tengo un conocimiento decente sobre compiladores, SSA, arquitectura de máquinas, etc., pero probablemente me faltan muchos detalles, ya que aún no he escrito un backend de compilador para código de máquina. Es por eso que no me siento calificado para escribir un documento de propuesta completo. Aún así, me encantaría recibir comentarios críticos sobre mis pensamientos sobre Go y WebAssembly.

Al mirar WebAssembly, me parece muy diferente a los objetivos de código de máquina habituales como x86 o arm. Por ejemplo, su arquitectura es una máquina de pila en lugar de una máquina de registro. Esto significa que no es adecuado inmediatamente como otro objetivo más en la última etapa del compilador Go junto a x86 y amigos. Una solución podría ser no ponerlo allí, sino tener un enfoque significativamente diferente para generar WebAssembly. El código para este enfoque tendría que vivir además de las etapas del compilador existentes, lo que no sería bueno en absoluto. Incluso se podría considerar una bifurcación del compilador en este escenario. En resumen: no veo que esto suceda.

Puede haber una alternativa: emular lo que necesitamos. Podemos usar la máquina de pila para emular una máquina de registro y, con suerte, hacerlo de una manera razonablemente eficaz. WebAssembly tiene memoria lineal con instrucciones de carga y almacenamiento, lo cual es bueno. No usaríamos la instrucción call de WebAssembly en absoluto y, en su lugar, implementaríamos nuestro propio mecanismo de llamada y gestión de pila. Las pilas vivirían en esa memoria lineal y serían administradas por el tiempo de ejecución de Go. El stackpointer sería una variable global. Todo el código viviría en una sola función WebAssembly. El nivel superior sería una declaración de cambio gigante (o el equivalente basado en br_table de WebAssembly) con una rama para cada función. Cada función tendría otra declaración de cambio con una rama por bloque básico SSA. Hay algunos detalles que estoy omitiendo aquí, pero en general, esto me parece una máquina registradora decente. Por supuesto, el rendimiento de esto depende en gran medida de qué tan bien WebAssembly pueda transformar estas construcciones en código de máquina real.

Así que por favor dime: ¿Soy completamente ingenuo y loco? Entonces estoy feliz de posponer mis pensamientos hasta que haya aprendido más. De lo contrario, esto puede servir como punto de partida para algún documento de propuesta real. Gracias.

Además de todo el trabajo necesario en el lado de Go, hay algunas cosas que WebAssembly puede necesitar antes de que el tiempo de ejecución de Go pueda apuntar a él.

WebAssembly aún no tiene subprocesos, pero está en la hoja de ruta y hay una especificación. https://github.com/WebAssembly/hilos

Con respecto a la recolección de basura, parece que podría haber múltiples opciones en el futuro, según la charla de Lin Clark https://youtu.be/HktWin_LPf4?t=28m31s

28:31
Entonces, hoy, puede enviar su propio recolector de basura con código si lo desea, pero es
lento por algunas razones y el grupo de la comunidad está haciendo posible que el código WebAssembly
para usarse solo con el GC incorporado, que es uno altamente optimizado que los navegadores
han estado trabajando, por lo que se ejecutará rápido y tendrá esa integración.

Al igual que con gomobile, hay que resolver el puente lingüístico.

@ randall77 también mencionó hilos como un requisito para el GC. ¿Es este realmente un requisito difícil para la primera versión? La concurrencia también se puede hacer en un solo hilo.

Con respecto a la implementación de GC, mi opinión personal es que no creo en un GC para gobernarlos a todos. Prefiero que Go tenga un GC específico de Go y que Python tenga un GC específico de Python. Al administrar completamente nuestro propio montón y pilas en la memoria lineal de WebAssembly, deberíamos poder usar el GC que Go ya tiene, hasta donde puedo ver actualmente.

@neelance Sí, múltiples subprocesos reales de WebAssembly son un requisito agradable, no estricto.

La propuesta de GC para WebAssembly aún es un trabajo en progreso. Los interesados ​​pueden participar aquí:

https://github.com/WebAssembly/gc

@neelance , no sé nada sobre compiladores, SSA, arquitectura de máquinas, etc. ¿Puede decir cómo lo que ha descrito afectaría el tamaño binario? Si entiendo correctamente, la eficiencia del tamaño era uno de los objetivos de alto nivel de WebAssembly . Debería ser una de las prioridades para este compilador Go->WebAssembly también, ¿verdad?

@alxkchr Mi experiencia es que la repetición debida al modelo estándar de generación de código se puede compensar mucho aplicando gzip. Aún así, mi propuesta no es la solución más eficiente con respecto al tamaño binario. Aún así, alguna solución que se pueda implementar en un tiempo razonable es mejor que ninguna solución, ¿verdad? ;-) También para mí personalmente, el tamaño binario no es una de las primeras prioridades.

Para tu información: He comenzado a implementar esto.

Las mejores noticias de @neelance :) ¿sigues las especificaciones? (Ojala)

¿La especificación Go? Es un nuevo backend/objetivo para el compilador Go normal, por lo que la especificación ya está ahí. ;)

Me refiero a las especificaciones de wasm :)

@neelance

Para tu información: He comenzado a implementar esto.

¿Puede compartir qué enfoque se utilizará para abordar

Nuestra conclusión actual es que no existe una manera eficiente de implementar
funcionalidad setjmp/longjmp actualmente, por lo tanto, no es un objetivo viable
de un puerto gc. Tenemos que esperar hasta que se desenrolle la pila real y
soporte de manejo de excepciones.

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

@neelance : Sé que aún es pronto, pero creo que sería más inteligente nombrar el wasm GOARCH wasm32 (lo mismo para los paquetes)

@sbinet Vale la pena considerar que las arquitecturas/paquetes ARM se denominan arm y arm64 (de manera similar mips y mips64 ) en lugar de arm32 y arm64 . Sin embargo, no sé si eso debe considerarse un buen o mal ejemplo.

@SerkanSipahi Inicialmente estoy apuntando a V8 (nodejs/chrome) y uso https://webassembly.github.io/spec/ como documentación sobre qué hacer.

@stuart-warren Sí, mi WIP está en esa sucursal. Sin embargo, no intente usarlo todavía, no se puede construir fácilmente en este momento y está lleno de código copiado y stubs/hacks. Lo anunciaré aquí cuando alcance algún estado alfa.

@cznic Como se escribió anteriormente, no estoy usando la instrucción call de wasm en absoluto, estoy administrando mi propia pila en la memoria lineal. Por lo tanto, se puede implementar setjmp/longjmp.

@sbinet En realidad, será una arquitectura de 64 bits ya que wasm tiene operaciones de 64 bits.

@neelance no del todo. La especificación WebAssembly solo admite espacios de direcciones de 32 bits por ahora, se planea una especificación wasm64 para más adelante .

Interesante, gracias por el enlace. Es posible que deseemos revisar esto más adelante. Actualmente almaceno todo en variables de 64 bits, por lo que int , uint y uintptr tienen un tamaño de 64 bits. Sin embargo, solo los primeros 32 bits se utilizan para direccionar la memoria. Esto es más fácil de implementar al principio.

Entonces suena como wasm64p32 (para seguir el nombre de nacl), o algo así
similar.

El 4 de noviembre de 2017 a las 5:28 a. m., "Richard Musiol" [email protected] escribió:

Interesante, gracias por el enlace. Es posible que deseemos revisar esto más adelante.
Actualmente almaceno todo en variables de 64 bits, así que int, uint y uintptr
todos tienen un tamaño de 64 bits. Sin embargo, sólo los primeros 32 bits se utilizan para
memoria de direccionamiento. Esto es más fácil de implementar al principio.


Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/golang/go/issues/18892#issuecomment-341889653 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AAgwpPTbfHRmoYNXLQfcPMVnARxb0UGrks5szEpjgaJpZM4L0o7D
.

Entonces suena como wasm64p32 (para seguir el nombre de nacl), o algo así
similar.

No creo que tenga sentido tener dos números, porque solo habrá una arquitectura (con una opción de tamaño de espacio de direcciones). De webassembly.org :

wasm32 y wasm64 son solo modos de WebAssembly, para ser seleccionados por una bandera en el encabezado de un módulo, y no implican ninguna diferencia semántica fuera de cómo se maneja la memoria lineal.

No creo que tenga sentido tener dos números, porque solo habrá una arquitectura (con una opción de tamaño de espacio de direcciones). De webassembly.org:

wasm32 y wasm64 son solo modos de WebAssembly, para ser seleccionados por una bandera en el encabezado de un módulo, y no implican ninguna diferencia semántica fuera de cómo se maneja la memoria lineal.

Esa es una declaración aspiracional. Podría resultar ser cierto, pero WebAssembly CG / WG no ha explorado wasm64 lo suficiente como para estar seguro de que la declaración es precisa.

Dejemos que @neelance trabaje. Los nombres son fáciles de cambiar más adelante.

Sé que Go se compila directamente en las instrucciones de la máquina (AFAIK), pero me pregunto si alguien alguna vez ha compilado Go to C. Sería interesante probar Go -> C -> wasm (aunque no muy eficiente).

@TomerHeber puede ser posible en forma de traducción a C ++, no de compilación, pero probablemente esto será más trabajo que compilación para wasm en sí

Hola a todos. Aquí hay una actualización de mi trabajo: Estoy progresando muy bien, lo que se debe en gran medida al gran trabajo del equipo de Go y los colaboradores hasta ahora. La mayor parte del código se comparte entre arquitecturas/plataformas, por lo que no era necesario implementar tanto como esperaba.

Aquí hay una lista de algunas cosas que ya están funcionando bien:

  • ejecutando el código wasm generado en navegadores y en Node.js
  • operaciones básicas, conversiones, etc.
  • interfaces
  • rutinas y canales
  • aplazar/pánico/rescatar
  • leer archivos desde el disco cuando se usa Node.js
  • las pruebas de los siguientes paquetes están pasando: 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

Algunas cosas que todavía necesitan trabajo:

  • reflexión
  • haciendo crecer la pila de goroutines
  • recolección de basura
  • optimizaciones de rendimiento
  • optimizaciones de tamaño de archivo wasm
  • una buena capa de interoperabilidad JS
  • muchos otros problemas para hacer que pasen más pruebas de paquetes

Estoy muy contento con el progreso en un mes y medio, y solo en mi tiempo libre. Creo que hay una buena posibilidad de que podamos incluir esto en Go 1.11. Espere mi próxima actualización en enero, ya que estaré de vacaciones y luego están las vacaciones.

¿Se pueden paralelizar algunas de esas tareas? Algunos bits parecen interesantes para el truco de las vacaciones.

Siéntase libre de investigarlo y crear un PR en mi tenedor. También puedes encontrarme en Gophers Slack.

Un área de investigación podría ser la optimización del uso de la pila. En este momento, la fase de asignación de registros asigna registros (variables locales en wasm) para cada operación. get_local y set_local siempre se usan antes y después de cada operación. Esto no es necesario si el valor simplemente pudiera permanecer en la pila para ser utilizado por alguna operación posterior. Sugiero agregar un pseudo registro REG_STACK y hacer que el generador de instrucciones salte get_local y set_local si se usa este registro. Luego haga que regalloc use este registro cuando sea apropiado.

Re:

una buena capa de interoperabilidad JS

¿Existe una manera sensata de implementar esto para wasm actualmente? Pensé que la interoperabilidad de Dom/js era una salida con wasm todavía. Si esto es posible, ¡sería enorme!

Puede importar y exportar funciones que pueden tener argumentos float64 y int32 y tiene la memoria lineal compartida. Todo lo demás se puede construir alrededor de eso. Solo la recolección de basura no sería tan agradable.

(He estado tratando de publicar esto en su repositorio (@neelance) pero no pude averiguar cómo publicar problemas...)

¿sería posible usar la cadena de herramientas wabt en lugar de llamar/importar js.foo ?
He encontrado que es más fácil interactuar con wabt en lugar de una instalación completa nodejs :)

(También estoy tratando de interpretar un programa simple main.go , traducido a a.wasm aquí: go-interpreter/wagon#36...)

He habilitado problemas en mi bifurcación, siéntase libre de publicar allí.

Realmente no entiendo tu pregunta. ¿Estás hablando de wasm-interp ? Algo necesita compilar y ejecutar el código de bytes wasm y necesita algún entorno JS para interactuar con el resto del sistema, por ejemplo, para imprimir en la consola.

Esto es genial. Para aquellos que quieran intentar compilar y ejecutar Go to wasm:

  1. Cree un programa simple de hola mundo que se imprima en la consola.
  2. GOOS=js GOARCH=wasm ./bin/go build -o out.wasm wasm.go
  3. ./misc/wasm/go_js_wasm_exec out.wasm

Disfrutar !

Si vincula go_js_wasm_exec en su RUTA, incluso puede usar go run . ;-)

Hola chicos, ¿cómo está la situación de recolección de basura con Go for WASM? Comenzamos a hablar sobre traer a Crystal y parece que Crystal probablemente comparte los mismos problemas que Go tiene actualmente con GC. ¿Habría alguna forma de colaborar o ayudar al grupo de trabajo de WebAssembly con esta situación?

No dude en participar en el hilo mencionado anteriormente o háganos saber dónde podríamos chatear / posiblemente colaborar en este tema.

Puede ser que el camino Opal sea el enfoque más sensato por ahora hasta que WASM madure en esta área, pero sería bueno saberlo con certeza antes de seguir ese camino.

Hola amigos, quería compartir lo que he estado trabajando en los últimos meses, ya que creo que gran parte del código subyacente es relevante: https://github.com/matthewmueller/joy

Estoy apuntando a JS (ES3) en este momento, pero el compilador implementa un gráfico de dependencia para todas las declaraciones (funciones, variables, etc.). Luego ordena el gráfico y traduce solo las declaraciones que se usan en el programa.

No creo que sea demasiado difícil usar este gráfico y apuntar a WebAssembly. Estoy deseando ayudar y colaborar en todo lo que pueda.

Para obtener más información, aquí hay algunos enlaces relevantes:

Con respecto al problema de GC para Crystal anterior, esto también podría tener una aplicación para Go, tenga en cuenta los comentarios de @kripken y la siguiente discusión aquí: https://github.com/WebAssembly/binaryen/issues/1312#issuecomment -348409211

Potencialmente querremos actualizar https://github.com/AppCypher/webassemblylanguages?

Espero que todos hayan tenido buenas vacaciones. Aquí está la actualización prometida:

Desde mi última actualización, logré poner en marcha la reflexión, el crecimiento de la pila y la recolección de elementos no utilizados. Las mejoras adicionales lo llevaron al punto de que las pruebas de 104 de los 136 paquetes stdlib están pasando ahora. Además, muchas de las pruebas del compilador son verdes. ¡Buen progreso!

Tenga en cuenta que actualmente me estoy enfocando en el soporte y la corrección de funciones. Todavía no he realizado ninguna optimización para el rendimiento o el tamaño de salida.

Aplaudo el experimento (y @neelance ty tanto por GopherJS por las gorutinas superiores en comparación con Promise , ¡probablemente me rescataste de C++ !), por lo que lo siguiente es simplemente un intento de agregar información potencialmente útil y tal vez incluso para crear conciencia sobre la incongruencia entre Go y un objetivo WASM. También potencialmente para aclarar el problema para algunos lectores. También porque quería un lugar apropiado para volcar la siguiente cita de @rossberg que encontré cuando estaba pensando de forma independiente en cómo compilar algo como gorountines para WASM.

@neelance respondió :

@cznic respondió :

@neelance escribió :

No usaríamos la instrucción call de WebAssembly en absoluto y, en su lugar, desplegaríamos nuestro propio mecanismo de llamada y gestión de pila. Las pilas vivirían en esa memoria lineal y serían administradas por el tiempo de ejecución de Go. El stackpointer sería una variable global. Todo el código viviría en una sola función WebAssembly. El nivel superior sería una declaración de cambio gigante (o el equivalente basado en br_table de WebAssembly) con una rama para cada función. Cada función tendría otra declaración de cambio con una rama por bloque básico SSA.

¿Puede compartir qué enfoque se utilizará para abordar:

@minux escribió :

Nuestra conclusión actual es que no existe una manera eficiente de implementar
funcionalidad setjmp/longjmp actualmente, por lo tanto, no es un objetivo viable
de un puerto gc. Tenemos que esperar hasta que se desenrolle la pila real y
soporte de manejo de excepciones.

@cznic Como se escribió anteriormente, no estoy usando la instrucción call de wasm en absoluto, estoy administrando mi propia pila en la memoria lineal. Por lo tanto, se puede implementar setjmp/longjmp.

Según el "codiseñador" y "autor de especificaciones" de WASM, las limitaciones de call , que lo hacen inapropiado para Go, tienen algo que ver con la seguridad:

@rosberg escribió :

No puede "reemplazar" fácilmente la pila de llamadas, ya que no hay forma de cosificar las direcciones de retorno (*). Sin embargo, puede implementar un shadow stack para sus variables locales en la memoria lineal si lo necesita.

De hecho, WebAssembly actualmente no expone ninguna noción de "pila" integrada. Al igual que otras decisiones de diseño, eso es importante: debido a que Wasm se ejecuta en la Web, tiene que ser "seguro". Es por eso que se escribe, no tiene un comportamiento indefinido, el código se separa de la memoria (y no es direccionable), se verifican los tipos de funciones, etc. Tener un concepto explícito de función también permite otros beneficios, como la asignación efectiva de registros, paralelo o perezoso. compilación, útiles herramientas de depuración, etc.

De hecho, el flujo de control está semiestructurado: las ramas son en realidad solo interrupciones y continuaciones, por lo que no se puede construir un flujo de control irreducible. Esa es una característica también.

[…]

(*) Presumiblemente, podría emular direcciones de retorno explícitas con índices en un salto de tabla gigante, compilando todo su programa en una sola función de bucle. Pero eso probablemente sería bastante lento y derrotaría gran parte del ecosistema WebAssembly .

Entonces, ¿el rendimiento y la interoperabilidad con el ecosistema WASM de lo que @neelance está intentando probablemente serán subóptimos?

Citando la habilidad de @neelance optimizando el rendimiento de GopherJS .

No sé a qué te refieres con "interoperabilidad con el ecosistema WASM", así que no puedo comentar al respecto. En cuanto al rendimiento te puedo decir esto:

Sí, el enfoque actual no es la forma más óptima de expresar el flujo de control en WebAssembly, pero funciona hoy . Tal vez sea posible en el futuro usar más la instrucción call de WebAssembly, pero para eso, WebAssembly necesitaría agregar algunas características más y necesitaría mucho más trabajo en el lado Go para ser compatible con eso. Prefiero tener algo con el 80 % del rendimiento que realmente funcione que algo que tenga el 100 % pero que sea solo hipotético. ;-)

Si está interesado en más detalles técnicos, hable conmigo en #webassembly en https://invite.slack.golangbridge.org/.

No sé a qué te refieres con "interoperabilidad con el ecosistema WASM", así que no puedo comentar al respecto.

Tal vez a lo que se refiere @rossberg con _“derrotar gran parte del ecosistema de WebAssembly”_ es la interoperabilidad con herramientas y otros lenguajes en el ecosistema que no eluden call y la pila de llamadas protegida al emular esencialmente su propias continuaciones empleando tablas switch ?

pero para eso, WebAssembly necesitaría agregar algunas características más

Espero que WASM se adapte mejor a los idiomas con goroutines (subprocesos verdes), porque, en realidad , son indiscutiblemente superiores al modelo JavaScript Promise desenrollado de pilas.

Prefiero tener algo con el 80 % del rendimiento que realmente funcione que algo que tenga el 100 % pero que sea solo hipotético. ;-)

Oh, estoy completamente de acuerdo, por eso me aseguré de comenzar mi publicación anterior con mi aplauso por sus prolíficos esfuerzos.

Cuanto más popular en la web/WASM, podemos hacer Go u otros lenguajes que tengan subprocesos verdes, entonces tal vez tengamos más posibilidades de obtener mejores primitivas WASM (por ejemplo, ¿análogas a -fsplit-stack de gcc ?) para un mejor rendimiento eventualmente .

Si su implementación realmente alcanza el 80 % del rendimiento óptimo dentro de las limitaciones actuales de WASM, estaré gratamente sorprendido. Si el resultado del rendimiento es excesivamente malo, entonces podría limitar la demostración de la popularidad de los subprocesos verdes frente al modelo basado en devolución de llamada JavaScript Promise (el potencial de la ironía de "derrotar gran parte del ecosistema WebAssembly" si suponemos que es el diseño ha sido impulsado por una prioridad en la optimización de JavaScript :-).

Tenga en cuenta también que estoy contemplando (todavía no tengo una decisión firme) agregar genéricos de clase de tipos a Go como transpilador (y proporcionar mi análisis de la propuesta de genéricos para Go 2), por lo que también estoy potencialmente involucrado en hacer mi parte para tratar de aumentar popularidad.

@shelby3 Deje de usar formatos que hagan que su texto sea tan pequeño que no sea legible. Si considera que algo no vale la pena que la gente lo lea, no lo escriba en primer lugar. Hacerlo ilegible sin dar una pista de lo que está oculto hace que los lectores pasen el doble (o más) de tiempo tratando de descifrarlo. Creo que es lo contrario de su intención original.

@ shelby3 Edité sus publicaciones para dejar de usar el formato de texto pequeño. Por favor, deja de hacer eso.

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

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

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

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

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

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

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

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

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

Ok, parece que muchos CL están comenzando a pasar volando.
¿Cómo nos va con respecto a la política de portabilidad: https://github.com/golang/go/wiki/PortingPolicy ?
En particular, ¿cómo serán los constructores?
¿Asumo @neelance que te estás registrando para mantener el puerto?
(Mis disculpas si uno de los CL explica todo esto, no los he leído todos).

Sí, voy a mantener el puerto. @bradfitz actualmente está buscando configurar el constructor.

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

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

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

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

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

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

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

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

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

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

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

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

Después de leer la arquitectura webassembly para el documento Go , específicamente para la implementación de JavaScript syscall que se está construyendo en el módulo 'fs' de Node, y que en gran medida no está implementada para el lado del navegador, me pregunto si podríamos o querríamos intentar implementar esto usando las _nuevas_ API del navegador? Específicamente, la especificación de la API de FileSystem parece que podría admitir al menos algunas de las llamadas al sistema. (FileSystem sigue siendo un borrador del editor y solo se implementa en FireFox, Chrome y Opera. Además, tiene el prefijo 'webkit-' en los dos últimos).
Podría intentar hacer una prueba de concepto, si cree que este podría ser un enfoque decente.

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

Hola a todos, me encanta el trabajo realizado por @neelance , y me preguntaba si con esta implementación de WASM (digamos, la primera versión), será posible usar cgo también. Incrustar código C, compilar en GO, compilar en WASM. Eso sería un maldito superpoder. Todos ustedes están haciendo un trabajo increíble. Increíble.

@cmaster11 Me alegra saber que te gusta. :) Sobre su pregunta: cgo no compila C to Go, sino que compila ambos lenguajes en código de máquina con sus respectivos compiladores y luego fusiona los resultados en un solo binario. Ya puede usar emscripten para compilar código C en WebAssembly. En teoría, debería ser posible cargar ambos binarios de WebAssembly en tiempo de ejecución y hacerlos interactuar. Sin embargo, creo que es poco probable que el proyecto Go dedique tiempo a facilitar este caso de uso en un futuro próximo.

aparentemente en su mayoría Millennials

@ shelby3 Probablemente soy mayor que tú y te voté negativo. El problema aquí es simplemente su incapacidad para comunicarse.

No es una cuestión de poder. @andybons en realidad te hizo un favor al editar tu publicación para que otros puedan leerla.

La compatibilidad con js/wasm sin webidl implica que no podemos interoperar mucho con otros idiomas desde el navegador web. La arquitectura wasm no parecía mencionar nada sobre webidl.

Eché un buen vistazo a la herramienta emscripten webidl python cuando se aplicó a la clase c ++ Foo de la siguiente manera.
Me encantaría ver un tipo de pato golang expuesto a través de webidl de la misma manera que la clase Foo.
Esa razón sería interoperar con otros módulos wasm que se cargan al mismo tiempo, pero necesitamos que los idl estén disponibles para poder incluir y llamar a sus stubs de clasificación. De lo contrario, necesitamos algún tipo de visor de objetos para determinar qué firmas de llamadas están disponibles en los diferentes archivos 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 , la interoperabilidad con otros lenguajes no es un objetivo para el soporte WebAssembly inicial de Go 1.11.

Está bien. Puedo entender que webidl no es un objetivo a corto plazo, pero tengo preguntas sobre cómo hacer que la salida de wasm sea útil. En primer lugar, volviendo a la clase Foo anterior definida anteriormente para usar con emscripten c ++ junto con su idl. Digamos que creé un tipo de pato golang que coincidía con él. Luego diga que exporto esas funciones como funciones de C para que se puedan llamar desde las implementaciones de C++ Foo SetVal y GetVal. Sé que, como resultado, sería más lento, pero el objetivo a largo plazo sería intentar que toda la implementación se construyera en el acto.

¿Cómo creo foo.go.wasm.a's y foo.go.wasm.so's? ¿Cada foo.wasm necesita su propio foo.go.js?
Si se generara una biblioteca llena de diferentes foos, ¿también se generaría otro otherfoos.go.a.js?

¿Cómo vinculo go.wasm.a y go.wasm.so al emcc output.wasm generado como se especifica en:
emcc -v Foo.cpp my_glue_wrapper.cpp --post-js glue.js -o output.js foo.go.wasm otherfoos.go.wasm.a

Cómo vincular funciones de sdl compatibles con emcc desde wasm dentro de go, por ejemplo.

¿Cuándo aparecerá el soporte para goroutines completos, MAXCPUCores, canales para wasm?
Gracias de nuevo.

@omac777 , lo que está dentro del alcance de Go 1.11 es esto:

El código Go se compila en un módulo WebAssembly y se ejecuta en un navegador, y podemos llamar de un lado a otro entre JavaScript.

Ignore todo lo relacionado con los archivos *.a o *.so o la interoperabilidad con C o GCC o emcc o SDL. Nada de eso está en el alcance y no funcionará.

¿Cuándo aparecerá el soporte para goroutines completos, MAXCPUCores, canales para wasm?

Es totalmente compatible con rutinas y canales (eso es parte de Go y es obligatorio). WebAssembly solo admite un solo núcleo, si eso es lo que quiere decir con MAXCPUCores . Esa no es una limitación de la compatibilidad con WebAssembly de Go o Go.

Entonces, ¿lo que estás diciendo es que no veré nada como esto en el corto plazo?
GOARCH=wasm GOOS=js go build -o awesome.wasm.so -buildmode=c-shared foo.go

Entonces, si tenemos navegadores web con 4 núcleos o 20 núcleos, ¿el wasm generado por go solo usará uno de esos núcleos en el navegador web? No entiendo cómo afirma que no es una limitación del soporte de ensamblaje web go or go. ¿Está afirmando que es una limitación de las especificaciones de WEBASSEMBLY.org?

@ omac777 - Sí, creo que actualmente es una limitación de WebAssembly en sí, no de la implementación de Go.

@omac777 La compatibilidad con subprocesos múltiples en WASM es un trabajo en progreso y pasará un tiempo hasta que se lance en los navegadores.

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

Entonces, ¿lo que estás diciendo es que no veré nada como esto en el corto plazo?
GOARCH=wasm GOOS=js go build -o impresionante.wasm.so -buildmode=c-shared foo.go

Probablemente en Go 1.12.

Para Go llamando a C/C++, creo que probablemente sea posible envolver funciones de C con JavaScript, luego llamar al envoltorio de JavaScript desde Go, con Go 1.11.

Sé que esto no es parte (tal vez) del hilo, pero ¿hay alguna documentación/tutoriales sobre cómo usar WebAssembly (compilación, etc.) en go v1.11?

@SerkanSipahi , todavía no. Pero habrá documentos antes del lanzamiento.

@SerkanSipahi Escribí los pasos que tomé para que funcionara en https://blog.lazyhacker.com/2018/05/webassembly-wasm-with-go.html.

También está esta publicación, aún relevante:
https://blog.gopheracademy.com/advent-2017/go-wasm/

se me ocurrió que no hemos (IIRC) especificado exactamente el mapeo (ni el mecanismo) para lo que entra en la sección export de un módulo wasm.

He presentado #25612.

Usando el objetivo wasm, aclare/documente desde go how to:
-use go para exportar/importar una función go hacia y desde wasm para que la usen otros idiomas.
-vincular sdl2/webgl/qt a un binario golang
-captura todos los eventos sdl2/webgl/qt
-Renunciar temporalmente al tiempo de la CPU al sistema operativo con una suspensión si estamos en un bucle. por ejemplo
en emscripten emscripten_sleep(10)

El archivo output.html de la herramienta go no parece tener éxito consistentemente con firefox/chrome, incluso si hubo una compilación exitosa de output.html. Se debe hacer más para garantizar que output.html funcione. antes de presentarlo como un éxito.

@ omac777 , ya hemos hablado de la mayor parte de eso. Pero para otros simplemente sintonizando:

Usando el objetivo wasm, aclare/documente desde go how to:
-use go para exportar/importar una función go hacia y desde wasm para que la usen otros idiomas.
-vincular sdl2/webgl/qt a un binario golang
-captura todos los eventos sdl2/webgl/qt

Según lo anterior, nada de eso está dentro del alcance de Go 1.11. No será compatible, documentado o probablemente incluso posible.

-Renunciar temporalmente al tiempo de la CPU al sistema operativo con una suspensión si estamos en un bucle. por ejemplo

@neelance obtuvo devoluciones de llamada e interoperabilidad entre JS y el programador Go, por lo que los time.Sleep normales y los amigos deberían funcionar como se esperaba.

Entiendo que Go 1.11 no tendrá ninguno de estos, pero ¿cuán lejos/durante cuánto tiempo se considerará cualquiera de los anteriores para ir? Hay personas a las que les encantaría ver que qt se integre limpiamente con go y actualmente la situación es que confiamos en un tercero para esa receta/qt que está bien pero hay limitaciones (actualmente no hay wasm qt ni qt 64bit arm targets soportado). autocad tiene una solución de ensamblaje web para windows y macos usando emscripten, c++ y react. Todavía siento que golang todavía está restringido para ciertas áreas de uso en lugar de donde se puede usar c ++.

Se puede tener mucho poder en el enfoque de 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 qué golang no puede tener un comportamiento similar?
ACTUALIZACIÓN: Estoy corregido. Golang no necesita interruptores "-s" debido a las directivas de compilación cgo integradas en el código go.

Sin embargo, borrar la memoria caché y borrar los puertos son una buena idea, ya que pueden presentarse errores al migrar a diferentes versiones de compilación de golang, es decir, go1.9 a go1.10. go1.10.3 a go1.11 (cuando migramos al estilo de vida vgo). Recientemente tuve que hacer un "go build -a" entre las versiones de go build.
GOARCH=wasm GOOS=js go --clear-cache --clear-ports

¿Por qué golang no puede tener un comportamiento similar?
GOARCH=wasm GOOS=js go --clear-cache --clear-ports

FWIW, el caché de Go no requiere una limpieza explícita para su corrección.

@neelance : ahora que están disponibles las devoluciones de llamada, creo que el soporte básico está completo. ¿Cerramos este error o tenías algo más en mente?

Sí, creo que podemos cerrar esto ahora. 🎉

¡¡¡Buen trabajo!!! @neelance

¡Esto es increíble, gran trabajo @neelance!

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

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

¿Es apropiado abrir un problema para reducir el tamaño del archivo (si eso es posible)? ¿O eso está siendo rastreado en otro lugar?

@matthewp , no dude en abrir un error de tamaño específico de ensamblaje web si lo desea. El general es el #6853.

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

¿El compilador golang tiene integridad de flujo de control integrada (CFI)? Recientemente revisé lo siguiente relacionado con las vulnerabilidades en WASM evitadas con CFI integrado en el compilador clang:
https://www.fastly.com/blog/hijacking-control-flow-webassembly-program
https://github.com/trailofbits/clang-cfi-showcase/blob/master/cfi_vcall.cpp

Solo lo hojeé, pero me parece que la publicación dice "WebAssembly no es un lenguaje de alto nivel como JavaScript, sino un lenguaje de bajo nivel, por lo que se pueden aplicar ciertas clases de errores si el lenguaje de origen (C o Go) lo permite ." No hay sorpresa allí. Esto significa que si Go tuviera tales problemas, también se aplicarían a otras arquitecturas, no solo a WebAssembly.

WebAssembly se trata principalmente de defender el navegador del código nefasto de WebAssembly. No se trata tanto de dar garantías dentro de la instancia de WebAsssembly (aunque algo de eso hay). Como dijo @neelance , depende de los compiladores LanguageX->WebAssembly proporcionar las garantías de seguridad requeridas.
Go no tiene CFI. No creo que sea fácil: en el punto en que comienza un método, ya hemos perdido la vtable. Incluso hemos perdido el hecho de que se utilizó una vtable.
Go es vulnerable a este exploit, en los casos en que exista algún paralelismo. Por ahora, al menos, el puerto WebAssembly Go (y WebAssembly, punto) no tiene paralelismo, por lo que este exploit es solo teórico. Sin embargo, la gente de WebAssembly planea implementar el paralelismo en algún momento.

@ randall77 ¿Cómo afecta esto a linux/amd64 simple? ¿Es el riesgo de alguna manera mayor para WebAssembly?

El riesgo es el mismo independientemente de la arquitectura (con la excepción de que WebAssembly aún no tiene subprocesos, por lo que en realidad es cero para WebAssembly por el momento). Las carreras de datos se pueden usar para simular unsafe , sin importar unsafe .
Sería difícil explotar tal vulnerabilidad. O necesita vincular un código que no es de confianza, o de alguna manera encontrar y activar un dispositivo en un binario existente que realiza una carrera de datos en un valor de interfaz y luego invoca un método en el resultado.

Bien, entonces si su código Go no tiene carreras de datos, entonces debería estar bien. Además, al ejecutar código que no es de confianza con WebAssembly, puede asegurarse de que no pueda escapar del entorno de WebAssembly, aunque pueda tener carreras de datos o simplemente usar unsafe . Gracias por las ideas interesantes y perdón por estar un poco fuera de tema para este problema.

Cuanto más examino este uso de JavaScript desde dentro de golang, más lo percibo como una infección que degradará la calidad y el mantenimiento a largo plazo del código de golang. Dejame explicar. Aquí hay un ejemplo de una maravillosa aplicación wasm golang que hace una magia impresionante.

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

Los resultados son impresionantes. Sin embargo, profundizar más en el código que realmente hace que suceda fue decepcionante porque requiere que cada vez que desee llamar a algo desde el lado de javascript, requiere que describa el nombre de la función de javascript o el valor de javascript como una cadena EN CADA TURNO . Como resultado, no hay forma de que el compilador de golang verifique la corrección de javascript en el momento de la compilación. Es "volar por oración" en tiempo de ejecución. Preferiría ver funciones/variables/tipos de golang en todas partes para el mantenimiento a largo plazo; de lo contrario, anula el propósito de usar golang para wasm en mi humilde opinión. Por cierto, detesto javascript y siempre lo he hecho. Es demasiado estilo libre. ¿Por qué ese lenguaje ha persistido en los navegadores web? La respuesta se me escapa.

Gracias por escuchar.

Estoy de acuerdo en que llamar a JS usando cadenas no es la mejor experiencia. Tal vez podríamos generar interfaces Go a partir de IDL de especificación de plataforma web. La desventaja es cómo mantenerse al día con las especificaciones, porque dependiendo del navegador que se ejecute, las API no están disponibles, mientras que, por otro lado, las nuevas especificaciones siguen llegando todo el tiempo a medida que evoluciona la plataforma web.

@ omac777 Estoy de acuerdo contigo. Es por eso que espero que haya buenas bibliotecas de Go alrededor de los niveles bajos de JS para que la mayoría de los usuarios nunca tengan que tocar syscall/js directamente. Similar al paquete syscall , es feo y casi nadie lo usa directamente. ;-)

@omac777 Para GopherJS, muchas personas usan enlaces de alto nivel para varias API de navegador en lugar del paquete js de bajo nivel directamente. Sospecho que un enfoque similar también será más popular con Wasm. Espero que muchos de los enlaces de GopherJS agreguen soporte para Wasm en el mismo paquete, y se crearán nuevos paquetes según sea necesario.

Para referencia, consulte https://github.com/gopherjs/gopherjs/wiki/Bindings , https://dmitri.shuralyov.com/talks/2016/Go-in-the-browser/Go-in-the-browser. diapositiva n.º 11 (y las siguientes 4 diapositivas) y https://github.com/dominikh/go-js-dom/issues/57.

También debemos considerar que hay un montón de cosas en la hoja de ruta de ensamblaje web:

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

eso mejorará bastante la historia syscall , a la larga, como

hacer referencia a DOM y otros objetos de API web directamente desde el código de WebAssembly;
llame a las API web (pasando primitivas u objetos DOM/GC/API web) directamente desde WebAssembly sin llamar a través de JavaScript; y
asigne y manipule de manera eficiente los objetos GC directamente desde el código WebAssembly.

De todos modos, gracias @neelance et. Alabama. para implementar la versión inicial. ¡Tan genial! 🥇

¿Qué pasaría si hubiera una implementación Go del DOM?

Los documentos y scripts se pueden escribir y ejecutar en Go, haciendo uso del sistema de tipos.

Luego, el código podría generarse desde Go DOM.

@fractalbach : si el grupo de trabajo confirma e implementa el enlace de host de WebAssembly, en realidad puede manipular DOM a través de WebAssembly. Entonces sería razonable tener bibliotecas de alto nivel para abstraer DOM, Documentos y scripts.

Pero antes de eso, no es tan atractivo hacerlo.

Ir a WebAssembly: vincular estructuras a referencias JS

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

El enfoque es atractivo. El uso es similar a json marshallling/unmarshalling dentro de las estructuras. Eso lo convierte en una habilidad fácilmente transferible.

Lo único que falta es cómo aplicar el mismo enfoque a la tipificación de patos. Preferiría no tener las declaraciones de función dentro de la estructura, pero fuera de ella independientes de la misma manera que la escritura pato. Si el servicio existe, puede usarlo. De esa manera, es fácilmente modificable sin afectar la estructura central que contiene los diferentes valores no funcionales deseados. ¡Rocas que tiran patos!

Gracias de nuevo a @neelance por todo tu trabajo. Es muy apreciado.
Gracias Sr. Nicolas Lepage por sus puntos de vista. Realmente ayudan a cristalizar lo que podría ser un mejor camino para interoperar con todo este ruido de javascript mientras tanto hasta que se complete la interfaz wasm directa.

Hola a todos, este es un hilo de alto tráfico con mucha gente suscrita. Tener una discusión general como esta no es fructífero para aquellos que solo están preocupados por el problema original, que es tener soporte de WebAssembly para Go.

Siéntase libre de continuar la discusión en los foros apropiados: golang-nuts/golang-dev. O si tiene algo específico en mente, abra un nuevo número.

Gracias.

¿Fue útil esta página
0 / 5 - 0 calificaciones