Design: Discusión: WebAssembly, Unicode y la plataforma web

Creado en 22 may. 2021  ·  19Comentarios  ·  Fuente: WebAssembly/design

Este número es para acompañar la discusión de "WebAssembly, Unicode y la plataforma web". La presentación está pregrabada, que es lo que decidimos probar en https://github.com/WebAssembly/meetings/pull/775 , con un tiempo de discusión programado para la videoconferencia CG del 22 de junio .


(Dele "click" para jugar)

Tenga en cuenta que menciono algunos conceptos que esperaría que fueran bien conocidos entre los miembros del CG, pero decidí incluirlos de todos modos para que la presentación también sea accesible para aquellos que no están familiarizados con el tema. ¡Comentarios bienvenidos!

Asuntos relacionados:

Comentario más útil

Una solución simple sería hacer que los lenguajes / API que acepten o produzcan cadenas Unicode no válidas usen (list u8) o (list u16) (posiblemente con algún alias agradable como byte_string para comunicar la intención) en lugar de el tipo IT string , que IIRC es un alias de (list char) .

Esta es actualmente mi solución preferida también: un tipo wtf16string sería un alias para (list u16) de la misma manera que string se define actualmente como un alias para (list char) . El valor del alias, IIUC, es que el resultado de una función que devuelve (list u16) llamada por (p. Ej.) JS aparecería como una lista JS (de números), mientras que el resultado de una función que devuelve wtf16string podría especificarse que aparece en JS como una cadena JS.

Agregar un alias adicional wtf16string al borrador de ABI canónico parece ser relativamente poco intrusivo.

Todos 19 comentarios

Quizás algunas posibles soluciones que recopilé de los comentarios fuera de línea hasta ahora, para su consideración:

WTF-16 separado

En Tipos de interfaz, defina:

string   := list char
string16 := list u16

Defina una coerción aplicada durante la vinculación, con los siguientes casos:

| Desde | Para | Expectativa
| ------------ | ------------ | -------------
| string | string16 | Vuelva a codificar de UTF-8 a UTF-16
| string16 | string | Vuelva a codificar de WTF-16 a UTF-8 (opción de reemplazo)

La coerción asegura que un módulo string16 funcione en un host WASI, respectivamente que un módulo string y string16 puedan interactuar entre sí, incluso si ambos son string y un módulo string16 o un host llaman a la misma exportación string o string16 , que de otro modo sería ambiguo.

Este también introduce una ambigüedad en la incrustación web en el sentido de que pasar un list u16 a JS podría convertirse en un Uint16Array o un DOMString . Una coerción en todo JS de Uint16Array a DOMString parece indeseable, pero el tipo JS podría insinuarse usando explícitamente el alias string16 (con su propia identificación binaria, string16 :> list u16 es puramente semántica cuando sea necesario) en lugar de list u16 en un módulo adaptador. De ahí el alias. En este caso, string16 se convertiría en DOMString mientras que list u16 se convertiría en Uint16Array .

No estoy particularmente apegado al nombre string16 y estaría bien con cualquier otro nombre, o cualquier alternativa que no requiera un nombre / identificación para resolver la ambigüedad.

Una optimización similar a list.is_canon no es necesaria aquí, ya que se puede usar list.count . Además, la puerta hacia UTF-any y una posible optimización Latin1, como se muestra a continuación, se puede mantener abierta reservando espacio para un futuro inmediato en las instrucciones del adaptador list.*_canon .

UTF-cualquiera

En Tipos de interfaz, defina:

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)

Esta posible solución se puede considerar cuando se requiera una buena formación. Evitaría la sobrecarga de codificación doble y los efectos indirectos en el tamaño del código, pero deja el problema sustituto sin resolver. Tenga en cuenta que se pueden agregar $unit 1-3 después de MVP como optimizaciones adicionales, o podemos comenzar con algunas de ellas de inmediato.

WTF-cualquiera

En Tipos de interfaz, defina:

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)

Esta solución potencial también requeriría redefinir char de valores escalares Unicode a puntos de código Unicode, mientras que restringir las listas de char para no contener pares sustitutos (pero permitir sustitutos aislados), potencialmente impuesta al levantar. Nuevamente, los $unit s concretos en un MVP son discutibles.

Este no introduce pérdidas por sí solo, por lo que todo lo demás se convierte en una optimización posterior al MVP.

Integrado W / UTF-cualquiera

