Design: Discussion : WebAssembly, Unicode et la plate-forme Web

Créé le 22 mai 2021  ·  19Commentaires  ·  Source: WebAssembly/design

Ce numéro est destiné à accompagner la discussion sur « WebAssembly, Unicode et la plate-forme Web ». La présentation est préenregistrée, c'est ce que nous avons décidé d'essayer sur https://github.com/WebAssembly/meetings/pull/775 , avec un temps de discussion prévu pour la réunion vidéo CG du 22 juin .


(cliquez pour jouer)

Veuillez noter que je mentionne certains concepts que je pense être bien connus des membres du CG, mais j'ai néanmoins décidé de les inclure pour rendre la présentation accessible à ceux qui ne connaissent pas le sujet. Commentaires bienvenus!

Problèmes liés:

Commentaire le plus utile

Une solution simple serait d'avoir des langages/API qui acceptent ou produisent des chaînes Unicode invalides en utilisant (list u8) ou (list u16) (éventuellement avec un joli alias comme byte_string pour communiquer l'intention) plutôt que le type IT string , dont IIRC est un alias pour (list char) .

C'est actuellement ma solution préférée aussi - un type wtf16string serait un alias pour (list u16) de la même manière que string est actuellement défini comme un alias pour (list char) . La valeur de l'alias, IIUC, est que le résultat d'une fonction renvoyant (list u16) appelée par (par exemple) JS apparaîtrait comme une liste JS (de nombres), alors que le résultat d'une fonction renvoyant wtf16string pourrait être spécifié comme apparaissant dans JS sous forme de chaîne JS.

L'ajout d'un alias wtf16string supplémentaire au projet d'ABI canonique semble être relativement peu intrusif.

Tous les 19 commentaires

Peut-être quelques solutions potentielles que j'ai recueillies à partir des commentaires hors ligne jusqu'à présent, pour examen :

Séparer WTF-16

Dans Types d'interface, définissez :

string   := list char
string16 := list u16

Définir une coercition appliquée lors de l'enchaînement, avec les cas suivants :

| De | À | Attente
|------------|-----------|-------------
| string | string16 | Réencoder d'UTF-8 à UTF-16
| string16 | string | Réencoder de WTF-16 en UTF-8 (option de remplacement)

La coercition garantit qu'un module string16 fonctionne sur un hôte WASI, respectivement qu'un module string et string16 peuvent s'interfacer, même si les deux string et un module ou un hôte string16 appellent la même exportation string ou string16 , ce qui serait autrement ambigu.

Celui-ci introduit également une ambiguïté dans le Web embedding en ce sens que passer un list u16 à JS pourrait devenir un Uint16Array ou un DOMString . Une coercition à l'échelle du JS de Uint16Array à DOMString semble indésirable, mais le type JS pourrait être suggéré en utilisant explicitement l'alias string16 (avec son propre identifiant binaire, string16 :> list u16 étant purement sémantique si nécessaire) au lieu de list u16 dans un module adaptateur. D'où le pseudonyme. Dans ce cas, string16 deviendrait un DOMString tandis que list u16 deviendrait un Uint16Array .

Je ne suis pas particulièrement attaché au nom string16 et j'irais bien avec tout autre nom, ou toute alternative qui ne nécessite pas de nom / identifiant pour résoudre l'ambiguïté.

Une optimisation du type list.is_canon n'est pas nécessaire ici, puisque list.count peut être utilisé. En outre, la porte vers UTF-any et une optimisation potentielle Latin1, comme ci-dessous, peut être maintenue ouverte en réservant de l'espace pour un futur immédiat dans les instructions de l'adaptateur list.*_canon .

UTF-tout

Dans Types d'interface, définissez :

list.lift_canon $unit [...]
list.is_canon $unit [...]
list.lower_canon $unit [...]

where the $unit immediate is
  0: 8-bit (UTF-8, ASCII-compatible)
  1: 16-bit (UTF-16)
  2: 32-bit (UTF-32)
  3: 8-bit (Latin1, narrow UTF-16)

Cette solution potentielle peut être envisagée lorsqu'une bonne forme est requise. Cela éviterait un surcoût de double réencodage et des effets indirects sur la taille du code, mais laisse le problème de substitution non résolu. Notez que $unit 1-3 peuvent être ajoutés après le MVP en tant qu'optimisations supplémentaires, ou nous pouvons commencer par certaines d'entre elles tout de suite.

