Go: tous : prise en charge de WebAssembly ("wasm")

Créé le 2 févr. 2017  ·  147Commentaires  ·  Source: golang/go

WebAssembly ("wasm") est similaire à Native Client, mais différent notamment en ce que d'autres navigateurs prévoient de l'implémenter.

http://webassembly.org/

Cela a été demandé à plusieurs reprises, il s'agit donc d'un bogue de suivi.

Que nous l'obtenions via cmd/compile, gccgo ou llvm-go, nous pouvons publier des mises à jour ici.

Arch-Wasm NeedsFix

Commentaire le plus utile

Salut à tous. Voici une mise à jour de mon travail : je fais de très bons progrès, ce qui est en grande partie dû à l'excellent travail de l'équipe Go et des contributeurs jusqu'à présent. La plupart du code est partagé entre les architectures/plates-formes, il n'y avait donc pas autant que je m'y attendais à implémenter.

Voici une liste de certaines choses qui fonctionnent déjà bien :

  • exécuter le code wasm généré dans les navigateurs et dans Node.js
  • opérations de base, conversions, etc.
  • interfaces
  • goroutines & canaux
  • différer/paniquer/secourir
  • lire les fichiers du disque lors de l'utilisation de Node.js
  • les tests des packages suivants sont en cours : 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

Certaines choses qui ont encore besoin de travail :

  • réflexion
  • faire pousser la pile de goroutines
  • collecte des ordures
  • optimisations des performances
  • optimisations de la taille des fichiers wasm
  • une belle couche d'interopérabilité JS
  • beaucoup d'autres problèmes pour faire passer plus de tests de paquets

Je suis très content des progrès réalisés en un mois et demi, et uniquement sur mon temps libre. Je pense qu'il y a de fortes chances que nous puissions intégrer cela dans Go 1.11. Attendez-vous à ma prochaine mise à jour en janvier, puisque je serai en vacances et puis il y a les vacances.

Tous les 147 commentaires

@cherrymui et moi avons longuement discuté de la possibilité d'un port wasm GC dans
ces derniers jours :

Notre conclusion actuelle est qu'il n'existe aucun moyen efficace de mettre en œuvre
fonctionnalité setjmp/longjmp actuellement, donc ce n'est pas une cible viable
d'un port gc. Nous devons attendre jusqu'à ce que la vraie pile se déroule et
prise en charge de la gestion des exceptions.

Tous les autres aspects semblaient bien, et nous avons même conçu un Go ABI sous wasm
(passez g et SP sur la pile wasm et tout le reste sur la pile Go émulée) et
un moyen de modifier le backend MIPS actuel pour prendre en charge wasm en émulant MIPS
s'enregistre en tant que variables locales wasm.

Peut-être que GopherJS peut prendre en charge wasm plus facilement.

Depuis gopherjs/gopherjs#432 :

Cependant, ce n'est pas une technologie que GopherJS peut utiliser. GopherJS compile au niveau AST, pas au niveau du code machine.

WebAssembly pourrait être utilisé comme backend pour le compilateur Go normal

@minux Le manque de threads ou d'e/s asynchrones semble être un problème plus important que les solutions de contournement ABI que nous aurions à faire à cause des bizarreries de wasm.

@minux , @cherrymui
pourriez-vous publier quelque part plus de détails sur ce que vous avez fait et réalisé ?
comme vous le savez peut-être, la communauté go-interpreter envisage d'écrire un interpréteur basé sur LLVM ou wasm bytecode.
(nous pouvons même avoir un étudiant GSoC travaillant sur l'interpréteur de bytecode wasm [1] , donc, juste la partie "consommation de bytecode", pas la "production de bytecode via une chaîne d'outils basée sur Go")

minimiser la quantité d'efforts dupliqués et la non-concordance d'impédance entre les différents composants serait formidable.

Je le recommande fortement comme élément stratégique. Considérez que dans quelques années seulement, les programmeurs Web afflueront en hordes pour choisir le langage de leur choix à compiler en assemblage Web. Plus tôt nous rejoindrons la course, mieux ce sera. Mozilla pousse Rust durement en tant que langage d'assemblage Web de choix...

Je seconde ce que @RaananHadar a dit. Il serait dommage que la spécification ne réponde pas aux besoins de Go, d'autant plus que l'exécution de Go peut être unique.

EDIT : Toutes mes excuses pour la nature MeToo de ce commentaire :) Merci pour le pointeur Brad.

Le contexte de machine de pile WebAssembly se compose d'une mémoire linéaire et d'une pile d'opérations. IIUC, la sauvegarde du contexte VM peut éventuellement se faire en sauvegardant :

  1. PC actuel, chaîne de bytecode
  2. La mémoire linéaire et la
  3. Pile d'opérations

À une liste globale de contextes enregistrés dans la structure de contexte de machine virtuelle, le cas échéant.