En Tipos de interfaz, defina:

  • Levante la "lista de puntos de código Unicode que modifican los pares sustitutos" pero reduzca la "lista de valores escalares Unicode". Este es un cambio de diseño no funcional cuando solo se aplica durante el levantamiento de 16 bits.
  • Agregue una opción passthrough opcional al bajar para obtener una "lista de puntos de código Unicode". Esta es una adición funcional que permite el paso a través sin pérdidas.

Al hacerlo, logramos:

IIUC, el problema principal es que TI quiere que las cadenas sean secuencias de puntos de código Unicode, pero algunos lenguajes consideran que las cadenas son secuencias de valores i8 o i16 que pueden corresponder o no a cadenas Unicode bien formadas. Una solución simple sería hacer que los lenguajes / API que acepten o produzcan cadenas Unicode no válidas usen (list u8) o (list u16) (posiblemente con algún alias agradable como byte_string para comunicar la intención) en lugar de el tipo IT string , que IIRC es un alias de (list char) . ¿Se han discutido todavía las ventajas y desventajas de hacer eso?

Creo que el problema es un poco más matizado, ya que TI quiere definir char como "Valores escalares Unicode", que tienen un agujero donde estarían los puntos de código sustitutos y, como tal, no pueden representar sustitutos aislados. . WTF, por otro lado, es "Puntos de código Unicode" sin esta restricción, pero las secuencias están restringidas para no contener pares de puntos de código sustitutos (estos serían sustituidos por puntos de código suplementarios> U + FFFF, mientras que los sustitutos aislados están bien). ¿Es esto lo que quisiste decir?

Aparte de eso, creo que las cadenas de bytes similares a C a partir de const char* que pueden ser cualquier cosa aún no se han discutido. Aunque puede que me lo haya perdido.

Una solución simple sería hacer que los lenguajes / API que acepten o produzcan cadenas Unicode no válidas usen (list u8) o (list u16) (posiblemente con algún alias agradable como byte_string para comunicar la intención) en lugar de el tipo IT string , que IIRC es un alias de (list char) .

Esta es actualmente mi solución preferida también: un tipo wtf16string sería un alias para (list u16) de la misma manera que string se define actualmente como un alias para (list char) . El valor del alias, IIUC, es que el resultado de una función que devuelve (list u16) llamada por (p. Ej.) JS aparecería como una lista JS (de números), mientras que el resultado de una función que devuelve wtf16string podría especificarse que aparece en JS como una cadena JS.

Agregar un alias adicional wtf16string al borrador de ABI canónico parece ser relativamente poco intrusivo.

WTF, por otro lado, es "Puntos de código Unicode" sin esta restricción, pero las secuencias están restringidas para no contener pares de puntos de código sustitutos (estos serían sustituidos por puntos de código suplementarios> U + FFFF, mientras que los sustitutos aislados están bien).

Ah, ¿eso significa que WTF-8 no es lo mismo que un (list u16) simple porque tiene esta restricción de adición? No había apreciado ese matiz. Mi intuición es que sería excesivo tener tanto un tipo string represente secuencias de valores escalares Unicode bien formados como un tipo wtf16string que es casi un (list u16) pero tiene restricciones adicionales. ¿Usar un alias para un (list u16) sin restricciones funcionaría lo suficientemente bien para sistemas que no imponen un formato correcto de Unicode? Esta nota en la especificación WTF-8 sugiere que lo haría.

Ah, ¿eso significa que WTF-8 no es lo mismo que un simple (lista u16) porque tiene esta restricción de adición?

Afirma que "Al igual que UTF-8 está restringido artificialmente al texto Unicode para que coincida con UTF-16, WTF-8 está restringido artificialmente para excluir pares de puntos de código sustitutos para que coincida con UTF-16 potencialmente mal formado". Iiuc, los trata de manera similar a como UTF-8 trata las secuencias de bytes demasiado largas o truncadas. WTF-8 puede representar cualquier (list u16) , pero no todos los (list u8) son WTF-8 válidos.

¿Usar un alias para un no restringido (lista u16) funcionaría lo suficientemente bien para sistemas que no imponen un formato correcto de Unicode?

WTF-16 asigna 1: 1 a valores aleatorios u16 y solo depende de cómo se interpreten estos valores, así que sí, (list u16) funcionaría.

IIUC, WTF-8 no es lo mismo que list u8 arbitrarios. Por ejemplo, prohíbe las "secuencias de bytes de pares sustitutos" (ver aquí ).