WTF-tout

Dans Types d'interface, définissez :

list.lift_canon $unit [...]
list.is_canon $unit [...]
list.lower_canon $unit [...]

where the $unit immediate is
  0: 8-bit (WTF-8, ASCII-compatible)
  1: 16-bit (WTF-16)
  2: 32-bit (Code points except surrogate pairs)
  3: 8-bit (Latin1, narrow WTF-16)

Cette solution potentielle nécessiterait également de redéfinir char des valeurs scalaires Unicode aux points de code Unicode, tout en restreignant les listes de char pour ne pas contenir de paires de substitution (mais autorisant les substitutions isolées), potentiellement appliquées lors du levage. Encore une fois, les $unit concrets dans un MVP sont discutables.

Celui-ci n'introduit pas de perte en soi, donc tout le reste devient en effet juste une optimisation post-MVP.

Intégré W/UTF-tout

Dans Types d'interface, définissez :

  • Soulevez la "liste des points de code Unicode modifiant les paires de substitution" mais abaissez la "liste des valeurs scalaires Unicode". Il s'agit d'un changement de conception non fonctionnel uniquement lorsqu'il est appliqué uniquement pendant le levage 16 bits.
  • Ajoutez une option optionnelle passthrough lors de la descente pour obtenir une "liste des points de code Unicode". Il s'agit d'un ajout fonctionnel permettant un passthrough sans perte.

Ce faisant, nous obtenons :

IIUC, le problème fondamental est que le service informatique souhaite que les chaînes soient des séquences de points de code Unicode, mais certains langages considèrent les chaînes comme des séquences de valeurs i8 ou i16 qui peuvent ou non correspondre à des chaînes Unicode bien formées. Une solution simple serait d'avoir des langages/API qui acceptent ou produisent des chaînes Unicode invalides en utilisant (list u8) ou (list u16) (éventuellement avec un joli alias comme byte_string pour communiquer l'intention) plutôt que le type IT string , dont IIRC est un alias pour (list char) . Les compromis de faire cela ont-ils déjà été discutés quelque part?

Je pense que le problème est un peu plus nuancé, en ce sens que le service informatique veut définir char comme des "valeurs scalaires Unicode", qui ont un trou là où se trouveraient les points de code de substitution, et en tant que tels ne peuvent pas représenter des substituts isolés . WTF, d'autre part, est "Unicode Code Points" sans cette restriction, mais les séquences sont limitées pour ne pas contenir de paires de points de code de substitution (celles-ci seraient remplacées par des points de code supplémentaires > U+FFFF, tandis que les substituts isolés sont OK). Est-ce que c'est ce que vous vouliez dire?

En dehors de cela, je pense que les chaînes d'octets de type C à partir de const char* qui peuvent être n'importe quoi n'ont pas encore été discutées. Je l'ai peut-être manqué, cependant.

Une solution simple serait d'avoir des langages/API qui acceptent ou produisent des chaînes Unicode invalides en utilisant (list u8) ou (list u16) (éventuellement avec un joli alias comme byte_string pour communiquer l'intention) plutôt que le type IT string , dont IIRC est un alias pour (list char) .

C'est actuellement ma solution préférée aussi - un type wtf16string serait un alias pour (list u16) de la même manière que string est actuellement défini comme un alias pour (list char) . La valeur de l'alias, IIUC, est que le résultat d'une fonction renvoyant (list u16) appelée par (par exemple) JS apparaîtrait comme une liste JS (de nombres), alors que le résultat d'une fonction renvoyant wtf16string pourrait être spécifié comme apparaissant dans JS sous forme de chaîne JS.

L'ajout d'un alias wtf16string supplémentaire au projet d'ABI canonique semble être relativement peu intrusif.

WTF, d'autre part, est "Unicode Code Points" sans cette restriction, mais les séquences sont limitées pour ne pas contenir de paires de points de code de substitution (celles-ci seraient remplacées par des points de code supplémentaires > U+FFFF, tandis que les substituts isolés sont OK).