Ainsi, un setjump devrait simplement restaurer ces valeurs et continuer avec la boucle d'interpréteur comme d'habitude (ceci est similaire à la façon dont la machine virtuelle emacs bytecode implémente les signaux : https://github.com/emacs-mirror/emacs/blob/master/src /bytecode.c#L785). Un système d'exception peut être implémenté en plus de cela, bien que je ne sois pas sûr de sa performance.

De plus, la spécification webassembly mentionne que la hauteur de la pile à tout moment dans le bytecode est statiquement connue , ce qui rend toutes les opérations de la pile équivalentes aux opérations sur les registres uniques à chaque position sur la pile. Cet article décrit un moyen d'obtenir une telle pile -> mappage de registre pour convertir le code machine de la pile en code natif, nous permettant d'utiliser setjmp/longjmp comme d'habitude.

Edit : Qu'en est-il de l'utilisation panic() et recover() avec des valeurs spéciales WasmException{} pour signaler une exception ? recover effectue déjà le travail difficile de déroulement de la pile, il ne devrait pas être difficile de restaurer la boucle de l'interpréteur après avoir récupéré d'une exception interceptée.

Oui, fondamentalement, la discussion avec @cherrymui a abouti à des conclusions similaires.

La conception initiale avec @cherrymui est la suivante :
(cette étape se concentre sur le fonctionnement de $GOROOT/test/sieve.go, aucune E/S asynchrone n'est
pris en considération.)
nous réutilisons le port MIPS, en mappant les 31 registres MIPS en tant que WASM local
variables et utiliser uniquement la pile WASM
pour les résultats intermédiaires. Nous ne pouvons pas utiliser le mécanisme d'appel de fonction de WASM pour
la plupart des fonctions Go car
l'absence de support de déroulement de pile.
changer le mips objlink (cmd/interne/obj) pour émuler chaque instruction MIPS
avec les instructions WASM respectives.
Cela rend l'implémentation de setjmp/longjmp (alias runtime.gogo) triviale et
réutilise beaucoup d'efforts existants.

Go doit déjà implémenter sa propre pile, distincte de la pile WASM,
parce que Go doit être copiable
pile, cartes de pointeur de pile et support de déroulement de pile, qui ne sont pas
disponible auprès de WASM.
(Cette stratégie s'aligne également sur le port LLVM, nous ne pouvons pas utiliser la pile LLVM pour
presque les mêmes raisons
(sauf si nous ajoutons une passe backend personnalisée à LLVM proprement dite pour encoder le pointeur de pile
Plans).)

Nous aurons probablement besoin d'utiliser un gros interrupteur pour enfiler des sauts indirects ? C'est
similaire à l'approche de NestedVM.
http://nestedvm.ibex.org/

Si nous décidons d'implémenter un backend WASM natif, nous pouvons le faire :
le Go ABI est :
tous les paramètres (y compris les résultats) sur la pile Go (émulée),
à l'entrée de la fonction, les éléments suivants se trouvent sur la pile WASM :
SP émulé, g.

La discussion a eu lieu il y a plus d'un mois, et j'ai probablement oublié
détails à ce stade.

IIUC, vous pouvez complètement jeter la pile WASM (selon la spécification). Une pile go extensible et copiable est encore quelque chose qui doit être étudié.

Oui, la conception initiale que j'ai mentionnée n'utilise que la pile WASM pour
intermédiaires utilisés dans le calcul. Toutes les données sont soit sur le tas Go (linéaire
mémoire) ou des pseudo-registres dans les variables locales WASM.

Je ne m'attends pas à ce que la spécification WASM incorpore le déplacement/segmentation et la pile de copie.
Il est rarement utilisé par les langages grand public ciblés par WASM.

@bradfitz @minux @vibhavp Quel est l'état actuel du wasm à golang ? Rien ne s'est passé depuis le 13 mars ! sera-t-il possible de transformer golang en wasm dans le futur ? y a-t-il peut-être une feuille de route de cela?

si quelqu'un décide d'implémenter le support wasm, je peux offrir mon temps pour des tâches non globales

@SerkanSipahi , personne ne travaille là-dessus. Ce bogue est marqué LongTerm. Si quelque chose commence à se produire, vous verrez des mises à jour ici.

Une bonne feuille de route ?

Nous avons DELVE et GDLV pour déboguer golang avec une interface graphique. Cela fonctionne bien aussi sur tous les ordinateurs de bureau et les performances sont excellentes.
https://github.com/derekparker/delve
https://github.com/aarzilli/gdlv

Maintenant, GDLV est basé sur NUCULAR qui est brillant avec de belles abstractions.
https://github.com/aarzilli/nucular

Donc je pensais que ce serait une bonne base pour faire ce qui a déjà été fait ici:

Il existe désormais 5 bibliothèques WASM go :
https://github.com/search?l=Go&q=webassembly&ref=simplesearch&type=Repositories&utf8=%E2%9C%93

Je crois que le NaCl est utilisé par diverses parties de l'écosystème Go. Autrement dit, il n'est pas utilisé uniquement par Chrome. Et dans tous les cas, cette annonce de blog concerne le PNaCl, qui, bien qu'il offre des fonctionnalités similaires au NaCl, est en fait un produit complètement différent basé sur une technologie différente. Il est donc prématuré à l'heure actuelle de supprimer le support NaCl de Go.

En tout cas, que nous supprimions ou non NaCl de Go n'a rien à voir avec le fait que nous ajoutions ou non la prise en charge de Web Assembly.

Je dirais que PNaCl n'est qu'une extension sur NaCl pour fournir un code indépendant de la plate-forme https://developer.chrome.com/native-client/nacl-and-pnacl J'ai posé des questions sur la dépréciation de NaCl ici - https://groups.google. com/d/topic/native-client-discuss/wgN2ketXybQ/discussion

Est-il possible d'obtenir la liste des différentes parties de l'écosystème Go où le NaCl est encore utilisé ?
Les parcourir un par un rendra la transition vers WebAssembly plus intéressante.

Je dirais que PNaCl n'est qu'une extension sur NaCl

Vous pouvez dire ce que vous voulez, mais cela ne veut pas dire que vous avez raison. Ce sont des ISA complètement différents, NaCL est juste l'ISA cible (x86/arm) avec quelques restrictions, tandis que PNaCl est un ISA complètement différent pour une machine abstraite.

Go n'a jamais pris en charge PNaCL, et le port Go NaCL n'a jamais été adapté à Chrome de toute façon. Cela n'avait rien à voir avec Chrome, ce n'était pas utilisable dans le navigateur. Que Chrome abandonne NaCL ou PNaCL n'a aucune pertinence pour Go. Nada, nul, aucune pertinence . Combien de fois cela doit-il être dit ? Bien sûr, si NaCL est complètement abandonné, Go sera obligé à un moment donné de l'abandonner également.

La prise en charge de WebAssembly dans Go n'a absolument rien à voir avec NaCL. Go peut ou non bénéficier de la prise en charge de WebAssembly. Si, ou quand il pourrait obtenir un tel support n'a aucune pertinence pour l'état du port NaCL.

Voici une partie très importante de l'écosystème où nous utilisons nacl : https://play.golang.org/p/MfJIq8wb5-

(qui s'exécute côté serveur, pas nacl-in-a-browser)

Que Chrome abandonne NaCL ou PNaCL n'a aucune pertinence pour Go. Nada, nul, aucune pertinence.

Et qui prendra alors en charge le chargeur de bac à sable et la chaîne d'outils ? Il est importé du projet Chrome, qui a transféré les efforts vers WebAssembly. Ne serait-il pas sage de suivre et de voir si Go playground peut déjà être porté du bac à sable NaCl vers le bac à sable WebAssembly ? Il peut également être exécuté côté serveur.

Je pense que tout le monde est en faveur de soutenir WebAssembly.

Le moment de discuter de l'abandon de NaCl est après que WebAssembly fonctionne pleinement. Il ne sert à rien d'en discuter avant.

@ianlancetaylor , pouvez-vous préciser "après que WebAssembly fonctionne pleinement" ?

En un coup d'œil, il semble que webassembly.org indique que "la version initiale de WebAssembly a atteint un consensus entre navigateurs" et que wasm est disponible dans les versions de navigateur actuelles ou futures de tous les fournisseurs de navigateurs .

@ vine77 Je veux dire après que WebAssembly fonctionne pleinement pour les programmes Go, au moins aussi bien que NaCl fonctionne aujourd'hui.

Alors, quel est le prochain test qui devrait réussir pour que WebAssembly fonctionne pour les programmes Go ?

@techtonik J'ai l'impression qu'il y a une certaine confusion ici. Lorsque nous disons que WebAssembly doit fonctionner pour les programmes Go, nous voulons dire que le compilateur Go doit générer du code WebAssembly pouvant s'exécuter dans le navigateur. Nous voulons dire que vous devriez pouvoir écrire quelque chose comme GOOS=wasm go build hello.go et obtenir un programme qui peut s'exécuter dans un navigateur. Nous ne sommes même pas proches de cela. Nous n'avons même pas commencé. Il n'y a donc pas de "prochain test". Il y a beaucoup de travail à faire. Et, autant que je sache, personne n'y travaille activement.

@ianlancetaylor
Il existe 4 implémentations pour golang. Un sérieusement impressionnant. Voir mon commentaire précédent pour les liens.

Garçon, ce fil est comme la voiture Chevy Chase vue avec les enfants sur le siège arrière criant "y sommes-nous encore" :)

@joeblew99 : aucun de ces liens n'est compilable Go to WebAssembly.
Ce sont des choses comme un compilateur WebAssembly -> amd64 écrit en Go.

J'avais peur que tu dises ça. Assez juste.
Alors, qu'est-ce qu'il faut pour le " faire monter " ? Donc tout le monde sait...
Gopherjs a un peu fait la même erreur de ne pas être au bon niveau dans l'architecture de la chaîne d'outils du compilateur / génération de code ?

Il y a une longue liste. La plupart ont à voir avec la collecte des ordures, d'une manière ou d'une autre.

  • Générez du code WebAssembly dans le backend SSA. Le backend est utilisé pour enregistrer les machines, l'adaptation à la pile de WebAssembly demandera du travail.
  • Qu'est-ce qu'un pointeur ? WebAssembly n'a pas de type de pointeur.
  • Comment introspectons-nous la pile ? Nous en aurions besoin pour la collecte des ordures, certes, mais aussi pour la panique/récupération, l'impression de trace, etc.
  • Comment suspendre/reprendre une goroutine ?
  • Comment pouvons-nous disposer le tas? WebAssembly ne fournit essentiellement que sbrk. Nous avons besoin d'une disposition plus générale de l'espace d'adressage. Où stockons-nous les informations sur les étendues, les bits ptr/nonptr, etc. ?
  • Multithreading. WebAssembly n'a pas de notion de threads pour le moment, ce dont nous aurions besoin, par exemple, pour faire du GC simultané. Nous aurions aussi besoin d'écluses et peut-être d'opérations atomiques.
  • Comment fournissons-nous l'accès au monde extérieur pour des packages tels que os et net ?
  • WebAssembly ne prend pas en charge "goto".

Ce n'est probablement pas une liste complète.

Lorsque nous disons que WebAssembly doit fonctionner pour les programmes Go, nous voulons dire que le compilateur Go doit générer du code WebAssembly pouvant s'exécuter dans le navigateur.

@ianlancetaylor serait-il plus simple de cibler d'abord le non-web ? NaCl a également été conçu pour être exécuté d'abord dans le navigateur, mais a ensuite obtenu un chargeur indépendant du navigateur, que Go utilise actuellement. WebAssembly sans navigateur - http://webassembly.org/docs/non-web/ - et il parle de shells minimaux pour les tests.

@randall77 est-il possible de sortir une liste de contrôle exploitable de cette liste ? Vous aimez un problème principal avec des liens vers des problèmes approfondissant chaque aspect ?

@techtonik wrt non-web : @vibhavp y travaille dans le cadre du stage GSoC, je faisais allusion à quelques messages ci-dessus.
c'est par là : https://github.com/go-interpreter/wagon

@techtonik : Je pense que le bon endroit pour une telle liste de contrôle est un document de proposition sur la prise en charge de wasm. Une fois qu'une telle proposition est acceptée et/ou que les gens y travaillent activement, ils pourraient bien sûr utiliser les problèmes pour des tâches individuelles. C'est prématuré à ce stade - je ne connais personne qui travaille activement sur l'un ou l'autre (une proposition ou un code).

Je suis d'accord sur une proposition doc.
Tout ce que je fais / contradictions est dans ce fil et a juste besoin d'être regroupé, avec une feuille de route qui permet d'étager l'équilibre risque / récompense.

J'aimerais aussi le voir s'adresser aux graphismes car il me sort comme un pouce endolori.

Je suis l'auteur de GopherJS , un compilateur de Go to JavaScript. J'ai écrit ce projet parce que je crois fermement qu'il devrait y avoir des alternatives à l'utilisation de JavaScript dans le navigateur, des alternatives comme Go et d'autres. J'ai des connaissances décentes sur les compilateurs, SSA, l'architecture de la machine, etc., mais il me manque probablement beaucoup de détails, car je n'ai pas encore écrit de backend de compilateur pour le code machine. C'est pourquoi je ne me sens pas qualifié pour rédiger un document de proposition complet. Pourtant, j'aimerais avoir des commentaires critiques sur mes réflexions sur Go et WebAssembly.

En regardant WebAssembly, cela me semble très différent des cibles de code machine habituelles comme x86 ou arm. Par exemple, son architecture est une machine à pile au lieu d'une machine à registre. Cela signifie qu'il n'est pas immédiatement adapté comme une autre cible à la dernière étape du compilateur Go à côté de x86 et de ses amis. Une solution pourrait être de ne pas le mettre là, mais plutôt d'avoir une approche très différente de la génération de WebAssembly. Le code de cette approche devrait vivre en plus des étapes de compilation existantes, ce qui ne serait pas agréable du tout. On pourrait même envisager un fork du compilateur dans ce scénario. En bref: je ne vois pas cela se produire.

Il pourrait y avoir une alternative : émuler ce dont nous avons besoin. Nous pouvons utiliser la machine à piles pour émuler une machine de registre et, espérons-le, le faire de manière raisonnablement performante. WebAssembly a une mémoire linéaire avec des instructions de chargement et de stockage, ce qui est bien. Nous n'utiliserions pas du tout l'instruction call de WebAssembly et lancerions à la place notre propre mécanisme de gestion de pile et d'appel. Les piles vivraient sur cette mémoire linéaire et seraient gérées par le runtime Go. Le pointeur de pile serait une variable globale. Tout le code vivrait dans une seule fonction WebAssembly. Le niveau supérieur serait une instruction switch géante (ou l'équivalent basé sur br_table de WebAssembly) avec une branche pour chaque fonction. Chaque fonction aurait une autre instruction switch avec une branche par bloc de base SSA. Il y a quelques détails que j'omets ici, mais dans l'ensemble, cela ressemble à une machine de registre décente pour moi. Bien sûr, les performances de cela dépendent fortement de la capacité de WebAssembly à transformer ces constructions en code machine réel.