Sin embargo, WTF-16 _es_ lo mismo que list u16 . Es un poco extraño que compartan un tema de nombres.

EDITAR: debería haberse actualizado :)

Publiqué una primera pregunta / respuesta centrada solo en la pregunta de los sustitutos en los tipos de interfaz / # 135 . Creo que ese es el bit de alto nivel y, si podemos estar de acuerdo en eso, entonces una discusión posterior sobre el soporte de uno o más formatos de codificación será más simple.

Gracias, Luke.

Si estaría dispuesto a admitir "Separate WTF-16" como se indicó anteriormente (la coerción es crucial para permitir el acceso a las API de WASI y para interactuar con JavaScript sin código de pegamento), me sentiría cómodo con el char sugerido Rango de valores. Los lenguajes WTF-16 tendrían entonces la trampilla de escape que necesitan para integrarse tan bien como se obtiene con módulos escritos en el mismo lenguaje, JavaScript y mediante reemplazo con lenguajes UTF- *. También me sentiría mucho mejor con WASI por cierto, ya que el principal punto de dolor introducido por la falta de coincidencia de las codificaciones de cadenas se resolvería con la coerción en su lugar.

Tener un tipo string16 separado como está sugiriendo con los sustitutos todavía tendría todos los problemas con los sustitutos descritos en interface-types / # 135 , así que creo que no sería mejor tener dos tipos de cadenas que .uno (especialmente si son implícitamente interconvertibles; entonces no son tipos significativamente separados). Tener dos tipos de cadenas también empeoraría las cosas concretamente al introducir una carga mental en cada diseñador y consumidor de interfaces ("¿por qué hay dos tipos? ¿Cuál es la diferencia? ¿Cuándo debo usar uno o el otro?"). Por último, agregar soporte para WTF-16 generalmente iría en contra de la futura guía de evolución de estándares Web / IETF también mencionada en interface-types / # 135 . Por lo tanto, no creo que debamos considerar agregar tipos de rodamientos sustitutos a menos que tengamos evidencia concreta real de que los tipos de interfaz no son viables sin ellos.

Para los casos de uso exclusivos de la Web, creo que tendría sentido resolver el problema en JS o Web API. Por ejemplo, es fácil imaginar las API de JS para "vincular" las importaciones y exportaciones de wasm. Este ya es un enfoque que se está adoptando en otras API de JS emergentes, como el cambio de pila, y me he estado preguntando si a dónde vamos es a las API de JS generales de "importación de enlace" / "exportación de enlace" que pueden manejar la Web. -Casos específicos de promesas, cadenas JS y vistas de matriz con tipo.

Tener un tipo string16 separado como está sugiriendo con sustitutos todavía tendría todos los problemas con los sustitutos descritos en interface-types / 135

Técnicamente cierto, pero también pasa por alto que las cadenas al menos siempre funcionarían entre módulos compilados por separado en el mismo idioma, cualquier idioma compatible y JavaScript, incluso sin un conocimiento previo del tipo de módulo con el que se está interactuando. Esa es normalmente la mayoría de los casos, creo. Como tal, me parece un compromiso razonable, también porque permite dedicar el rango de valor char deseado a cadenas bien formadas (USV).

Tener dos tipos de cadenas también empeoraría las cosas concretamente al introducir una carga mental en cada diseñador y consumidor de interfaces ("¿por qué hay dos tipos? ¿Cuál es la diferencia? ¿Cuándo debería usar uno o el otro?")

La alternativa de la rotura ocasional me parece mucho peor, así que si eso es lo que se necesita, creo que a la mayoría de la gente le irá bien. Quizás un buen nombre para el segundo tipo de cadena ( domstring ?) Sea suficiente para mitigar este pequeño problema.

Por último, agregar soporte para WTF-16 generalmente iría en contra de la futura guía de evolución de estándares Web / IETF

Desafortunadamente, en ausencia de una trampilla de escape para los idiomas afectados, no me importa mucho cuán sólido sea el razonamiento de alguien sobre una supuesta tendencia, ya que mientras el MVP de TI va a romper algo en algún lugar para alguien, y es en gran parte inútil. para el lenguaje similar a JavaScript en el que estoy trabajando, solo puedo oponerme.

Por lo tanto, estoy tratando de encontrar una solución razonable o un compromiso con el que todos puedan vivir, y me haría feliz si pudiéramos cooperar.