Ah, cela signifie-t-il que WTF-8 n'est pas la même chose qu'un simple (list u16) parce qu'il a cette restriction d'addition ? Je n'avais pas apprécié cette nuance. Mon intuition est qu'il serait exagéré d'avoir à la fois un type string représentant des séquences de valeurs scalaires Unicode bien formées ainsi qu'un type wtf16string qui est presque un (list u16) mais a des restrictions supplémentaires. L'utilisation d'un alias pour un (list u16) sans restriction fonctionnerait-elle assez bien pour les systèmes qui n'appliquent pas la bonne formation Unicode ? Cette note dans la spécification WTF-8 suggère que ce serait le cas.

Ah, ça veut dire que WTF-8 n'est pas la même chose qu'un plain (liste u16) car il a cette restriction d'ajout ?

Il indique "Comme UTF-8 est artificiellement limité au texte Unicode afin de correspondre à UTF-16, WTF-8 est artificiellement limité à exclure les paires de points de code de substitution afin de correspondre à UTF-16 potentiellement mal formé." Iiuc, il les traite de la même manière que UTF-8 traite les séquences d'octets trop longues ou tronquées. WTF-8 peut représenter n'importe quel (list u16) , mais tous les (list u8) sont pas valides comme WTF-8.

L'utilisation d'un alias pour un nombre illimité (liste u16) fonctionnerait-elle assez bien pour les systèmes qui n'appliquent pas la bonne formation Unicode ?

WTF-16 mappe 1:1 sur des valeurs u16 aléatoires et cela dépend simplement de la façon dont ces valeurs sont interprétées, donc oui, (list u16) fonctionnerait.

IIUC, WTF-8 n'est pas tout à fait la même chose que list u8 arbitraire. Par exemple, il interdit les "séquences d'octets de paire de substitution" (voir ici ).

Cependant, WTF-16 _est_ identique à list u16 . C'est un peu bizarre qu'ils partagent un thème de nommage.

EDIT : aurait dû rafraichir :)

J'ai posté une première question/réponse axée uniquement sur la question des substituts dans interface-types/#135 . Je pense que c'est le bit le plus important et, si nous pouvons nous mettre d'accord là-dessus, une discussion ultérieure sur la prise en charge d'un ou plusieurs formats d'encodage sera plus simple.

Merci, Luc.

Si vous seriez prêt à prendre en charge "Separate WTF-16" comme ci-dessus (la coercition est cruciale pour permettre l'accès aux API WASI et pour s'interfacer avec JavaScript sans code de colle), je me sentirais à l'aise avec le char suggéré plage de valeurs. Les langages WTF-16 auraient alors la trappe de sortie dont ils ont besoin pour s'intégrer aussi bien qu'il l'obtient avec des modules écrits dans le même langage, JavaScript et par remplacement par des langages UTF-*. Je me sentirais également beaucoup mieux à propos de WASI, car le principal problème introduit par la non-concordance des encodages de chaînes serait résolu avec la coercition en place.

Avoir un type string16 séparé comme vous le suggérez avec les substituts aurait toujours tous les problèmes avec les substituts décrits dans interface-types/#135 , donc je pense qu'il ne serait pas mieux d'avoir deux types de chaînes contre . one (surtout s'ils sont implicitement inter-convertibles ; alors ce ne sont pas des types distincts de manière significative). Avoir deux types de chaînes aggraverait également concrètement les choses en introduisant une charge mentale sur chaque concepteur et consommateur d'interface (« pourquoi y a-t-il deux types ? quelle est la différence ? quand dois-je utiliser l'un ou l'autre ? »). Enfin, l'ajout de la prise en charge de WTF-16 irait généralement à l'encontre du futur guide d'évolution des normes Web/IETF également mentionné dans interface-types/#135 . Ainsi, je ne pense pas que nous devrions envisager d'ajouter des types porteurs de substitution à moins d'avoir des preuves concrètes que les types d'interface ne sont pas viables sans cela.

Pour les cas d'utilisation exclusifs au Web, je pense qu'il serait logique de résoudre le problème dans les API JS ou Web. Par exemple, il est facile d'imaginer des API JS pour "lier" les importations et les exportations de wasm. C'est déjà une approche adoptée dans d'autres API JS émergentes, comme la commutation de pile, et je me demandais si nous allions vers les API JS générales "bind import"/"bind export" capables de gérer le Web -cas spécifiques de promesses, de chaînes JS et de vues de tableau typées.