Alors, s'il vous plaît, dites-moi : suis-je complètement naïf et fou ? Ensuite, je suis heureux de reporter mes pensées jusqu'à ce que j'en ai appris davantage. Si ce n'est pas le cas, cela peut servir de point de départ pour un document de proposition réel. Merci.

En plus de tout le travail nécessaire du côté Go, WebAssembly peut avoir besoin de certaines choses avant que le runtime Go puisse le cibler.

WebAssembly n'a pas encore de threads, mais c'est sur la feuille de route et il y a une spécification. https://github.com/WebAssembly/threads

En ce qui concerne la collecte des ordures, il semble qu'il pourrait y avoir plusieurs options à l'avenir, d'après le discours de Lin Clark https://youtu.be/HktWin_LPf4?t=28m31s

28:31
Donc, aujourd'hui, vous pouvez expédier votre propre ramasse-miettes avec du code si vous le souhaitez, mais c'est
lent pour plusieurs raisons et le groupe communautaire rend possible le code WebAssembly
à utiliser uniquement avec le GC intégré qui est hautement optimisé que les navigateurs
ont travaillé, il fonctionnera donc rapidement et vous aurez cette intégration.

Comme avec gomobile, il y a le pont linguistique à comprendre.

@randall77 a également mentionné les threads comme une exigence pour le GC. Est-ce vraiment une exigence difficile pour la première version ? La simultanéité peut également être effectuée dans un seul thread.

En ce qui concerne la mise en œuvre de GC, mon opinion personnelle est que je ne crois pas en un seul GC pour les gouverner tous. Je préférerais que Go ait un GC spécifique à Go et que Python ait un GC spécifique à Python. En gérant complètement nos propres tas et piles sur la mémoire linéaire de WebAssembly, nous devrions être en mesure d'utiliser le GC que Go possède déjà, pour autant que je sache actuellement.

@neelance Oui, plusieurs vrais threads WebAssembly sont un avantage, pas une exigence stricte.

La proposition du GC pour WebAssembly est toujours en cours. Les personnes intéressées peuvent participer ici :

https://github.com/WebAssembly/gc

@neelance , je ne connais rien aux compilateurs, SSA, architecture machine, etc. Pouvez-vous s'il vous plaît dire comment ce que vous avez décrit affecterait la taille binaire? Si je comprends bien, l'efficacité de la taille était l'un des objectifs de haut niveau de WebAssembly . Cela devrait également être l'une des priorités de ce compilateur Go-> WebAssembly, n'est-ce pas ?

@alxkchr Mon expérience est que la répétition due au passe-partout code-gen peut être largement compensée en appliquant gzip. Pourtant, ma proposition n'est pas la solution la plus efficace en ce qui concerne la taille binaire. Pourtant, une solution qui peut être mise en œuvre dans un délai raisonnable vaut mieux que pas de solution, n'est-ce pas ? ;-) Aussi pour moi personnellement, la taille binaire n'est pas l'une des premières priorités.

fyi : J'ai commencé à implémenter cela.

@neelance best news ever :) suivez-vous les spécifications ? (J'espère)

La spécification Go ? Il s'agit d'un nouveau backend/cible pour le compilateur Go normal, donc la spécification est déjà là. ;)

je veux dire wasm spec :)

@neelance

fyi : J'ai commencé à implémenter cela.

Pouvez-vous s'il vous plaît partager quelle approche sera utilisée pour répondre

Notre conclusion actuelle est qu'il n'existe aucun moyen efficace de mettre en œuvre
fonctionnalité setjmp/longjmp actuellement, donc ce n'est pas une cible viable
d'un port gc. Nous devons attendre jusqu'à ce que la vraie pile se déroule et
prise en charge de la gestion des exceptions.

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