No veo cómo lo que está diciendo aborda los problemas planteados en los tipos de interfaz / # 135 o proporciona evidencia en contra de que TI no sería viable en general sin la inclusión de un nuevo tipo domstring . La API JS existente ya proporciona una trampilla de escape de propósito general para realizar conversiones de valores arbitrarios en los límites, por lo que no veo cómo se necesita una segunda trampilla de escape en este momento temprano. Creo que simplemente necesitamos más evidencia basada en la experiencia para contrarrestar la sólida orientación que se nos ha dado contra la propagación de cadenas que contienen sustitutos.

(FWIW, si podemos estar de acuerdo en la ausencia de sustitutos, creo que tendría sentido hablar sobre el soporte de U TF-16 como una codificación adicional en el ABI canónico de string . Pero ese es un tema completamente separado con algunas opciones, por lo que no quiero mezclar eso con la semántica de cadena abstracta que debe entenderse primero).

Agradezco su segundo párrafo, en el sentido de que ya resolvería algunos problemas muy molestos. Estoy de acuerdo en que admitir UTF-16 es útil por separado y agradecería que se agregue al explicador / MVP. ¡Cuenta conmigo!

Sin embargo, me está costando seguir sus argumentos en el primer párrafo. Quizás si no me cree, aquí está Linus Torvalds explicando una regla muy importante que creo que se extiende más allá del kernel de Linux: No rompa el espacio de usuario . Y aquí está él en la misma charla, defendiendo la sabiduría del programador de Si es un error en el que la gente confía, no es un error, es una característica , solo para continuar con:

Es realmente triste cuando la biblioteca más básica de todo el sistema está bien para romper cosas siempre que las cosas "mejoren" y "arreglen" la ABI.

Y no tener que preocuparse por los sustitutos es de hecho una especie de característica, ya que los usuarios pueden hacer un substring(0, 1) aquí o allá y llamar a una función importada con él, o pueden split("") , pasar y join() nuevamente, o cree un StringBuilder como un módulo que ocasionalmente no produzca caracteres de reemplazo dobles como si fuera mágico. Quiero decir, hay una razón por la que un montón de lenguajes muy populares optaron por no imponer un formato correcto, y cuando Wasm quiere admitir bien estos lenguajes y sus usuarios, cuanto más modular se vuelve Wasm, más límites habrá, el Será más difícil saber en qué módulo vive una función y más aparente será el problema.

Realmente no sé cuántas pruebas más necesito para demostrar que diseñar algo de una manera que ignore la realidad actual es una mala idea. De hecho, esto parece estar bien solo en los tipos de interfaz, mientras que mantenemos todas las demás propuestas en estándares muy altos. Y aunque no soy un experto en esto, creo que fue el propio estándar Unicode el que cometió exactamente el mismo error con respecto a las necesidades de los idiomas UCS-2 al insistir en los USV, lo que llevó a aproximadamente una década de desesperación similar discusiones (puedo recomendar todo el hilo, pero especialmente el último comentario antes de que se quedara en silencio), en 2014 que culminó con la descripción de la solución práctica comúnmente aplicada que es la codificación WTF-8.

Tenga en cuenta que emitir un carácter de reemplazo cuando se encuentran errores de codificación de caracteres en los flujos de bits es una forma bien conocida de corrupción de datos silenciosa peligrosa y los sistemas que requieren integridad prohíben hacerlo.

De manera relacionada, si codePointAt arrojaría una excepción al golpear a un sustituto solitario, es muy posible que termine con un error que rompa toda su aplicación porque alguien colocó accidentalmente un carácter emoji en la posición incorrecta en una cadena en una base de datos

Desafortunadamente, ecmascript hace que sea muy difícil asegurarse de no generar cadenas con puntos de código sustitutos no apareados en algún lugar de ellas, es tan fácil como tomar las primeras 157 unidades .length de una cadena y quizás agregar "..." para abreviarla. Y es un extraño accidente si eso sucede en la práctica porque los personajes que no son BMP son raros. Deberíamos ser muy reacios a introducir peligros con la esperanza de mejorar nuestra higiene Unicode.