Avoir un type string16 séparé comme vous le suggérez avec les substituts aurait toujours tous les problèmes avec les substituts décrits dans interface-types/135

Techniquement vrai, mais il manque également que les chaînes fonctionneraient au moins toujours entre des modules compilés séparément dans le même langage, tout langage compatible et JavaScript, même sans connaissance préalable du type de module avec lequel on s'interface. C'est typiquement la majorité des cas je pense. En tant que tel, cela me semble être un compromis raisonnable, également parce qu'il permet de dédier la plage de valeurs char souhaitée

Avoir deux types de chaînes aggraverait également concrètement les choses en introduisant un fardeau mental sur chaque concepteur et consommateur d'interface ("pourquoi y a-t-il deux types? quelle est la différence? quand dois-je utiliser l'un ou l'autre?")

L'alternative de la casse occasionnelle me semble bien pire, donc si c'est ce qu'il faut, je pense que la plupart des gens s'en tireront bien. Peut-être qu'un bon nom pour le deuxième type de chaîne ( domstring ?), est suffisant pour atténuer ce problème mineur.

Enfin, l'ajout de la prise en charge de WTF-16 irait généralement à l'encontre du futur guide d'évolution des normes Web/IETF

Malheureusement, en l'absence d'une échappatoire pour les langues affectées, peu m'importe à quel point le raisonnement de quiconque sur une prétendue tendance est solide, car tant que le MVP informatique va casser quelque chose quelque part pour quelqu'un, et est en grande partie inutile pour le langage de type JavaScript sur lequel je travaille, je ne peux que m'y opposer.

Par conséquent, j'essaie de trouver une solution raisonnable ou un compromis avec lequel tout le monde peut vivre, et cela me ferait plaisir si nous pouvions coopérer.

Je ne vois pas comment ce que vous dites résout les problèmes soulevés dans interface-types/#135 ou fournit une contre-évidence que l'informatique ne serait pas viable en général sans l'inclusion d'un nouveau type domstring . L'API JS existante fournit déjà une trappe d'évacuation à usage général pour effectuer des conversions de valeurs arbitraires aux limites, donc je ne vois pas comment une deuxième trappe d'évacuation est nécessaire à ce stade précoce. Je pense que nous avons simplement besoin de plus de preuves basées sur l'expérience pour contrecarrer les conseils solides qui nous ont été donnés contre la propagation de chaînes contenant des substituts.