@neelance : Je sais que c'est encore tôt, mais je pense qu'il serait plus sage de nommer le wasm GOARCH wasm32 (idem pour les packages)

@sbinet Il convient de considérer que les architectures / packages ARM sont nommés arm et arm64 (de la même manière mips et mips64 ) plutôt que arm32 et arm64 . Cependant, je ne sais pas si cela doit être considéré comme un bon ou un mauvais exemple.

@SerkanSipahi Je cible initialement V8 (nodejs/chrome) et j'utilise https://webassembly.github.io/spec/ comme documentation sur ce qu'il faut faire.

@stuart-warren Oui, mon WIP est sur cette branche. Cependant, n'essayez pas encore de l'utiliser, il ne peut pas être facilement construit en ce moment et il est plein de code copié et de stubs/hacks. Je l'annoncerai ici quand il atteindra un état alpha.

@cznic Comme écrit ci-dessus, je n'utilise pas du tout l'instruction call de wasm, je gère ma propre pile sur la mémoire linéaire. Ainsi, setjmp/longjmp peut être implémenté.

@sbinet En fait, ce sera une architecture 64 bits puisque wasm a des opérations 64 bits.

@neelance pas entièrement. La spécification WebAssembly ne prend en charge que les espaces d'adressage 32 bits pour l'instant, une spécification wasm64 est prévue pour plus tard .

Intéressant, merci pour le lien. Nous voudrons peut-être revoir cela plus tard. Actuellement, je stocke tout dans des variables 64 bits, donc int , uint et uintptr ont tous une taille de 64 bits. Cependant, seuls les 32 premiers bits sont utilisés pour l'adressage de la mémoire. C'est plus simple à mettre en place dans un premier temps.

Cela ressemble alors à wasm64p32 (pour suivre la dénomination nacl), ou quelque chose
similaire.

Le 4 novembre 2017 à 5h28, "Richard Musiol" [email protected] a écrit :

Intéressant, merci pour le lien. Nous voudrons peut-être revoir cela plus tard.
Actuellement, je stocke tout dans des variables 64 bits, donc int, uint et uintptr
ont tous une taille de 64 bits. Cependant, seuls les 32 premiers bits sont utilisés pour
mémoire d'adressage. Ceci est plus facile à mettre en œuvre au début.


Vous recevez ceci parce que vous êtes abonné à ce fil.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/golang/go/issues/18892#issuecomment-341889653 , ou muet
le fil
https://github.com/notifications/unsubscribe-auth/AAgwpPTbfHRmoYNXLQfcPMVnARxb0UGrks5szEpjgaJpZM4L0o7D
.

Cela ressemble alors à wasm64p32 (pour suivre la dénomination nacl), ou quelque chose
similaire.

Je ne pense pas qu'il soit utile d'avoir deux nombres, car il n'y aura qu'une seule architecture (avec un choix de taille d'espace d'adressage). Depuis webassembly.org :

wasm32 et wasm64 ne sont que des modes de WebAssembly, à sélectionner par un indicateur dans un en-tête de module, et n'impliquent aucune différence sémantique en dehors de la gestion de la mémoire linéaire.

Je ne pense pas qu'il soit utile d'avoir deux nombres, car il n'y aura qu'une seule architecture (avec un choix de taille d'espace d'adressage). Depuis webassembly.org :

wasm32 et wasm64 ne sont que des modes de WebAssembly, à sélectionner par un indicateur dans un en-tête de module, et n'impliquent aucune différence sémantique en dehors de la gestion de la mémoire linéaire.

C'est une déclaration ambitieuse. Cela pourrait s'avérer vrai, mais le WebAssembly CG / WG n'a pas suffisamment exploré wasm64 pour que je sois sûr que la déclaration est exacte.

Laissons @neelance travailler. Les noms sont faciles à changer plus tard.

Je sais que Go est compilé directement en instructions machine (AFAIK), mais je me demande si quelqu'un a déjà compilé Go to C. Il serait intéressant d'essayer Go --> C --> wasm (mais pas très efficace).

@TomerHeber cela peut être possible sous forme de traduction en C++, pas de compilation, mais ce sera probablement plus de travail que de compilation pour wasm lui-même

Salut à tous. Voici une mise à jour de mon travail : je fais de très bons progrès, ce qui est en grande partie dû à l'excellent travail de l'équipe Go et des contributeurs jusqu'à présent. La plupart du code est partagé entre les architectures/plates-formes, il n'y avait donc pas autant que je m'y attendais à implémenter.

Voici une liste de certaines choses qui fonctionnent déjà bien :

  • exécuter le code wasm généré dans les navigateurs et dans Node.js
  • opérations de base, conversions, etc.
  • interfaces
  • goroutines & canaux
  • différer/paniquer/secourir
  • lire les fichiers du disque lors de l'utilisation de Node.js
  • les tests des packages suivants sont en cours : 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

Certaines choses qui ont encore besoin de travail :

  • réflexion
  • faire pousser la pile de goroutines
  • collecte des ordures
  • optimisations des performances
  • optimisations de la taille des fichiers wasm
  • une belle couche d'interopérabilité JS
  • beaucoup d'autres problèmes pour faire passer plus de tests de paquets

Je suis très content des progrès réalisés en un mois et demi, et uniquement sur mon temps libre. Je pense qu'il y a de fortes chances que nous puissions intégrer cela dans Go 1.11. Attendez-vous à ma prochaine mise à jour en janvier, puisque je serai en vacances et puis il y a les vacances.

Certaines de ces tâches peuvent-elles être parallélisées ? Certains morceaux semblent intéressants pour le hack des vacances.

N'hésitez pas à vous renseigner et à créer un PR sur ma fourchette. Vous pouvez également me trouver sur le Gophers Slack.

Un domaine d'investigation pourrait être l'optimisation de l'utilisation de la pile. À l'heure actuelle, la phase d'allocation des registres alloue des registres (variables locales dans wasm) pour chaque opération. get_local et set_local sont toujours utilisés avant et après chaque opération. Ceci n'est pas nécessaire si la valeur peut simplement rester sur la pile pour être utilisée par une opération ultérieure. Je suggère d'ajouter un pseudo-registre REG_STACK et de faire en sorte que le générateur d'instructions saute get_local et set_local si ce registre est utilisé. Ensuite, faites en sorte que regalloc utilise ce registre le cas échéant.

Ré:

une belle couche d'interopérabilité JS

Existe-t-il un moyen sain d'implémenter cela pour wasm actuellement? Je pensais que l'interopérabilité Dom/js était encore une issue avec wasm. Si c'est possible, ce serait énorme !

Vous pouvez importer et exporter des fonctions qui peuvent avoir des arguments float64 et int32 et vous avez la mémoire linéaire partagée. Tout le reste peut être construit autour de cela. Seul le ramassage des ordures ne serait pas si agréable.

(J'ai essayé de publier ceci sur votre dépôt (@neelance) mais je n'ai pas trouvé comment publier des problèmes ...)

serait-il possible d'utiliser la chaîne d'outils wabt au lieu d'appeler/importer js.foo ?
J'ai trouvé plus facile d'interagir avec wabt au lieu d'une installation complète nodejs :)

(J'essaye aussi d'interpréter un simple main.go , traduit en a.wasm ici : go-interpreter/wagon#36...)

J'ai activé les problèmes sur mon fork, n'hésitez pas à y poster.

Je ne comprends pas vraiment votre question. Parlez-vous de wasm-interp ? Quelque chose doit compiler et exécuter le bytecode wasm et vous avez besoin d'un environnement JS pour interagir avec le reste du système, par exemple pour imprimer sur la console.

C'est bien. Pour ceux qui veulent s'essayer à la compilation et à l'exécution de Go to wasm -

  1. Créez un programme hello world simple qui s'imprime sur la console.
  2. GOOS=js GOARCH=wasm ./bin/go build -o out.wasm wasm.go
  3. ./misc/wasm/go_js_wasm_exec out.wasm

Prendre plaisir !

Si vous liez go_js_wasm_exec dans votre PATH, vous pouvez même utiliser go run . ;-)