La razón por la que JS, Java y C # tienen las cadenas que tienen es que, cuando Unicode se dio cuenta de que 2 bytes no eran suficientes y, por lo tanto, UCS-2 no era viable, ya se había escrito un montón de código, por lo que estos lenguajes simplemente no lo hicieron. no tengo elección. Del mismo modo, para las llamadas al sistema de Linux expuestas al espacio de usuario. Por el contrario, hoy en día no existe ningún código que utilice API definidas en TI, por lo que no tenemos los mismos requisitos de compatibilidad con versiones anteriores. Por muchas razones, wasm y los tipos de interfaz intencionalmente no buscan emular perfectamente un lenguaje único existente o una ABI de syscall. Puede ser un objetivo válido, pero sería un proyecto / estándar / capa diferente al modelo de componente. Este es el beneficio de la estratificación y el alcance: no necesitamos nada que logre todos los objetivos posibles.

Quiero volver a enfatizar que, por supuesto, dentro de un componente, las cadenas se pueden representar de cualquier manera que sea apropiada para el lenguaje, por lo que en realidad solo estamos hablando de la semántica de las API . En cuanto a las API web ya definidas:

  1. Tenemos muchas razones para creer que no es necesario (y a menudo no tiene sentido) aprobar sustitutos.
  2. siempre existe la vía de escape de usar enlaces de API JS personalizados (no es un requisito que el 100% de las API web tengan un enlace sin pegamento JS a las API web)

Por lo tanto, todavía no creo que tengamos ninguna evidencia que sugiera que TI no será viable sin llevar adelante esta semántica de cadenas WTF-16, que creo que es la pregunta apropiada para un MVP.

Un par de puntos con los que no estoy de acuerdo:

No veo cómo lo que está diciendo aborda los problemas planteados en interface-types / # 135

Este es un tema separado ahora, y en la publicación anterior estaba hablando de lo que creo que es un compromiso razonable para resolver la pérdida. En particular, estaría de acuerdo con su razonamiento en el número separado, pero solo cuando haya una alternativa sin pérdidas disponible. En mi opinión, esto no es un uno u otro. De lo contrario, seguiría siendo de la opinión de que WTF-8/16 es la opción más inclusiva y menos restringida y, como tal, es preferible, también porque uno de los objetivos de alto nivel de Wasm es integrarse sin problemas con la plataforma web, respectivamente, mantener al revés -compatible de la Web, y eso también se aplica a los tipos de interfaz.

La API JS existente ya proporciona una trampilla de escape de propósito general para realizar conversiones de valores arbitrarios en los límites, por lo que no veo cómo se necesita una segunda trampilla de escape en este momento temprano.

siempre existe la trampilla de escape de usar enlaces API personalizados de JS

Lamentablemente, esto no es suficiente en nuestro caso, donde actualmente tenemos un código de pegamento como:

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));
  }
}

Primero, dado que nos preocupamos mucho por Chrome y Node.js, descubrimos que TextDecoder de V8 para UTF-16LE es mucho más lento que en otros motores (SM es realmente rápido), por lo que String.fromCharCode es en realidad más rápido en V8 hasta cierto punto de equilibrio. Así que decidimos optimizarlo por ahora. A continuación, no existe TextDecoder para WTF-16 (que es molesto por separado), por lo que primero intentamos decodificar UTF-16 bien formado, y si eso falla, lo dejamos lanzar y volver a fragmentar el mucho más lento String.fromCharCode . La fragmentación es necesaria porque no se puede simplemente aplicar String.fromCharCode en una cadena larga, ya que es probable que se desborde la pila.

Por otro lado, Rust, por ejemplo, no necesitaría esto, que es una de las razones por las que creo que TI, en este momento, no es tan neutral como debería ser. En general, creo que el objetivo de TI string s es poder interactuar bien con JS, que sigue siendo nuestro principal objetivo de interoperabilidad.

hoy en día no existe ningún código que utilice API definidas en TI, por lo que no tenemos los mismos requisitos de compatibilidad con versiones anteriores

La primera mitad es técnicamente cierta, ya que la TI aún no existe, pero IIUC nuestros requisitos incluyen la mejora de los casos de uso existentes, como por ejemplo, tener en cuenta el fragmento torpe del código de pegamento anterior. Idealmente para tantos idiomas como sea posible, por lo que post-MVP se convierte en "solo una optimización", como dijiste en tu presentación. Por el contrario, en este momento TI básicamente comienza con lo que ya es una optimización para lenguajes que pueden hacer uso de un codificador / decodificador UTF-8, que creo que no es neutral.

wasm y los tipos de interfaz intencionalmente no buscan emular perfectamente un lenguaje único existente o una ABI de syscall