(FWIW, si nous pouvons nous mettre d'accord sur l'absence de substituts, je pense qu'il serait logique de parler de la prise en charge de U TF-16 en tant qu'encodage supplémentaire dans l'ABI canonique de string . Mais c'est un tout autre sujet avec quelques options, donc je ne veux pas mélanger cela avec la sémantique de chaîne abstraite qui doit d'abord être comprise.)

J'apprécie votre deuxième paragraphe, en ce sens qu'il résoudrait déjà des problèmes très ennuyeux. Je suis d'accord que le support UTF-16 est utile séparément, et j'apprécierais qu'il soit ajouté à l'explicateur / MVP. Compte sur moi!

Cependant, j'ai du mal à suivre vos arguments dans le premier paragraphe. Peut-être que si vous ne me croyez pas, voici Linus Torvalds expliquant une règle très importante qui, je pense, s'étend au-delà du noyau Linux : ne pas casser l'espace utilisateur . Et le voici dans le même discours, soutenant la sagesse du programmeur de Si c'est un bogue sur lequel les gens comptent, ce n'est pas un bogue, c'est une fonctionnalité , pour continuer avec :

C'est vraiment triste quand la bibliothèque la plus centrale de tout le système est d'accord pour casser des trucs tant que les choses « s'améliorent » et qu'elles « corrigent » l'ABI.

Et ne pas avoir à se soucier des substituts est en effet une sorte de fonctionnalité, en ce sens que les utilisateurs peuvent faire un substring(0, 1) négligent ici ou là et appeler une fonction importée avec, ou peuvent split("") , passer et join() nouveau, ou créez un StringBuilder tant que module qui ne produira pas occasionnellement de doubles caractères de remplacement comme si c'était magique. Je veux dire, il y a une raison pour laquelle un tas de langages très populaires ont choisi de ne pas appliquer le bien-formé, et quand Wasm veut bien prendre en charge ces langages et ses utilisateurs, alors plus Wasm devient modulaire, plus il y aura de limites, le il deviendra plus difficile de dire dans quel module réside une fonction, et plus le problème deviendra apparent.

Je ne sais vraiment pas combien de preuves supplémentaires il me faut pour prouver que concevoir quelque chose d'une manière qui ignore la réalité actuelle est une mauvaise idée. En fait, cela semble être OK dans les types d'interface uniquement, alors que nous maintenons toutes les autres propositions à des normes très élevées. Et bien que je ne sois pas un expert en la matière, je pense que c'est la norme Unicode elle-même qui a commis exactement la même erreur en ce qui concerne les besoins des langages UCS-2 en insistant sur les USV, ce qui a conduit à environ une décennie de problèmes tout aussi désespérés. discussions (peut recommander l'intégralité du fil, mais surtout le dernier commentaire avant qu'il ne devienne silencieux), en 2014 aboutissant à la description de la solution pratique couramment appliquée qu'est l'encodage WTF-8.

Notez que l'émission d'un caractère de remplacement lors de la rencontre d'erreurs de codage de caractères dans les flux binaires est une forme bien connue de corruption de données silencieuse et dangereuse et que les systèmes qui nécessitent une intégrité interdisent de le faire.

De même, si codePointAt lèverait une exception en frappant un seul substitut, vous pourriez très bien vous retrouver avec un bogue qui casse toute votre application parce que quelqu'un a accidentellement placé un caractère emoji à la mauvaise position dans une chaîne dans une base de données

Malheureusement, ecmascript rend très difficile de garantir que vous ne générez pas de chaînes avec des points de code de substitution non appariés quelque part, c'est aussi simple que de prendre les 157 premières unités .length d'une chaîne et peut-être d'ajouter "..." pour l'abréger. Et c'est un accident bizarre si cela se produit réellement dans la pratique, car les caractères non BMP sont rares. Nous devrions être très réticents à introduire des dangers dans l'espoir d'améliorer notre hygiène Unicode.

La raison pour laquelle JS, Java et C # ont les chaînes qu'ils font est que, au moment où Unicode s'est rendu compte que 2 octets n'étaient pas suffisants et que UCS-2 n'était donc pas viable, un tas de code était déjà écrit, donc ces langages n'ont tout simplement pas pas le choix. De même, pour les appels système Linux exposés à l'espace utilisateur. En revanche, aucun code n'existe aujourd'hui qui utilise des API définies dans l'informatique, nous n'avons donc pas les mêmes exigences de compatibilité descendante. Pour de nombreuses raisons, wasm et les types d'interface ne cherchent intentionnellement

Je tiens à souligner à nouveau que, bien sûr, à l' intérieur d' un composant, les chaînes peuvent être représentées de la manière appropriée au langage, nous ne parlons donc en réalité que de la sémantique des API . Quant aux API Web déjà définies :

  1. nous avons de nombreuses raisons de croire qu'il n'est pas nécessaire (et souvent pas significatif) de transmettre des mères porteuses
  2. il y a toujours la possibilité d'utiliser des liaisons d'API JS personnalisées (il n'est pas obligatoire que 100% des API Web aient une liaison sans colle JS aux API Web)

Ainsi, je ne pense toujours pas que nous ayons de preuves suggérant que l'informatique ne sera pas viable sans appliquer cette sémantique de chaîne WTF-16, ce qui est, je pense, la question appropriée pour un MVP.

Quelques points avec lesquels je ne suis pas d'accord :

Je ne vois pas en quoi ce que vous dites résout les problèmes soulevés dans interface-types/#135

C'est une question distincte maintenant, et dans le post précédent, je parlais de ce que je pense être un compromis raisonnable pour résoudre les pertes. En particulier, je serais d'accord avec votre raisonnement dans le numéro séparé, mais uniquement lorsqu'une solution de secours sans perte est disponible. Ce n'est pas un non plus à mon avis. Sinon, je resterais d'avis que WTF-8/16 est le choix le plus inclusif et le moins restreint, et en tant que tel est préférable, également parce que l'un des objectifs de haut niveau de Wasm est de s'intégrer de manière transparente avec la plate-forme Web respectivement de maintenir l'arrière-plan -nature compatible du Web, et cela s'applique également aux types d'interface.

L'API JS existante fournit déjà une trappe d'évacuation à usage général pour effectuer des conversions de valeurs arbitraires aux limites, donc je ne vois pas comment une deuxième trappe d'évacuation est nécessaire à ce stade précoce.

il y a toujours l'échappatoire de l'utilisation de liaisons d'API JS personnalisées

Ce n'est malheureusement pas suffisant dans notre cas, où nous avons actuellement un code de colle comme :

const STRING_SMALLSIZE = 192; // break-even point in V8
const STRING_CHUNKSIZE = 1024; // mitigate stack overflow
const utf16 = new TextDecoder("utf-16le", { fatal: true }); // != wtf16

/** Gets a string from memory. */
function getStringImpl(buffer, ptr) {
  let len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1;
  const wtf16 = new Uint16Array(buffer, ptr, len);
  if (len <= STRING_SMALLSIZE) return String.fromCharCode(...wtf16);
  try {
    return utf16.decode(wtf16);
  } catch {
    let str = "", off = 0;
    while (len - off > STRING_CHUNKSIZE) {
      str += String.fromCharCode(...wtf16.subarray(off, off += STRING_CHUNKSIZE));
    }
    return str + String.fromCharCode(...wtf16.subarray(off));
  }
}

Premièrement, comme nous nous soucions beaucoup de Chrome et de Node.js, nous avons constaté que le TextDecoder du V8 pour UTF-16LE est beaucoup plus lent que dans les autres moteurs (le SM est vraiment rapide), donc String.fromCharCode est en fait plus rapide en V8 jusqu'à un certain seuil de rentabilité. Nous avons donc décidé d'optimiser pour l'instant. Ensuite, il n'existe pas de TextDecoder pour WTF-16 (ce qui est ennuyeux séparément), nous essayons donc d'abord de décoder un UTF-16 bien formé, et si cela échoue, nous le laissons lancer et retomber en morceaux. le String.fromCharCode beaucoup plus lent. Le découpage est nécessaire car on ne peut pas simplement appliquer String.fromCharCode sur une longue chaîne, car cela risque de déborder la pile.

D'un autre côté, Rust par exemple n'en aurait pas besoin, ce qui est l'une des raisons pour lesquelles je pense que l'informatique, en ce moment, n'est pas aussi neutre qu'elle devrait l'être. En général, je pense que l'intérêt de l'IT string s est en effet de pouvoir bien s'interfacer avec JS, qui reste notre principale cible d'interopérabilité.

aucun code n'existe aujourd'hui qui utilise des API définies dans l'informatique, nous n'avons donc pas les mêmes exigences de compatibilité descendante

La première moitié est techniquement vraie, car l'informatique n'existe pas encore, mais nos exigences pour l'IIUC incluent l'amélioration des cas d'utilisation existants, comme par exemple la prise en compte du gros morceau de code de colle ci-dessus. Idéalement pour autant de langues que possible, donc le post-MVP devient en effet "juste une optimisation" comme vous l'avez dit dans votre présentation. Au contraire, à l'heure actuelle, l'informatique commence essentiellement par ce qui est déjà une optimisation pour les langages pouvant utiliser un encodeur/décodeur UTF-8, ce qui, à mon avis, n'est pas neutre.

wasm et les types d'interface ne cherchent intentionnellement pas à émuler parfaitement un langage unique ou un appel système ABI existant

J'ai lu ceci comme si j'étais de cet avis, ce que je ne suis pas du tout. Je suis prêt à vous donner le bénéfice du doute ici, mais j'aimerais ajouter qu'à mon avis, l'informatique est actuellement inutilement restreinte et, en tant que telle, ne sert bien qu'un ensemble très spécifique de langues. Au contraire, WTF-8/16 est l'encodage le plus inclusif que j'aurais pensé être la valeur par défaut logique, également parce qu'il effectue des allers-retours vers les chaînes JS. Nous ne sommes pas d'accord ici, mais seulement en l'absence d'une trappe d'évacuation appropriée. S'il existait une alternative viable sans perte, afin que personne ne soit cassé ou inutilement désavantagé, je serais d'accord avec votre raisonnement sur le type de chaîne par défaut.

nous avons de nombreuses raisons de croire qu'il n'est pas nécessaire (et souvent pas significatif) de transmettre des mères porteuses

Nous ne sommes pas d'accord ici. En particulier, je pense que ma présentation et mes commentaires soulèvent un doute raisonnable quant au fait qu'il peut, dans certains cas, même s'il est rare, être très significatif (par exemple, lorsque l'intégrité est requise), et je suis d'avis que « Nous devrions être très réticents à introduire dans l'espoir d'améliorer notre hygiène Unicode." C'est-à-dire, si nous le pouvons, je pense que nous devrions concevoir l'ABI canonique d'une manière qui soit garantie de fonctionner également dans les cas importants suivants : Java/C#/AS<->JS, Java/C#/AS<-> Java/C#/AS. Le remplacement sur d'autres chemins est probablement inévitable, mais au moins les langues et les utilisateurs ont alors le choix, respectivement la valeur par défaut n'est pas déjà cassée dans de rares cas.

Je ne pense toujours pas que nous ayons de preuves suggérant que l'informatique ne sera pas viable sans appliquer cette sémantique de chaîne WTF-16

En présence de doute raisonnable et de l'absence de volonté d'explorer ce que je crois être un compromis raisonnable, je m'attendrais à ce que le fardeau de la preuve vous incombe maintenant. Encore une fois, je suis prêt à vous laisser la chaîne par défaut et un avenir bien formé, mais pas au détriment de ne pas tenir compte de ce qui peut être rare, mais toujours, des dangers. De nombreuses langues populaires peuvent être affectées par cela, et cela peut devenir très difficile à justifier à l'avenir une fois qu'elles s'en rendent compte.

Je suis d'accord que le code de colle JS n'est pas idéal, mais je pense que la bonne solution pour cela se trouve dans l'API JS ou dans JS, pas en ajoutant le concept de chaîne wtf-16 à l'ensemble du futur écosystème de composants. Au-delà de cela, je ne vois pas de nouvelles informations auxquelles répondre qui n'a pas déjà été répondu; il semble que nous soyons principalement en désaccord sur les questions d'objectifs/de portée.

Je m'attendrais à ce que l'anomalie TextDecoder soit encore plus difficile à corriger dans JS, car il a apparemment déjà décidé que cela était hors de portée. Et JS peut en quelque sorte le faire, car TextDecoder dans JS n'est pas quelque chose qui est invoqué entre deux appels de fonction , mais principalement utilisé pour récupérer des données sur le réseau ou à partir du stockage.

L'anomalie encore plus intéressante, c'est qu'il n'y a même pas de TextEncoder pour UTF-16LE, donc il faut faire :

/** Allocates a new string in the module's memory and returns its pointer. */
function __newString(str) {
  if (str == null) return 0;
  const length = str.length;
  const ptr = __new(length << 1, STRING_ID);
  const U16 = new Uint16Array(memory.buffer);
  for (var i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
  return ptr;
}

Comme vous pouvez le voir, il s'agit d'un problème majeur pour quelque chose comme Java, C#, AS et autres, et les deux seraient toujours nécessaires lorsqu'un list u16 est passé. Et dans le contexte de ce problème, ce n'est pas exclusif à l'API JS, dans ce double ré-encodage + perte entre deux modules du même langage n'est pas si différent :(

Il existe tout un espace d'options au-delà de TextEncoder / TextDecoder pour savoir comment traiter ce cas d'utilisation sur le Web. Un autre étend new WebAssembly.Function() (qui est déjà implémenté dans certains navigateurs) pour effectuer des conversions de chaînes en ajoutant des paramètres facultatifs supplémentaires au constructeur. Une telle approche rendrait également la fonctionnalité disponible pour les utilisations non-composant de wasm (et potentiellement beaucoup plus tôt), renforçant ainsi le fait que l'API JS serait le bon endroit pour traiter ce cas d'utilisation.

Pour info : Ajout de l'option "Integrated W/UTF-any" qui est apparue dans https://github.com/WebAssembly/interface-types/issues/135#issuecomment -863493832 à la liste des suggestions ci-dessus :)

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

Questions connexes

chicoxyzzy picture chicoxyzzy  ·  5Commentaires

cretz picture cretz  ·  5Commentaires

Artur-A picture Artur-A  ·  3Commentaires

artem-v-shamsutdinov picture artem-v-shamsutdinov  ·  6Commentaires

badumt55 picture badumt55  ·  8Commentaires