Hé les gars, comment se passe la collecte des ordures avec Go for WASM ? Nous avons commencé à parler de faire venir Crystal et il semble que Crystal partage probablement les mêmes problèmes que Go a actuellement avec GC. Y aurait-il un moyen de collaborer ou d'aider le groupe de travail WebAssembly dans cette situation ?

N'hésitez pas à participer au fil de discussion mentionné ci-dessus ou à nous faire savoir où nous pourrions peut-être discuter / éventuellement collaborer sur ce problème.

Il se peut que le chemin Opal soit l'approche la plus sensée pour le moment jusqu'à ce que WASM mûrisse dans ce domaine, mais il serait bon de le savoir avec certitude avant de s'engager dans cette voie.

Salut les gens, je voulais partager ce sur quoi j'ai travaillé ces derniers mois car je pense qu'une grande partie du code sous-jacent est pertinente : https://github.com/matthewmueller/joy

Je cible JS (ES3) en ce moment, mais le compilateur implémente un graphe de dépendance pour toutes les déclarations (funcs, variables, etc.). Il trie ensuite le graphe et ne traduit que les déclarations utilisées dans le programme.

Je ne pense pas qu'il serait trop difficile d'utiliser ce graphique et de cibler WebAssembly. Je suis impatient d'aider et de collaborer de toutes les manières possibles.

Pour plus d'informations voici quelques liens pertinents :

En ce qui concerne le problème GC pour Crystal ci-dessus, cela pourrait également avoir une application pour Go, notez les remarques de @kripken et la discussion suivante ici : https://github.com/WebAssembly/binaryen/issues/1312#issuecomment -348409211

Potentiellement, nous voudrons mettre à jour https://github.com/AppCypher/webassemblylanguages ?

J'espère que tout le monde a passé de bonnes vacances. Voici la mise à jour promise :

Depuis ma dernière mise à jour, j'ai réussi à faire fonctionner la réflexion, la croissance de la pile et la collecte des ordures. Des améliorations supplémentaires l'ont amené au point que les tests de 104 des 136 packages stdlib réussissent maintenant. En outre, de nombreux tests du compilateur sont verts. Bon progrès!

Veuillez garder à l'esprit que je me concentre actuellement sur la prise en charge et l'exactitude des fonctionnalités. Je n'ai pas encore fait d'optimisations pour les performances ou la taille de sortie.

J'applaudis l'expérience (et @neelance ty tellement pour GopherJS pour les goroutines supérieures par rapport à Promise , vous m'avez probablement sauvé de C++ !), donc ce qui suit est simplement une tentative d'ajouter des informations potentiellement utiles et peut-être même peut-être pour faire prendre conscience de l'incongruité entre Go et une cible WASM. Aussi potentiellement pour clarifier le problème pour certains lecteurs. Aussi parce que je voulais un endroit approprié pour vider la citation @rossberg suivante que j'ai trouvée lorsque je réfléchissais indépendamment à la façon de compiler quelque chose comme gorountines sur WASM.

@neelance a répondu :

@cznic a répondu :

@neelance a écrit :

Nous n'utiliserions pas du tout l'instruction call de WebAssembly et lancerions à la place notre propre mécanisme de gestion de pile et d'appel. Les piles vivraient sur cette mémoire linéaire et seraient gérées par le runtime Go. Le pointeur de pile serait une variable globale. Tout le code vivrait dans une seule fonction WebAssembly. Le niveau supérieur serait une instruction switch géante (ou l'équivalent basé sur br_table de WebAssembly) avec une branche pour chaque fonction. Chaque fonction aurait une autre instruction switch avec une branche par bloc de base SSA.

Pouvez-vous s'il vous plaît partager quelle approche sera utilisée pour traiter :

@minux a écrit :

Notre conclusion actuelle est qu'il n'existe aucun moyen efficace de mettre en œuvre
fonctionnalité setjmp/longjmp actuellement, donc ce n'est pas une cible viable
d'un port gc. Nous devons attendre jusqu'à ce que la vraie pile se déroule et
prise en charge de la gestion des exceptions.

@cznic Comme écrit ci-dessus, je n'utilise pas du tout l'instruction call de wasm, je gère ma propre pile sur la mémoire linéaire. Ainsi, setjmp/longjmp peut être implémenté.

Selon le "co-concepteur" et "l'auteur des spécifications" de WASM, les limitations sur call , qui le rendent inapproprié pour Go, ont quelque chose à voir avec la sécurité :

@rossberg a écrit :

Vous ne pouvez pas facilement "remplacer" la pile d'appels, car il n'y a aucun moyen de réifier les adresses de retour (*). Cependant, vous pouvez implémenter une pile fantôme pour vos variables locales dans la mémoire linéaire si vous en avez besoin.

En fait, WebAssembly n'expose actuellement aucune notion de "pile" intégrée. Comme un certain nombre d'autres décisions de conception, c'est important : parce que Wasm s'exécute sur le Web, il doit être "sûr". C'est pourquoi il est typé, n'a pas de comportement indéfini, le code est séparé de la mémoire (et non adressable), les conversions sur les types de fonction sont vérifiées, etc. Avoir un concept explicite de fonction permet également d'autres avantages, tels qu'une allocation de registre efficace, parallèle ou paresseux compilation, outils de débogage utiles, etc.

Le control-flow est en effet semi-structuré : les branches ne sont en réalité que des ruptures et des continuations, de sorte qu'on ne peut pas construire de control flow irréductible. C'est aussi une caractéristique.

[…]

(*) Vous pourriez vraisemblablement émuler des adresses de retour explicites avec des indices dans un saut de table géant, en compilant tout votre programme en une seule fonction de bouclage. Mais ce serait probablement assez lent et mettrait en échec une grande partie de l'écosystème WebAssembly .

Ainsi, les performances et l'interopérabilité avec l'écosystème WASM de ce que @neelance tente seront probablement sous-optimales ?

Citant la compétence de @neelance optimisant les performances de GopherJS .

Je ne sais pas ce que vous entendez par "interopérabilité avec l'écosystème WASM", donc je ne peux pas commenter cela. Concernant les performances, je peux vous dire ceci :

Oui, l'approche actuelle n'est pas la manière la plus optimale d'exprimer le flux de contrôle dans WebAssembly, mais cela fonctionne aujourd'hui . Peut-être qu'il sera possible à l'avenir d'utiliser davantage l'instruction call de WebAssembly, mais pour cela, WebAssembly devrait ajouter quelques fonctionnalités supplémentaires et il faudrait beaucoup plus de travail du côté Go pour être compatible avec cela. Je préfère avoir quelque chose avec 80% des performances qui fonctionne réellement que quelque chose qui a 100% mais qui n'est qu'hypothétique. ;-)

Si vous êtes intéressé par plus de détails techniques, parlez-moi sur #webassembly à https://invite.slack.golangbridge.org/.

Je ne sais pas ce que vous entendez par "interopérabilité avec l'écosystème WASM", donc je ne peux pas commenter cela.

Peut-être que ce à quoi @rossberg fait référence avec _"vaincre une grande partie de l'écosystème WebAssembly"_, est l'interopérabilité avec des outils et d'autres langages de l'écosystème qui n'évitent pas call et la pile d'appels protégée en émulant essentiellement votre propres continuations utilisant des tables switch ?

mais pour cela, WebAssembly aurait besoin d'ajouter quelques fonctionnalités supplémentaires

J'espère que WASM s'adaptera mieux aux langages avec des goroutines (fils verts), car afaics ils sont incontestablement supérieurs au modèle JavaScript de déroulement de la pile Promise .

Je préfère avoir quelque chose avec 80% des performances qui fonctionne réellement que quelque chose qui a 100% mais qui n'est qu'hypothétique. ;-)

Oh, je suis entièrement d'accord, c'est pourquoi je me suis assuré de faire précéder mon message précédent de mes applaudissements pour vos efforts prolifiques.