Leí esto como si tuviera esta opinión, que no lo soy en absoluto. Estoy dispuesto a concederle el beneficio de la duda aquí, pero me gustaría añadir que, en mi opinión, la tecnología de la información está actualmente innecesariamente restringida y, como tal, solo sirve para un conjunto muy específico de idiomas. Por el contrario, WTF-8/16 es la codificación más inclusiva que hubiera esperado que fuera la lógica predeterminada, también porque realiza viajes de ida y vuelta a cadenas JS. No estamos de acuerdo aquí, pero solo en ausencia de una escotilla de escape adecuada. Si existiera una alternativa viable sin pérdidas, por lo que nadie está roto o en desventaja innecesaria, estaría bien con su razonamiento del tipo de cadena predeterminado.

Tenemos muchas razones para creer que no es necesario (y a menudo no tiene sentido) aprobar sustitutos.

No estamos de acuerdo aquí. En particular, creo que mi presentación y mis comentarios presentan dudas razonables de que, en algunos casos, aunque sea raro, sea muy significativo (digamos, cuando se requiere integridad), y soy de la opinión de que "Deberíamos ser muy reacios a presentar peligros con la esperanza de mejorar nuestra higiene Unicode ". Es decir, si podemos, creo que deberíamos diseñar el ABI canónico de una manera que garantice que funcione también en los siguientes casos importantes: Java / C # / AS <-> JS, Java / C # / AS <-> Java / C # / AS. El reemplazo en otras rutas es probablemente inevitable, pero al menos los idiomas y los usuarios tienen una opción, respectivamente, el valor predeterminado no está ya roto en casos excepcionales.

Todavía no creo que tengamos ninguna evidencia que sugiera que no será viable sin llevar adelante esta semántica de cadenas WTF-16

En presencia de dudas razonables y ausencia de voluntad para explorar lo que creo que es un compromiso razonable, esperaría que la carga de la prueba recaiga ahora sobre usted. Una vez más, estoy dispuesto a dejarle a usted la cadena predeterminada y un futuro bien formado, pero no a expensas de no tener en cuenta lo que pueden ser peligros raros, pero aún así. Muchos lenguajes populares pueden verse afectados por esto, y eso puede resultar muy difícil de justificar en el futuro una vez que se den cuenta.

Estoy de acuerdo en que el código de pegamento JS no es ideal, pero creo que la solución correcta para eso está en la API de JS o en JS, no agregando el concepto de wtf-16-string a todo el ecosistema de componentes futuros. Más allá de eso, no veo nueva información para responder que no haya sido respondida; parece que en su mayoría estamos en desacuerdo sobre cuestiones de objetivos / alcance.

Esperaría que la anomalía TextDecoder sea ​​aún más difícil de solucionar en JS, ya que aparentemente ya decidió que esto está fuera de alcance. Y JS puede hacer eso, porque TextDecoder en JS no es algo que se invoca entre dos llamadas a funciones , sino que se usa principalmente para recuperar datos a través de la red o del almacenamiento.

Sin embargo, la anomalía aún más interesante es que ni siquiera hay un TextEncoder para UTF-16LE, por lo que hay que hacer:

/** 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;
}

Como puede ver, este es un problema importante para algo como Java, C #, AS y otros, y ambos serían necesarios cuando se pasa un list u16 . Y en el contexto de este problema no es exclusivo de la API de JS, ya que la doble recodificación + pérdida entre dos módulos del mismo idioma no es tan diferente :(

Hay todo un espacio de opciones más allá de TextEncoder / TextDecoder sobre cómo abordar ese caso de uso en la Web. Otro es extender new WebAssembly.Function() (que ya está implementado en algunos navegadores) para realizar conversiones de cadenas agregando parámetros opcionales adicionales al constructor. Este enfoque también pondría la funcionalidad a disposición de los usos de wasm que no son componentes (y potencialmente mucho antes), reforzando el punto de que la API de JS sería el lugar adecuado para abordar este caso de uso.

Para su información: se agregó la opción "Integrated W / UTF-any" que apareció en https://github.com/WebAssembly/interface-types/issues/135#issuecomment -863493832 a la lista de sugerencias anterior :)

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

Temas relacionados

artem-v-shamsutdinov picture artem-v-shamsutdinov  ·  6Comentarios

beriberikix picture beriberikix  ·  7Comentarios

jfbastien picture jfbastien  ·  6Comentarios

chicoxyzzy picture chicoxyzzy  ·  5Comentarios

konsoletyper picture konsoletyper  ·  6Comentarios