Plus nous pouvons créer Go ou d'autres langages qui ont des threads verts sur le Web/WASM, plus nous avons de chances d'obtenir de meilleures primitives WASM (par exemple, analogues à -fsplit-stack ?) pour de meilleures performances à terme .

Si votre implémentation atteint vraiment 80% des performances optimales dans les limites actuelles de WASM, je serai agréablement surpris. Si le résultat des performances est excessivement mauvais, cela pourrait limiter la démonstration de la popularité des threads verts par rapport au modèle basé sur le rappel JavaScript Promise (le potentiel de l'ironie de "vaincre une grande partie de l'écosystème WebAssembly" si nous supposons que c'est la conception a été guidée par une priorité sur l'optimisation de JavaScript :-) .

Notez également que j'envisage (pas encore de décision ferme) d'ajouter des génériques de classe de types à Go en tant que transpileur (et de fournir mon analyse de la proposition de génériques pour Go 2), donc je suis également potentiellement impliqué pour faire ma part pour essayer d'augmenter popularité.

@ shelby3 Veuillez cesser d'utiliser un formatage qui rend votre texte si petit qu'il n'est pas lisible. Si vous considérez que quelque chose ne vaut pas la peine d'être lu par les gens, ne l'écrivez pas en premier lieu. Le rendre illisible sans donner un indice sur ce qui est caché oblige les lecteurs à passer deux fois (ou plus) de temps à essayer de le déchiffrer. Je pense que c'est le contraire de votre intention initiale.

@ shelby3 J'ai édité vos messages pour arrêter d'utiliser le petit formatage du texte. S'il vous plaît, arrêtez de faire ça.

Le changement https://golang.org/cl/102835 mentionne ce problème : go/build, cmd/dist: add js/wasm architecture

Le changement https://golang.org/cl/103255 mentionne ce problème : wasm: add scripts for running WebAssembly binaries

Le changement https://golang.org/cl/103256 mentionne ce problème : cmd/compile: add SSA config options noAvg and noHmul

Le changement https://golang.org/cl/103275 mentionne ce problème : cmd/compile/internal/gc: factor out beginning of SSAGenState.Call

Le changement https://golang.org/cl/103295 mentionne ce problème : cmd/compile: add wasm architecture

Le changement https://golang.org/cl/103535 mentionne ce problème : cmd/compile: wasm stack optimization

Le changement https://golang.org/cl/103795 mentionne ce problème : cmd/link: add wasm architecture

Le changement https://golang.org/cl/103877 mentionne ce problème : runtime: add js/wasm architecture

Le changement https://golang.org/cl/103915 mentionne ce problème : internal/bytealg: add wasm architecture

Ok, on dirait que beaucoup de CL commencent à voler.
Comment en sommes-nous par rapport à la politique de portage : https://github.com/golang/go/wiki/PortingPolicy ?
En particulier, à quoi ressembleront les constructeurs ?
Je suppose @neelance que vous vous inscrivez pour maintenir le port ?
(Mes excuses si l'un des CL explique tout cela, je ne les ai pas tous lus.)

Oui, je vais entretenir le port. @bradfitz étudie actuellement la configuration du constructeur.

Le changement https://golang.org/cl/106995 mentionne ce problème : sync/atomic: add wasm architecture

Le changement https://golang.org/cl/106996 mentionne ce problème : math: add wasm architecture

Le changement https://golang.org/cl/106997 mentionne ce problème : time: add wasm architecture

Le changement https://golang.org/cl/106998 mentionne ce problème : mime: add wasm architecture

Le changement https://golang.org/cl/109195 mentionne ce problème : syscall/js: add package

Le changement https://golang.org/cl/109976 mentionne ce problème : syscall: enable some nacl code to be shared with js/wasm

Le changement https://golang.org/cl/109977 mentionne ce problème : os: add js/wasm architecture

Le changement https://golang.org/cl/109995 mentionne ce problème : net: add js/wasm architecture

Le changement https://golang.org/cl/110095 mentionne ce problème : crypto: add js/wasm architecture

Le changement https://golang.org/cl/110096 mentionne ce problème : all: skip unsupported tests for js/wasm

Le changement https://golang.org/cl/112736 mentionne ce problème : env/js-wasm, dashboard: add start of a js-wasm builder

Le changement https://golang.org/cl/113515 mentionne ce problème : misc/wasm: make wasm_exec.js more flexible

Après avoir lu l'architecture webassembly pour Go document , en particulier pour l'implémentation de syscall JavaScript construite sur le module 'fs' de Node, et largement non implémentée du côté navigateur, je me demande si nous pourrions ou voudrions essayer de les implémenter en utilisant les _nouvelles_ API du navigateur ? Plus précisément, la spécification de l' API FileSystem semble pouvoir prendre en charge au moins certains des appels système. (FileSystem est toujours un brouillon de l'éditeur et n'est implémenté que sur FireFox, Chrome et Opera. De plus, il est préfixé "webkit-" sur les deux derniers.)
Je pourrais essayer de faire une preuve de concept, si vous pensez que cela pourrait être une approche décente.

Le changement https://golang.org/cl/114197 mentionne ce problème : runtime, sycall/js: add support for callbacks from JavaScript

Salut tout le monde, j'adore le travail effectué par @neelance , et je me demandais si avec cette implémentation WASM (disons, la première version de celle-ci), il serait également possible d'utiliser cgo . Intégrez du code C, compilez en GO, compilez en WASM. Ce serait une putain de superpuissance. Vous faites tous un travail formidable. Impressionnant.

@cmaster11 Heureux d'apprendre que vous l'aimez. :) Sur votre question : cgo ne compile pas C to Go, mais compile les deux langages en code machine avec leurs compilateurs respectifs, puis fusionne les résultats en un seul binaire. Vous pouvez déjà utiliser emscripten pour compiler du code C en WebAssembly. En théorie, il devrait être possible de charger les deux binaires WebAssembly lors de l'exécution et de les faire interagir. Cependant, je pense qu'il est peu probable que le projet Go passe du temps à faciliter ce cas d'utilisation dans un avenir proche.

apparemment principalement des milléniaux

@ shelby3 Je suis probablement plus âgé que vous et je vous ai déclassé. Le problème ici est simplement votre incapacité à communiquer.

Ce n'est pas une question de pouvoir. @andybons vous a fait une faveur en éditant votre message afin qu'il puisse être lu par d'autres.

La prise en charge de js/wasm sans webidl implique que nous ne pouvons pas interagir beaucoup avec d'autres langages à partir du navigateur Web. L'architecture wasm ne semblait rien mentionner à propos de webidl.

J'ai bien regardé l'outil emscripten webidl python lorsqu'il est appliqué à la classe c++ Foo comme suit.
J'aimerais voir un type de canard golang exposé via webidl de la même manière que la classe Foo.
Cette logique serait d'interagir avec d'autres modules wasm qui sont chargés en même temps, mais nous avons besoin des idl disponibles afin de pouvoir inclure et appeler leurs stubs de marshalling. Sinon, nous avons besoin d'une sorte de visualiseur d'objets pour déterminer quelles signatures d'appel sont disponibles à partir des différents fichiers 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 , l'interopérabilité avec d'autres langages n'est pas un objectif pour la prise en charge initiale de WebAssembly 1.11 de Go.

D'accord. Je peux comprendre que webidl n'est pas un objectif à court terme, mais j'ai des questions sur la façon de rendre la sortie wasm utile. Tout d'abord, revenons à la classe Foo ci-dessus définie ci-dessus pour une utilisation avec emscripten c++ avec son idl. Disons que j'ai créé un type de canard golang qui lui correspondait. Supposons ensuite que j'exporte ces fonctions en tant que fonctions C afin qu'elles puissent être appelées à partir des implémentations C++ Foo SetVal et GetVal. Je sais que cela serait plus lent en conséquence, mais essayer de faire en sorte que toute la mise en œuvre soit construite dans go serait l'objectif à long terme.

Comment créer des foo.go.wasm.a et des foo.go.wasm.so ? Est-ce que chaque foo.wasm a besoin de son propre foo.go.js ?
Si une bibliothèque pleine de différents foos était générée, y aurait-il alors un autre foos.go.a.js généré également ?

Comment puis-je lier go.wasm.a et go.wasm.so à la sortie emcc générée.wasm comme spécifié dans :
emcc -v Foo.cpp my_glue_wrapper.cpp --post-js glue.js -o output.js foo.go.wasm otherfoos.go.wasm.a

Comment lier les fonctions sdl prises en charge par emcc à partir de wasm dans go par exemple.

Quand la prise en charge des goroutines complètes, des MAXCPUCores, des canaux apparaîtra-t-elle pour wasm ?
Merci encore.

@omac777 , ce qui est dans la portée de Go 1.11 est ceci :

Le code Go se compile dans un module WebAssembly et s'exécute dans un navigateur, et nous pouvons faire des allers-retours entre JavaScript.

Ignorez tout ce qui concerne les fichiers *.a ou *.so ou l'interopérabilité avec C ou GCC ou emcc ou SDL. Rien de tout cela n'est dans la portée et ne fonctionnera pas.

Quand la prise en charge des goroutines complètes, des MAXCPUCores, des canaux apparaîtra-t-elle pour wasm ?

Il prend entièrement en charge les goroutines et les canaux (cela fait partie de Go et est requis). WebAssembly ne prend en charge qu'un seul cœur, si c'est ce que vous entendez par MAXCPUCores . Ce n'est pas une limitation du support WebAssembly de Go ou Go.

Donc, ce que vous dites, c'est que je ne verrai rien de tel de sitôt ?
GOARCH=wasm GOOS=js go build -o awesome.wasm.so -buildmode=c-shared foo.go

Donc, si nous avons des navigateurs Web avec 4 cœurs ou 20 cœurs, le wasm généré par Go n'utilisera qu'un seul de ces cœurs dans le navigateur Web ? Je ne comprends pas comment vous dites que ce n'est pas une limitation du support go or go webassembly. Déclarez-vous qu'il s'agit d'une limitation de la spécification WEBASSEMBLY.org elle-même ?

@omac777 - Oui, je pense qu'il s'agit actuellement d'une limitation de WebAssembly lui-même, pas de l'implémentation de Go.

@omac777 La prise en charge du multithreading dans WASM est un travail en cours et il faudra un certain temps avant qu'il ne soit publié dans les navigateurs.

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

Donc, ce que vous dites, c'est que je ne verrai rien de tel de sitôt ?
GOARCH=wasm GOOS=js go build -o awesome.wasm.so -buildmode=c-shared foo.go

Probablement dans Go 1.12.

Pour Go appelant C/C++, je pense qu'il est probablement possible d'encapsuler des fonctions C avec JavaScript, puis d'appeler le wrapper JavaScript à partir de Go, avec Go 1.11.

Je sais que cela ne fait pas partie (peut-être) du fil, mais existe-t-il une documentation/tutoriels sur l'utilisation de WebAssembly (compilation, etc.) dans go v1.11 ?

@SerkanSipahi , pas encore. Mais il y aura des docs avant la sortie.

@SerkanSipahi J'ai écrit les étapes que j'ai suivies pour le faire fonctionner sur https://blog.lazyhacker.com/2018/05/webassembly-wasm-with-go.html.

Il y a aussi ce post, toujours d'actualité :
https://blog.gopheracademy.com/advent-2017/go-wasm/

il m'est apparu que nous n'avions pas (IIRC) spécifié exactement le mappage (ni le mécanisme) pour ce qui se passe dans la section export d'un module wasm.

J'ai déposé #25612.

À l'aide de la cible wasm, veuillez clarifier/documenter comment :
-utilisez go pour exporter/importer une fonction go vers et depuis wasm pour les autres langues à utiliser.
-lier sdl2/webgl/qt à un binaire golang
-attraper tous les événements sdl2/webgl/qt
-Restituer temporairement le temps CPU au système d'exploitation avec un sommeil si nous sommes dans une boucle. par exemple
dans emscripten emscripten_sleep(10)

Le fichier output.html de l'outil go ne semble pas réussir de manière cohérente avec firefox/chrome même s'il y a eu un output.html construit avec succès. Plus devrait être fait pour s'assurer que output.html fonctionne. avant de le présenter comme un succès.

@omac777 , nous avons passé en revue la plupart de ces éléments ci-dessus. Mais pour les autres, il suffit de se connecter :

À l'aide de la cible wasm, veuillez clarifier/documenter comment :
-utilisez go pour exporter/importer une fonction go vers et depuis wasm pour les autres langues à utiliser.
-lier sdl2/webgl/qt à un binaire golang
-attraper tous les événements sdl2/webgl/qt

Comme ci-dessus, rien de tout cela n'est dans la portée de Go 1.11. Cela ne sera pas pris en charge, documenté ou probablement même possible.

-Restituer temporairement le temps CPU au système d'exploitation avec un sommeil si nous sommes dans une boucle. par exemple

@neelance a obtenu des rappels et une interopérabilité entre JS et le planificateur Go, donc les time.Sleep réguliers et les amis devraient fonctionner comme prévu.

Je comprends que Go 1.11 n'aura aucun de ces éléments, mais jusqu'où / combien de temps l'un des éléments ci-dessus sera-t-il pris en compte pour aller. Il y a des gens qui aimeraient voir qt proprement intégré à go et actuellement la situation est que nous comptons sur un tiers pour cette recette/qt qui est tout bon mais il y a des limitations (actuellement pas de wasm qt et pas de cibles de bras qt 64bit prise en charge). autocad a une solution de webassembly pour windows et macos utilisant emscripten, c++ et react. J'ai toujours l'impression que golang est toujours limité pour certains domaines d'utilisation par opposition à l'endroit où c++ peut être utilisé.

Il y a beaucoup de pouvoir à avoir dans l'approche 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

Pourquoi golang ne peut-il pas avoir un comportement similaire?
MISE À JOUR : Je suis corrigé. Golang n'a pas besoin de commutateurs "-s" en raison des directives de compilation cgo intégrées dans le code go.

Le cache clair et les ports clairs sont cependant une bonne idée car il peut y avoir des bogues introduits lors de la migration vers différentes versions de construction de golang, c'est-à-dire go1.9 à go1.10. go1.10.3 à go1.11 (lorsque nous migrons vers le mode de vie vgo). J'ai récemment dû faire un "go build -a" entre les versions de go build.
GOARCH=wasm GOOS=js aller --clear-cache --clear-ports

Pourquoi golang ne peut-il pas avoir un comportement similaire?
GOARCH=wasm GOOS=js aller --clear-cache --clear-ports

FWIW, le cache de Go ne nécessite pas d'effacement explicite pour l'exactitude.

@neelance - Maintenant que les rappels sont en place, je pense que le support de base est terminé. Allons-nous fermer ce bogue ou aviez-vous quelque chose d'autre en tête ?

Oui, je pense qu'on peut fermer ça maintenant. 🎉

Bon travail!!! @neelance

C'est génial, super travail @neelance !

Le changement https://golang.org/cl/120057 mentionne ce problème : doc/go1.11: mention GOOS/GOARCH values of WebAssembly port explicitly

Le changement https://golang.org/cl/120575 mentionne ce problème : cmd/dist: skip non-std tests on js/wasm

Est-il approprié d'ouvrir un problème sur la réduction de la taille du fichier (si cela est même possible) ? Ou est-ce que cela est suivi ailleurs?

@matthewp , n'hésitez pas à ouvrir un bogue de taille spécifique à l'assemblage Web si vous le souhaitez. Le général est le #6853.

Le changement https://golang.org/cl/120958 mentionne ce problème : net: re-implement built-in simulated network on JS and NaCl

Le compilateur golang a-t-il une intégrité de flux de contrôle (CFI) intégrée ? J'ai récemment parcouru ce qui suit concernant les vulnérabilités de WASM empêchées avec CFI intégré au compilateur clang :
https://www.fastly.com/blog/hijacking-control-flow-webassembly-program
https://github.com/trailofbits/clang-cfi-showcase/blob/master/cfi_vcall.cpp

Je viens de le survoler, mais il me semble que le message dit "WebAssembly n'est pas un langage de haut niveau tel que JavaScript, mais un langage de bas niveau, donc certaines classes de bogues peuvent s'appliquer si le langage source (C ou Go) le permet ." Pas de surprise là-bas. Cela signifie que si Go avait de tels problèmes, ils s'appliqueraient également à d'autres architectures, pas seulement à WebAssembly.

WebAssembly consiste principalement à défendre le navigateur contre le code WebAssembly néfaste. Il ne s'agit pas tant de fournir des garanties dans l'instance WebAssembly (bien qu'il y en ait une partie). Comme @neelance l' a dit, il appartient aux compilateurs LanguageX-> WebAssembly de fournir toutes les garanties de sécurité requises.
Go n'a pas de CFI. Je ne pense pas que ce serait facile - au moment où une méthode démarre, nous avons déjà perdu la vtable. Nous avons même perdu le fait qu'une vtable était utilisée.
Go est vulnérable à cet exploit, dans les cas où il y a un parallélisme. Pour l'instant, au moins, le port WebAssembly Go (et WebAssembly, point final) n'a pas de parallélisme donc cet exploit n'est que théorique. Les gens de WebAssembly prévoient cependant d'implémenter le parallélisme à un moment donné.

@ randall77 Comment cela affecte-t-il le linux/amd64 ordinaire ? Le risque est-il plus important pour WebAssembly ?

Le risque est le même quelle que soit l'architecture (à l'exception que WebAssembly n'a pas encore de threads, donc il est en fait nul pour WebAssembly pour le moment). Les courses de données peuvent être utilisées pour simuler unsafe , sans importer unsafe .
Il serait difficile d'exploiter une telle vulnérabilité. Vous devez soit lier un code non approuvé, soit trouver et déclencher un gadget dans un binaire existant qui effectue une course de données sur une valeur d'interface, puis invoquer une méthode sur le résultat.

D'accord, donc si votre code Go n'a pas de courses de données, alors ça devrait aller. De plus, lors de l'exécution de code non approuvé avec WebAssembly, vous pouvez vous assurer qu'il ne peut pas échapper à l'environnement WebAssembly, même s'il peut avoir des courses de données ou simplement utiliser unsafe . Merci pour les idées intéressantes et désolé d'être un peu hors sujet pour ce problème.

Plus j'examine cette utilisation de javascript depuis golang, plus je la perçois comme une infection qui dégradera la qualité et la maintenance à long terme du code golang. Laisse-moi expliquer. Voici un exemple d'une merveilleuse application wasm golang qui fait une magie impressionnante pour les yeux.

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

Les résultats sont impressionnants. Plonger davantage dans le code qui le rend réellement possible était décevant car il exigeait que chaque fois que vous vouliez appeler quelque chose du côté javascript, vous deviez décrire le nom de la fonction javascript ou la valeur javascript sous forme de chaîne À CHAQUE TOUR . Par conséquent, le compilateur golang n'a aucun moyen de vérifier l'exactitude de javascript au moment de la compilation. C'est "voler par la prière" à l'exécution. Je préférerais voir les fonctions/variables/types golang partout pour une maintenance à long terme, sinon cela va à l'encontre de l'objectif d'utiliser golang pour wasm à mon humble avis. BTW je déteste le javascript et l'ai toujours fait. C'est trop freestyle. Pourquoi un tel langage a-t-il persisté dans les navigateurs Web ? La réponse m'échappe.

Merci pour votre attention.

Je suis d'accord qu'appeler JS en utilisant des chaînes n'est pas la meilleure expérience. Peut-être pourrions-nous générer des interfaces Go à partir des spécifications IDL de la plate-forme Web. L'inconvénient est de savoir comment suivre les spécifications, car selon le navigateur qu'il exécutera, l'API n'est pas disponible, tandis que de l'autre côté, de nouvelles spécifications continuent d'arriver tout le temps à mesure que la plate-forme Web évolue.

@omac777 Je suis d'accord avec vous. C'est pourquoi j'espère qu'il y aura de belles bibliothèques Go autour des bas niveaux de JS afin que la plupart des utilisateurs n'aient jamais à toucher directement à syscall/js . Semblable au package syscall , il est moche et presque personne ne l'utilise directement. ;-)

@omac777 Pour GopherJS, de nombreuses personnes utilisent des liaisons de haut niveau pour diverses API de navigateur plutôt que le package de bas niveau js directement. Je soupçonne qu'une approche similaire sera également la plus populaire avec Wasm. Je m'attends à ce que de nombreuses liaisons GopherJS ajoutent la prise en charge de Wasm dans le même package, et de nouveaux packages seront créés selon les besoins.

Pour référence, voir https://github.com/gopherjs/gopherjs/wiki/Bindings , https://dmitri.shuralyov.com/talks/2016/Go-in-the-browser/Go-in-the-browser. slide #11 (et les 4 slides suivants), et https://github.com/dominikh/go-js-dom/issues/57.

Nous devrions également considérer qu'il y a un tas de choses sur la feuille de route de l'assemblage Web :

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

cela améliorera beaucoup l'histoire syscall , à long terme, comme

référencez le DOM et d'autres objets de l'API Web directement à partir du code WebAssembly ;
appeler les API Web (en passant des primitives ou des objets DOM/GC/API Web) directement depuis WebAssembly sans passer par JavaScript ; et
allouer et manipuler efficacement les objets GC directement à partir du code WebAssembly.

Quoi qu'il en soit, merci @neelance et. Al. pour la mise en œuvre de la version initiale. Tellement génial! 🥇

Et s'il y avait une implémentation Go du DOM ?

Les documents et les scripts peuvent être écrits et exécutés en Go, en utilisant le système de type.

Ensuite, le code pourrait être généré à partir du Go DOM.

@fractalbach : Si la liaison d'hôte de WebAssembly est confirmée et implémentée par le groupe de travail, vous pouvez réellement effectuer une manipulation DOM via WebAssembly. Il serait alors raisonnable d'avoir des bibliothèques de haut niveau pour résumer le DOM, les documents et les scripts.

Mais avant cela, ce n'est pas aussi attrayant à faire.

Go WebAssembly : lier des structures à des références JS

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

La démarche est séduisante. L'utilisation est similaire à json marshallling/unmarshalling dans les structures. Cela en fait une compétence facilement transférable.

La seule chose qui manque est de savoir comment appliquer la même approche au typage canard ? Je préférerais ne pas avoir les déclarations de fonction dans la structure, mais en dehors de celle-ci, de la même manière que le typage de canard. Si le service existe, il peut l'utiliser. De cette façon, il est facilement modifiable sans affecter la structure principale contenant les différentes valeurs non fonctionnelles souhaitées. Des rochers typés canard !

Merci encore @neelance pour tout votre travail. C'est très apprécié.
Merci M. Nicolas Lepage pour vos points de vue. Ils aident vraiment à cristalliser ce qui pourrait être un meilleur chemin pour interagir avec tout ce bruit javascript pour l'intérim jusqu'à ce que l'interfaçage direct wasm soit terminé.

Bonjour à tous, c'est un sujet à fort trafic avec beaucoup de personnes abonnées. Avoir une discussion générale comme celle-ci n'est pas fructueux pour ceux qui sont juste préoccupés par le problème initial - qui est d'avoir le support WebAssembly pour Go.

N'hésitez pas à poursuivre la discussion dans les forums appropriés - golang-nuts/golang-dev. Ou si vous avez quelque chose de spécifique en tête, veuillez ouvrir un nouveau sujet.

Merci.

Cette page vous a été utile?
0 / 5 - 0 notes