Design: 适用于所有字符串编码的 UTF-8

创建于 2017-02-15  ·  80评论  ·  资料来源: WebAssembly/design

目前:

  • 我们对大多数 WebAssembly 的二进制整数编码使用 var[u]int。 一致性很好。
  • 我们对所有“字符串”(例如导入/导出)使用长度 + 字节,并且我们让嵌入器在他们认为合适的时候应用额外的限制(

984 使用 UTF-8 字符串打开了一罐蠕虫。 我们可以:

  • 为每个字节做长度 + UTF-8 的 varuint; 或者
  • 为每个代码点的代码点数 + UTF-8 做 varuint。

我不反对它——UTF-8 非常简单,并不意味着Unicode——但我希望讨论是独立的。 这个问题就是那个讨论。

让我们在这个问题中讨论支持 / 反对 UTF-8 的所有字符串(不是 Unicode )的论点,并在这个问题上投票 👍 或 👎 以获得普遍的情绪。

最有用的评论

我认为您的论点存在域错误。 我们正在谈论的字符串都不是面向用户的。 它们是面向开发的名称。 许多/大多数编程语言不支持 Unicode 标识符,工具也不支持。 例如 gdb 可以处理 Unicode 源标识符吗? 我不这么认为。 因此,假设所有消费者都在这个领域集中使用 Unicode 是非常乐观的(或者更确切地说,不切实际)。

“面向开发”的意思是“面向任意工具链”,这意味着您需要预先就编码达成一致,否则工具将不得不进行编码“检测”(即猜测,这在应用于短值)或具有带外信息。 开发人员仍然是用户。 ^_^

如果您认为很多工具链都不会理解 Unicode,那么我不确定您为什么认为它们会理解任何其他任意二进制编码。 如果这是您的限制,那么只需指定并要求 ASCII,它在任何地方都 100% 支持。 如果您不愿意将自己限制为 ASCII,那么您需要接受一个公认的非 ASCII 编码方案 - UTF-8。

说“嗯,大多数东西可能只支持 ASCII,但我们会让开发人员把他们想要的东西放在那里以防万一”是两个世界中最糟糕的。

所有80条评论

UTF-8 的参数:非常简单。 JavaScript 中的编码器解码器。 同样, UTF-8 不是 Unicode

反对 UTF-8 的论点:它比长度 + 字节稍微复杂一点,导致潜在的实现分歧。

同样,UTF-8 不是 Unicode。

你到底在什么? 这是一句废话。

认为您是想说没有必要引入国际化库。 这是真的 - 强制字符串以 UTF-8 编码与 Unicode 的所有更复杂的部分无关,例如规范化。 当您进行与人类交互的字符串工作时,这些是很有用的工具,但就像三角函数库对做数学的人有用,而在决定如何编码整数时无关紧要。

但 UTF-8 从字面上看是一种 Unicode 编码; 你的陈述没有书面意义。 ^_^

但 UTF-8 从字面上看是一种 Unicode 编码; 你的陈述没有书面意义。 ^_^

是的,我特别指的是 UTF-8 描述的代码点编码,而不是正确处理代码点(就本提案而言,代码点是一个不透明的整数)。 放在 wasm-isms 中,UTF-8 类似于 var[u]int,但更适合字符。 此外,UTF-8 不是唯一的Unicode 编码,它可用于编码非 Unicode 整数。 所以,UTF-8 不是 Unicode。

进一步的提议将查看单个代码点并对其进行处理。 这不是那个提议。

而且没有理由这样做。 除了严格的相等比较和排序之外,没有任何 Web API 发现需要对代码点进行内省,除非它实际上是一个 i18n API。

另一个选项是每个代码点的字节长度 + UTF-8( @jfbastien,除非这是您说每个字节的 UTF-8 时的意思,我承认这对我没有意义)。 我不认为这会让一个并不真正关心的原始解析器变得更加困难,同时允许一个复杂的 Unicode 库将字节数组、偏移量和长度作为输入并返回一个字符串。

我同意“UTF-8 代码点”的定义,它们只是整数。 二进制规范应该保留它。 各个嵌入者可以围绕允许的代码点、规范化和其他细微差别定义规则。 分析工具可以为潜在的兼容性问题提供警告。

我认为错误处理决策也应该留给嵌入者。 通过索引而不是名称访问 WASM 函数的系统不需要它们是有效的(并且它们很容易通过字节长度前缀跳过)。

这是对潜在问题及其原因进行总结的尝试。 更正和补充是最受欢迎的。

wasm 应该要求模块导入/导出标识符是有效的 UTF-8 吗?

我对反对理由的理解是:

  • 处理导入和导出是应用程序启动的关键路径,并且希望避免任何会减慢应用程序速度的事情。
  • 广泛的不变性“核心 wasm 规范不解释字符串”。 字符串解释通常很复杂,人们希望将它封装起来,并具有广泛的不变量和边界,人们可以在高层次上进行推理。
  • WebAssembly 解码器通常对安全性敏感,因此普遍希望最大限度地减少所涉及的代码量。
  • 一些 WebAssembly 生产者可能希望在这些标识符中嵌入任意数据,并且他们更方便地按照自己的意愿对数据进行编码,而不是将其转换为字符串形式。

wasm 应该在不需要它的区域推荐 UTF-8 吗?

原因是即使我们不能要求它,提及 UTF-8 可能会阻止生态系统之间不必要的不​​兼容性。

我对反对理由的理解是,即使提到 UTF-8 也会损害字符串解释问题的概念封装。

wasm 应该为 name-section 名称指定 UTF-8 吗?

原因是:这些名字的全部目的是为了转换成字符串显示,没有编码是不可能的,所以我们应该只指定UTF-8,这样工具就不用猜测了。

我对反对理由的理解是:如果 wasm 在其他区域有其他类似字符串的东西没有指定编码(即上面讨论的导​​入/导出),那么为了一致性起见,它不应该为任何字符串指定编码.

@sunfishcode提供了很好的总结,但我想补充三个关键点。

@jfbastien ,限制字符串的二进制_syntax_(编码)而不是_semantics_(字符集)将是所有替代方案中最没有意义的。 因此,出于所有实际目的,UTF-8 意味着 Unicode。 再说一次,这不仅仅是关于引擎。 如果您将名称定义为 Unicode,那么您将在所有环境中的所有 Wasm 生态系统上强制使用该名称。 这几乎意味着所有环境都需要有一些 Unicode 支持。

@tabatkins ,我认为您的论点存在域错误。 我们正在谈论的字符串都不是_面向用户的_。 它们是面向开发的名称。 许多/大多数编程语言不支持 Unicode 标识符,工具也不支持。 例如 gdb 可以处理 Unicode 源标识符吗? 我不这么认为。 因此,假设所有消费者都_在这个空间_中都聚集在 Unicode 上是非常乐观的(或者更确切地说,不切实际)。

最后,分歧不是网络上的 Wasm _是否_应该假设 UTF-8,而是_where_我们指定了这一点。

我认为您的论点存在域错误。 我们正在谈论的字符串都不是面向用户的。 它们是面向开发的名称。 许多/大多数编程语言不支持 Unicode 标识符,工具也不支持。 例如 gdb 可以处理 Unicode 源标识符吗? 我不这么认为。 因此,假设所有消费者都在这个领域集中使用 Unicode 是非常乐观的(或者更确切地说,不切实际)。

“面向开发”的意思是“面向任意工具链”,这意味着您需要预先就编码达成一致,否则工具将不得不进行编码“检测”(即猜测,这在应用于短值)或具有带外信息。 开发人员仍然是用户。 ^_^

如果您认为很多工具链都不会理解 Unicode,那么我不确定您为什么认为它们会理解任何其他任意二进制编码。 如果这是您的限制,那么只需指定并要求 ASCII,它在任何地方都 100% 支持。 如果您不愿意将自己限制为 ASCII,那么您需要接受一个公认的非 ASCII 编码方案 - UTF-8。

说“嗯,大多数东西可能只支持 ASCII,但我们会让开发人员把他们想要的东西放在那里以防万一”是两个世界中最糟糕的。

说“嗯,大多数东西可能只支持 ASCII,但我们会让开发人员把他们想要的东西放在那里以防万一”是两个世界中最糟糕的。

@tabatkins ,没有人提出上述建议。 正如我所说,问题不是_是否_而是_在哪里_来定义此类特定于平台/环境的事项。 Wasm 应该可以嵌入到最广泛和最异构的环境中,有些环境比其他环境丰富得多(例如,JS _does_ 支持 Unicode 标识符)。 因此,您希望允许在每个平台的基础上进行选择。 因此它属于平台 API 规范而不是核心规范。

别无选择,不过! 如果您的嵌入环境不支持非 ASCII,您只需不要在您的字符串中使用非 ASCII 。 (如果是这种情况,您仍然需要编码保证 - 例如,UTF-16 与 ASCII 不兼容!)

如果您的环境确实支持非 ASCII,您需要知道使用什么编码,所有情况下的正确选择是 UTF-8。

您在想象什么环境中不知道字符串的编码有什么好处?

限制字符串的二进制语法(编码)而不是语义(字符集)将是所有替代方案中最没有意义的。 因此,出于所有实际目的,UTF-8 意味着 Unicode。

不,绝对不会。 例如,同时 (a) 将字符串限制为 ASCII 字符,并且 (b) 规定它以 UTF-8 编码是完全合理的。 使用 ASCII 字符并不意味着编码,否则所有编码都将与 ASCII 兼容! (例如,UTF-16 不是。)所以你仍然需要指定一些东西; UTF-8 是“ASCII 兼容的”,对此很好。

同样,如果您同意将这些名称限制为仅限 ASCII,那么强制要求编码为 US-ASCII 是合理的。 如果您希望它可以超越 ASCII,那么强制编码为 UTF-8 是合理的。 强制执行其他任何操作,或根本不强制执行任何操作(并强迫所有消费者猜测或使用带外信息),是唯一不合理的可能性。

再说一次,这不仅仅是关于引擎。 如果您将名称定义为 Unicode,那么您将在所有环境中的所有 Wasm 生态系统上强制使用该名称。 这几乎意味着所有环境都需要有一些 Unicode 支持。

同样,这看起来像是在谈论国际化库。 我们所讨论的仅仅是如何将字节序列解码回字符串; 这只需要了解如何解码 UTF-8,这是非常简单且非常快的。

除非您正在进行人性化的字符串操作,否则您所需要的只是按代码点比较字符串的能力,并可能按代码点对字符串进行排序,这两者都不需要任何“Unicode 支持”。 例如,这就是现有 Web 技术使用的全部内容,我认为没有任何理由 Wasm 环境通常需要做比这更复杂的事情。

我赞成为所有字符串强制使用 utf8。 对于非 Web 环境,纯 utf8 解码/编码似乎是一个非常低的实现负担(与其他所有内容相比)。 此外,据我所知,与花在其他所有事情上的时间相比,验证 utf8 导入/名称所花费的时间微不足道,所以我认为这里没有性能论据。

实事求是地讲,即使我们没有在核心WASM规范强制UTF8,你有一个坏的时间与任何交互操作,如果除非你是一个的岛屿您的自定义工具链也没使用UTF8,然后也许你刚刚说“搞砸了”,无论如何都要做你自己的非utf8事情......因为那么谁在乎呢。

不过,我真的很想做的是解决#984,它似乎阻止了这个......

@lukewagner我不认为#984 被阻止了。 😄

我想你是对的。

您在想象什么环境中不知道字符串的编码有什么好处?

@tabatkins ,看来我还不够清楚。 我不认为这样的环境。 但是,我想象了具有不兼容要求的广泛环境。 并非所有东西都是UTF-8 的子集,例如Latin1 仍然被广泛使用。 您可能不在乎,但 Wasm 核心规范的工作并不是在环境多样性的道路上放置不必要的石头。

如果您的自定义工具链也没有使用 utf8,除非您是一个孤岛,否则您将很难与任何东西互操作

@lukewagner ,我确实希望 Wasm 将用于可能几乎没有重叠的各种“大陆”。 你可以在他们做什么的地方指定互操作(实际上,名称编码可能是在不同平台之间共享模块的最小问题——它是主机库)。 甚至总孤岛也并非不现实,尤其是嵌入式系统(它们也往往对 Unicode 几乎没有用处)。

实现基于非浏览器的 WebAssembly 引擎最困难的部分之一是让事情按照它在浏览器中的方式工作(主要是 JS 部分)。 我希望如果编码没有标准化,我们最终会得到一个事实上的标准,每个人都复制为 web 目标所做的事情。 这只会导致更难找到有关如何解码这些字符串的信息。

允许某些环境进一步限制允许的内容可能是有价值的,但不要求 UTF-8 只会导致更多的困难。

@MI3Guy ,反建议是将 UTF-8 编码指定为 JS API 的一部分。 因此,如果您正在构建 JS 嵌入,那么无论哪种方式都将其定义为 UTF-8,对您没有任何影响。 (但是,我们还希望允许其他既不是 Web 也不是 JavaScript 的嵌入器 API。)

对。 我的观点是,如果您不进行 JS 嵌入,则必须模拟 JS 嵌入器所做的很多事情才能使用 WebAssembly 工具链。

为每个代码点的代码点数 + UTF-8 做 varuint。

我只想大声反对这个选项。 它使事情复杂化,不适用于用户特定的部分,并且不能提供任何我能看到的好处——为了知道 UTF-8 字符串中的代码点数量,实际上你总是最终扫描字符串无效的编码,因此您不妨在使用时计算代码点。

并非所有东西都是UTF-8 的子集,例如Latin1 仍然被广泛使用。 您可能不在乎,但 Wasm 核心规范的工作并不是在环境多样性的道路上放置不必要的石头。

正确的; 一旦离开 ASCII 范围,UTF-8 就与几乎所有编码都不同。 我不确定你的观点是什么,但是。 实际上使用Latin-1 编码是不好的,因为有很多其他的编码看起来相同但编码不同的字母。 如果您尝试在您的 Wasm 代码中使用名称“æther”,并将其编码为 Latin-1,那么其他人(合理地)尝试使用 UTF-8 工具链读取名称,他们将收到解码错误。 或者,也许另一个人犯了类似的错误,但改用了 Windows-1250 编码(用于中欧/东欧语言)-他们会得到无意义的单词“ćther”。

我真的不确定你想在这里保护什么样的“多样性”。 使用任何其他编码实际上没有任何好处,并且有很多缺点。 你可以用另一种编码编码的每个字符都存在于 Unicode 中,并且可以用 UTF-8 编码,但反过来几乎从来都不是真的。 目前没有相关工具无法处理 UTF-8; 这项技术实际上已经有二十年历史了

我一直告诉你 Web 标准在几年前就解决了这个问题,不是因为 Wasm 是一个需要遵循 Web 规则的 Web 规范,而是因为文本编码是一个生态系统问题,几乎每个人都有同样的问题,而 Web 已经解决了带着犯错的痛苦,并且已经学会了如何正确地做。 在 Wasm 中再次出错没有任何好处; 每个必须对文本进行编码的环境要么从一开始就直接使用 UTF-8,要么像其他人一样犯同样的错误并遭受同样的痛苦,然后最终选择 UTF-8。 (或者,在极少数情况下,开发一个足够隔离的环境,他们可以标准化不同的编码,并且很少支付与外部环境通信的代价。但他们标准化了编码,这就是所有这一切的重点。)

因此,如果您正在构建 JS 嵌入,那么无论哪种方式都将其定义为 UTF-8,对您没有任何影响。 (但是,我们还希望允许其他既不是 Web 也不是 JavaScript 的嵌入器 API。)

这个问题与 Web 或 JS 无关。 生态系统的每个部分都需要一种已知的、一致的文本编码,并且有一个在编程环境、国家和语言中得到广泛认同的编码:UTF-8。

我投票支持'为长度(以字节为单位)+ UTF-8 为每个字节做 varuint'。 假设这不是一个有争议的选择——几乎每个字符串实现都将字符串存储为“代码单元数”而不是“代码点数”,因为它更简单——那么真正的问题不是“如果字符串不是,验证是否应该失败有效的 UTF-8”?

正如我在 #970 中指出的那样,无效的 UTF-8 可以往返转换为 UTF-16,因此如果允许无效的 UTF-8,不想存储原始字节的软件就不必这样做。 另一方面,检查 UTF-8 是否有效并不难(尽管我们必须回答——是否应该接受过长的序列?代理字符?)

总的来说,我倾向于说让我们强制使用 UTF-8。 在某人拥有无法转换为 UTF-8 的字节(可能是因为编码未知)的奇怪情况下,可以将任意字节音译为 UTF-8。

我真的不确定你想在这里保护什么样的“多样性”。

@tabatkins ,是的,这似乎是误解的核心。

重要的是要意识到 WebAssembly,尽管它的名字,并不局限于网络。 我们非常谨慎地将其定义在合适的层中,以便每一层都尽可能广泛地使用。

最值得注意的是,它的_核心_实际上_根本不是一种网络技术_。 相反,尝试将其视为 _virtual ISA _。 这种抽象在广泛的不同环境中很有用,从非常丰富的(网络)到非常简陋的(嵌入式系统),它们之间不一定有任何关系,可能在很大程度上不兼容,并且具有相互冲突的约束( Wasm 无法改变)。

因此,将 Unicode 强加到 _core_ Wasm 上并没有比将 Unicode 强加到 C 编程语言中的所有字符串文字更有意义。 你只会强迫一些潜在客户违反这一点标准。 有什么收获?

然而,在这个核心规范之上将有额外的规范层,用于在 _concrete_ 环境(例如 JavaScript)中定义其嵌入和 API。 在该级别上修复字符串编码非常有意义,无论如何,我们应该这样做。

PS:定义 Wasm 范围的口号是它是对通用硬件的抽象,而不是对通用编程语言的抽象。 并且硬件与诸如字符串编码之类的软件问题无关。 这就是 ABI 的用途。

@罗斯伯格铬

因此,在核心 Wasm 上强加 Unicode 并没有比在 C 编程语言中的所有字符串文字上强加 Unicode 更有意义。 你只会强迫一些潜在客户违反这一点标准。 有什么收获?

我同意 100%。 这个问题与 Unicode 无关,它纯粹是关于 UTF-8,一种整数编码,而不强制要求将整数解释为 Unicode。

我不明白我们是否同意这一点。 您能否澄清一下:您对 UTF-8 是否满意,如果不是为什么?

@jfbastien ,要求所有 C 字符串文字都符合 UTF-8 会更有效率吗?

正如我之前提到的,限制编码而不是字符集对我来说毫无意义。 这就像定义没有语义的语法。 你为什么要这样做? 您在互操作方面的收益为零,但仍然为不使用 UTF-8 的环境(无论如何只有 Unicode 环境这样做)设置了人为的障碍。

@jfbastien ,要求所有 C 字符串文字都符合 UTF-8 会更有效率吗?

不明白,能解释一下吗?

正如我之前提到的,限制编码而不是字符集对我来说毫无意义。 这就像定义没有语义的语法。 你为什么要这样做? 您在互操作方面的收益为零,但仍然为不使用 UTF-8 的环境(无论如何只有 Unicode 环境这样做)设置了人为的障碍。

我认为这是讨论的关键。

@tabatkins提到了这方面的先例:

同样,这看起来像是在谈论国际化库。 我们所讨论的仅仅是如何将字节序列解码回字符串; 这只需要了解如何解码 UTF-8,这是非常简单且非常快的。

除非您正在进行人性化的字符串操作,否则您所需要的只是按代码点比较字符串的能力,并可能按代码点对字符串进行排序,这两者都不需要任何“Unicode 支持”。 例如,这就是现有 Web 技术使用的全部内容,我认为没有任何理由 Wasm 环境通常需要做比这更复杂的事情。

所以我同意:用你的话来说,这个提议是“定义没有语义的语法”。 这是常见的事情。 事实上,WebAssembly 目前的长度 + 字节规范已经做到了这一点!

我想了解障碍是什么。 我真的没有看到一个。

重要的是要意识到 WebAssembly,尽管它的名字,并不局限于网络。

我刚刚在之前的评论中指出,这与网络无关。 你一直试图使用这个论点,这让我很困惑。 我所说的与网络无关; 我只是将网络的经验作为经验教训的一个重要例子。

因此,在核心 Wasm 上强加 Unicode 并没有比在 C 编程语言中的所有字符串文字上强加 Unicode 更有意义。 你只会强迫一些潜在客户违反这一点标准。 有什么收获?

您没有提出您认为的观点 - C确实具有内置编码,因为字符串文字使用 ASCII 编码。 (如果您想要其他任何东西,您必须通过转义适当的字节序列来手动完成。)在更当前的 C++ 中,您可以使用 UTF-16 和 UTF-8 字符串文字,同时您仍然可以将任意字节放入字符串中\x转义, \u转义至少验证该值是一个有效的代码点。

所有这些都是必需的,因为没有从字符到字节的固有映射。 这就是编码的作用。 同样,没有指定的编码只是意味着语言的用户,当他们从其他方接收字节序列时,必须猜测编码才能将它们转回文本。

您在互操作方面的收益为零,但仍然为不使用 UTF-8 的环境(无论如何只有 Unicode 环境这样做)设置了人为的障碍。

可否请您点存在的环境,不包含在Unicode使用字符? 您一直试图从理论纯度/环境多样性的角度来捍卫这一立场,但实际上 Unicode 的全部意义在于包括所有字符。 它是唯一可以为这样做提供远程可信参数的字符集,并且当您使用 Unicode 字符集时,UTF-8 是首选的通用编码。

你试图保护什么多样性? 看到一个例子就太好了。 :/

@塔巴特金斯

重要的是要意识到 WebAssembly,尽管它的名字,并不是
仅限于网络。

我只是在前面的评论中说这没有什么
与网络有关。 你一直试图使用这个论点,它真的
迷惑我。 我所说的与网络无关; 我只是
指出网络的经验是经验教训的一个重要例子。

我想强调的是,Wasm 应该适用于尽可能多的
平台尽可能,现代与否。 你从幸福的结局开始争论
一切都是Unicode和/或UTF-8的范围,以及一切
其他只是被弃用。

你没有表达你认为你在表达的观点 - C确实有一个

内置编码,因为字符串文字使用 ASCII 编码。 (如果你想
您必须通过转义适当的字节手动完成的任何其他操作
序列。)在当前的 C++ 中,您可以使用 UTF-16 和 UTF-8 字符串
文字,虽然您仍然可以将任意字节放入字符串中
\x 转义,\u 转义至少验证该值是有效的
代码点。

不,那是不正确的。 C 规范不需要 ASCII。 它甚至不
要求与 ASCII 兼容。 它允许几乎任意的“源
字符集”和字符串文字可以包含完整的任何字符
放。 没有关于编码的限制,它完全是
实现定义。 已经有 C 的实现在运行
EBCDIC 平台,并且当前标准仍然支持。 海湾合作委员会
可以处理任何 iconv 编码的源(其中大约有 140
除了UTF-8),例如在亚洲流行的UTF-16。 C++ 也不例外。

(这也应该回答@jfbastien的问题。)

所有这些都是必需的,因为没有来自字符到字节。 这就是编码的作用。 再次,没有
指定的编码仅意味着该语言的用户,当他们收到
来自其他方的字节序列,必须猜测编码转
他们回到文本。

再次:这个_将_根据环境适当指定。 当有人
从在同一生态系统中运行的其他人那里接收一个 Wasm 模块
那么没有问题。 任何 JS 开发人员都不需要关心。

但是,如果有人从_另一个生态系统_接收模块,那么
还有很多其他不兼容的来源需要担心,例如
对 API、内置库等的期望。双方都需要
无论如何都要明确他们的互操作假设。 同意一个名字
编码将是他们的问题中最少的。

您在互操作方面的收益为零,但仍然为

不使用 UTF-8 的环境(只有 Unicode 环境使用)
反正)。

能否请您点的环境中存在使用
未包含在 Unicode 中的字符? 你一直试图捍卫这一点
从理论纯度/环境多样性的角度来看,但
从字面上看,Unicode 的全部意义在于包括所有字符。 这是唯一可以远程创建的字符集
这样做的可信论据,以及当您使用 Unicode 字符时
设置,UTF-8 是首选的通用编码。

你试图保护什么多样性? 即使能看到也会很棒
一个例子。 :/

例如,以下是嵌入式操作系统列表: https :
类别:嵌入式操作系统
其中一些可能使用 UTF-8,有些则不会。 有些人可能会发现 Wasm 的用途,
很可能不会。 但是减少它对我们没有任何好处
方便他们。

您可能仍然熟悉该列表中的一个条目是 DOS。 作为
尽管我们都喜欢它死,但 DOS 系统仍然很活跃,它们使用
原始设备制造商。

@jfbastien :

所以我同意:用你的话来说,这个提议是“定义没有
语义”。这是常见的事情。事实上,WebAssembly 的
当前长度 + 字节规范已经做到了这一点!

我所知道的这种事情的罕见发生都与
为特定于实现的行为提供逃生舱口。 那是
也是唯一合理的用例。 不过,这在这里没有意义。 如果你
想要为字符串提供这样的逃生舱口,那为什么还要要求
UTF-8,而不是允许任何字节字符串“语法”? 这是没有的语法
语义作为禁用器,而不是启用器。

我想了解障碍是什么。 我真的没有看到一个。
>
某些客户端不能简单地使用所有字节值而必须经过
在生态系统中没有用的冗余 UTF 编码。 那一切
他们的工具链中的工具也必须为此烦恼。 那它
创建不会的其他错误情况(超出范围值)
否则为他们而存在。

让我反过来问:(在他们的生态系统中)有什么好处?
我真的没有看到一个。

@tabatkins
想确保我了解分界线的位置。
需要明确的是,您只建议对代码点进行 utf-8 编码,而不管它们是否组合无效(可以在 10 行代码中完成)。
例如,可以在规范中使用粗体大写字母来表示:如果您认为需要一个国际化库来实现 Wasm,那么您做错了什么?

这样做的目标是:

  • 确保任何最终出现在网络上的有效 wasm 至少可以显示无效内容的豆腐字符。
  • 鼓励生成 wasm 的工具(即使在 Web 之外的上下文中)在需要超越 ascii 时更喜欢 unicode 而非其他编码。 (在这个方向上的软碰撞不会发生完全验证)。

问题?

  • 这是否会成为更多验证的潜移默化要求? 我认为我在这个领域的核心担忧是,将 ICU 视为依赖项将永远是一种不合理的负担。
  • 我认为这意味着积极鼓励像 Latin1 这样与 UTF-8 冲突的编码的目标? 即发出它的工具链将是不合规的,同样地接受它的实现。

  • 由于重叠使用来自以前编码孤岛的区域的位,我认为网络历来难以统一这个空间。 另一方面,我的印象是 UTF-8 设置的东西使得转换成本不成比例地由非 ASCII 人承担,并且某些地区有更多的烘烤。我认为 unicode 转换是一种实际的必然性(并且几乎完成)。 是否有一些我们可以指出的集中式文档/实体来解决有关 unicode 的一些政治和区域问题是如何在网络上解决的?

@罗斯伯格铬

  • 我看到验证编码的某些方面而不是其他方面的逻辑不一致。 另一方面,我的印象是 utf8 在这一点上很普遍(并且工具 + 验证中的一小部分成本很低)。 您的主要不适是将裸 utf-8 验证添加到规范中是不一致还是其他原因?

需要明确的是,您只建议对代码点进行 utf-8 编码,而不管它们是否组合无效(可以在 10 行代码中完成)。

是的,我不相信有任何无效的组合; 只有一些单独的代码点(为 UTF-16 代理保留的代码点)在技术上无法编码为 UTF-8。 也就是说,如果需要完整的字节控制,那么WTF-8 编码确实存在,但是我们应该非常明确地将“是的,我们希望有时允许这些字符串在其中实际包含任意非字符串数据”作为目标,如果我们走那条路。 WTF-8(和 WTF-16)格式仅旨在为在强制执行 UTF-* 格式良好方面具有向后兼容约束的环境提供正式规范。

例如,可以在规范中使用粗体大写字母来表示:如果您认为需要一个国际化库来实现 Wasm,那么您做错了什么?

是的,i18n 不需要任何方式、形状或形式。 例如,CSS 默认为 UTF-8,并且仅在允许 ASCII 范围之外的内容时进行原始代码点比较/排序。 Wasm 也没有理由走得更远。

这是否会成为更多验证的潜移默化要求? 我认为我在这个领域的核心担忧是,将 ICU 视为依赖项将永远是一种不合理的负担。

到目前为止,Web 平台从未需要对裸名进行额外的验证。 我的经验表明它永远没有必要。

我认为这意味着积极 [dis -ed] 鼓励像 Latin1 这样与 UTF-8 冲突的编码的目标? 即发出它的工具链将是不合规的,同样地接受它的实现。

是的,用你的话改为“令人沮丧”。 ^_^ 重点是生产者和消费者可以可靠地编码和解码字符串到/从字节序列,而不必猜测另一个端点在做什么。 对于曾经遇到过它的每个环境来说,这都是一种可怕的痛苦,现在有一种广泛采用的解决方案。

由于重叠使用来自以前编码孤岛的区域的位,我认为网络历来难以统一这个空间。 另一方面,我的印象是 UTF-8 设置的东西使得转换成本不成比例地由非 ASCII 人承担,并且某些地区有更多的烘烤。我认为 unicode 转换是一种实际的必然性(并且几乎完成)。 是否有一些我们可以指出的集中式文档/实体来解决有关 unicode 的一些政治和区域问题是如何在网络上解决的?

是的,它在过渡过程中肯定存在问题; 由于向后兼容,HTML 仍然需要默认为 Latin-1,并且仍然有一些小范围的 Web 内容更喜欢特定于语言的编码(主要是 Shift-JIS,一种日语编码)。 但在过去的二十年里,世界上绝大多数地区都发生了转变,现在人们认为这种转变或多或少已经完成。

长期以来,“UTF-8 给非 ASCII 人带来负担”一直是一个有害但几乎完全不真实的谣言。 大多数欧洲语言首先包含大部分 ASCII 字母表,因此它们的大部分文本都是单字节序列,最终小于 UTF-16。 这同样适用于拼音等书写系统。 CJK 语言主要占据 3 字节的 UTF-8 区域,但它们也包含大量 ASCII 字符,尤其是在标记语言或编程语言中,因此,一般而言,对于 UTF-8,请参阅更小或类似的编码大小UTF-16 或其专用编码。

仅对于 CJK 或非 ASCII 字母(如西里尔字母)中的大量原始文本,我们看到 UTF-8 实际上比专用编码占用更多空间。 然而,在90 年代初,这些都是令人担忧的问题,当时硬盘容量以兆字节为单位,文本文件大小的轻微膨胀实际上可能很重要。 近 20 年来,这一直不是一个问题; 现在大小差异完全无关紧要。

Wrt 到“Unicode 转换”,这已经非常普遍地发生了。 如今,一种不需要用 UTF-8 编码的文本格式正在犯一个可怕的、非历史性的错误。

我不确定是否有任何具体的文件概述了这些内容,但我敢打赌它们存在于某个地方。 ^_^

如果目标是保持二进制规范尽可能纯净,让我们完全删除名称。 无论如何,它的所有内部引用都基于索引。

相反,向需要 UTF-8 的 JavaScript 规范添加一个强制性的自定义部分。 其他环境,例如@rossberg-chromium 暗指的苏联时代的大型机,可以定义自己的自定义部分。 通过提供两个自定义部分,单个 WASM 文件可以支持两个平台。 自定义工具通过转换更流行的部分来生成晦涩的平台缺失部分会相对简单。

如果目标是保持二进制规范尽可能纯净,让我们完全删除名称。 无论如何,它的所有内部引用都基于索引。

这是对导入/导出工作方式的重新设计。 它不在桌面上,应该在与此不同的问题中提出建议。

@bradnelson
结合了两全其美:它在以下方面施加了成本
限制、复杂性和开销,但在以下方面没有实际好处
互操作。 我想我仍然很困惑这点是什么。

@rossberg-chromium 这里寻求的主要好处是减轻工具和库的猜测负担。

由于这里寻求的主要好处是减轻工具和库的猜测负担,因此讨论的任何上述变体(UTF-8 与 WTF-8 等)都比没有好,因为即使在最坏的情况下, “我很确定我无法从字面上对这些字节进行转码”比“这些字节看起来像是 windows-1252;也许我会尝试一下”。 众所周知,猜测容易出错,这里寻求的主要好处是减轻工具和库的猜测负担。

@sunfishcode ,怎么样? 我还是迷路了。

所以这是一个具体的场景。 假设我们在不同的平台上,而我正在尝试向您传递一个模块。 假设为了论证,我的平台使用 EBCDIC 而你的 ASCII。 根据当前的提议完全合法。 然而,我的模块对你和你的工具链完全没用。

这两种编码都是 7 位,因此 UTF-8 甚至不会进入图片。

那么 UTF-8 会带来什么? 好吧,我可以“解码”我得到的任何未知字符串。 但就我所知,结果是_只是另一个 31 位值的不透明二进制 blob_。 它不提供任何信息。 我不知道如何将它与我自己的字符串相关联。

那么,为什么我还要费心去解码一个未知的字符串呢? 好吧,_我不会_! 我也可以使用 8 位值的原始二进制 blob 并节省空间和周期。 不过,该规范仍然需要我花费周期来空洞地验证编码。

考虑到所有这些,通过采用这个特定的提案,(核心)Wasm 或工具会获得什么?

AFAICS,规定了特定的编码但没有字符集
结合了两全其美:它在以下方面施加了成本
限制、复杂性和开销,但在以下方面没有实际好处
互操作。 我想我仍然很困惑这点是什么。

我们肯定会强加一个字符集 - Unicode 字符集。 JF 之前的措辞非常混乱,请不要在意。 这并不意味着我们需要向 Wasm 添加检查以实际执行此操作; 解码器通常足够强大,可以处理无效字符。 (例如,网络通常只是用 U+FFFD 替换字符替换它们。)

所以这是一个具体的场景。 假设我们在不同的平台上,而我正在尝试向您传递一个模块。 假设为了论证,我的平台使用 EBCDIC 而你的 ASCII。 根据当前的提议完全合法。 然而,我的模块对你和你的工具链完全没用。

需要停止假装几十年的旧系统不仅相关,而且相关性如此之高,以至于它们证明做出与我们在过去几十年中所学到的关于编码痛苦的所有知识背道而驰的决定是合理的。 您坚持认为 Web Assembly 在与古老的大型机交谈时会扭曲自身以最大限度地提高便利性,而忽略了世界上其他所有人能够可靠地交流文本数据的好处,这对任何人都没有帮助。 你只会伤害语言,让 99.9%(非常保守的估计)用户的生活变得更加艰难。

许多不同的系统都经历了所有这些混乱。 编码战争并不好玩。 他们浪费了大量金钱和时间,并导致了大量损坏的文本。 我们结束了那些战争,不过。 Unicode 被创建和发布,并成为整个世界的主要字符集,以至于所有其他字符集在这一点上实际上只不过是历史上的好奇心。 我们仍然对是否使用 UTF-16 与 UTF-8 进行低级别的酝酿斗争,但至少这两者通常很容易区分(查看 BOM,或寻找占优势的空字节),以及整体 UTF -8 轻而易举地占主导地位。

您对编码自由的坚持忽略了所有这段历史,也忽略了自引入 Unicode 以来的 20 年中学到的所有经验教训。 它忽略了设计现代系统的所有经验和专业知识,这些经验和专业知识使大多数用户看不到编码问题,因为系统可以依靠以特定方式编码的所有内容。 如果您坚持这样做,一次一个 mojibake,您将产生严重的、有害的、代价高昂的问题。

@罗斯伯格铬

所以这是一个具体的场景。 假设我们在不同的平台上,而我正在尝试向您传递一个模块。 假设为了论证,我的平台使用 EBCDIC 而你的 ASCII。 根据当前的提议完全合法。 然而,我的模块对你和你的工具链完全没用。

那么 UTF-8 会带来什么? 好吧,我可以“解码”我得到的任何未知字符串。 但就我所知,结果只是另一个 31 位值的不透明二进制 blob。 它不提供任何信息。 我不知道如何将它与我自己的字符串相关联。

UTF-8 会准确地告诉您如何将它与您自己的字符串相关联。 这正是它要解决的问题。 (WTF-8 在它可以的时候也会,它会在它不能的时候明确地告诉你。)

您的意思是将任意数据结构转换为字符串形式然后编码为 UTF-8? 确实,您无法对其进行 demangle,但您至少可以明确地将损坏的名称显示为字符串,这比在某些用例中没有任何内容有所改进。

你的意思是上面关于使用 UTF-8 作为不透明整数编码而不是 Unicode 的讨论吗? 我认为讨论有些混乱。 将编码称为“语法”和国际化“语义”很诱人,但这掩盖了一个有用的区别:UTF-8 仍然可以说某个字节序列表示“Ö”,而无需说明消费者与该信息有什么关系。 以这种方式使用,它是 Unicode 的一种编码,但它不需要上面使用的“Unicode Support”所建议的那种成本。

那么,为什么我还要费心去解码一个未知的字符串呢? 好吧,我不会! 我也可以使用 8 位值的原始二进制 blob 并节省空间和周期。 不过,该规范仍然需要我花费周期来空洞地验证编码。

我现在已经构建了一个 SpiderMonkey,对 wasm 导入/导出标识符进行了完整的 UTF-8 验证,包括超长和代理。 我无法检测到WebAssembly.validate的性能差异,无论是在 AngryBots 上,还是在一个小的 emscripten 编译的测试用例上,尽管如此,它仍然有 30 个导入。

该规范是多个关注点之间的折衷。 我很欣赏对启动时间的关注,因此我现在进行了一些实验并对其进行了测量。 我鼓励其他人做自己的实验。

此外,UTF-8 不是唯一的 Unicode 编码,它可用于编码非 Unicode 整数。 所以,UTF-8 不是 Unicode。

UTF-8 可以编码哪些不属于 Unicode 的整数(即,在 U+0000 到 U+10FFFF 范围之外)? 这种说法似乎是错误的。

如果不验证字符,则可以对任何 21 位整数进行编码。

不太确定为什么我们不会验证...

@flagxor https://encoding.spec.whatwg.org/描述了暴露在网络上的各种编码。 请注意,它们都没有超出 Unicode 字符集,但它们显然并非全部字节兼容。

“验证”会做什么? 让你的 wasm 程序无效? 我认为没有任何可以合理施加的实际后果。

就像,在 CSS 中使用无效转义只会将 U+FFFD 放入您的样式表中,它不会做任何奇怪的事情。

@annevk

此外,UTF-8 不是唯一的 Unicode 编码,它可用于编码非 Unicode 整数。 所以,UTF-8 不是 Unicode。

UTF-8 可以编码哪些不属于 Unicode 的整数(即,在 U+0000 到 U+10FFFF 范围之外)? 这种说法似乎是错误的。

至少:U+FFFE 和 U+FFFF 在 Unicode 中是非字符。 Unicode 永远不会使用代码点(整数值)来编码字符,但它们可以用 UTF-8 编码。

不过,它们仍然是 Unicode 代码点。 我不会过多关注“角色”。

@tabatkins解码为 U+FFFD 是合理的,但这限制了您可以获得的整数数量。

因此,在核心 Wasm 上强加 Unicode 并没有比在 C 编程语言中的所有字符串文字上强加 Unicode 更有意义。 你只会强迫一些潜在客户违反这一点标准。 有什么收获?

您可能会注意到 C11 添加了char16_tchar32_t类型以及u UTF-16 编码字符串文字的前缀, U前缀用于UCS-4 编码的字符串文字,以及 UTF-8 编码的字符串文字的u8前缀。 我没有深入挖掘他们添加它们的理由,但我认为“在标准 C/C++ 中处理 Unicode 是一场噩梦”至少是动机的一部分。

@tabatkins@sunfishcode ,好吧,所以你们说的不是同一件事。 但是 AFAICT @jfbastien已经明确反复声明他的提议是关于指定没有 Unicode 字符集的 UTF-8。

这也是低成本主张成立的唯一解释。

因为如果我们实际上 _do_ 假设 UTF-8 意味着 Unicode 那么这个要求肯定比任何系统上的任何工具的 UTF-8 编码/解码都要昂贵得多,这些工具还没有碰巧谈论(子集)Unicode——他们'd 需要包括一个完整的转码层。

@tabatkins ,核心 Wasm 将嵌入到预先存在的系统中——有时是出于便携性以外的其他原因——它无权改变或强加任何东西。 如果他们面临您描述的问题,那么这些问题独立于 Wasm 存在。 _我们_无法解决_他们的_问题。

_trying_ 将 Unicode 强加给所有这些的可能结果是,一些潜在的将简单地违反规范的那部分,使其完全没有实际意义(或者更糟的是,他们将完全无视 Wasm)。

如果 OTOH 我们在适当的层指定它,那么我们就不会冒这种风险——在实践中不会丢失任何东西。

因为如果我们确实假设 UTF-8 意味着 Unicode,那么对于任何系统上的任何工具来说,这个要求肯定比 UTF-8 编码/解码要昂贵得多,这些工具还没有碰巧谈论(的)Unicode(子集)——他们'd 需要包括一个完整的转码层。

哪些平台使用非 Unicode 而非 ASCII 的本机字符集,没有将这些字符转换为 Unicode 或从 Unicode 转换的工具,并且需要在 Wasm 中使用非 ASCII 标识符? (我的意思是真的存在,而不是某个决定在 DOS 中使用 Wasm 的假设性俄罗斯组织。)

@rocallahan我相信 @rossberg-chromium 关注(或者至少我会关注)像嵌入式系统这样的设备,它们不希望增加一个完整的 ICU 库的成本。 他们要么被迫接受膨胀,不进行完整验证,要么不接受包含非 ascii 字符(他们可能无法控制)的 wasm 文件。

此外,严格来说,此类设备通常包括具有非标准字符集的硬件,例如:
https://www.crystalfontz.com/product/cfah1602dyyhet-16x2-character-lcd?kw=&origin=pla#datasheets
https://www.crystalfontz.com/products/document/1078/CFAH1602DYYHET_v2.1.pdf
(其中有一个愚蠢的混合 ascii + latin1 + 日语字符集)
但问题是你必须验证什么,这无论如何都是相关的。

@tabatkins虽然我认为已经表明意图是:

  • 强制 UTF-8 + Unicode 作为字节的唯一“正确”解释
  • 显式声明 Unicode 不必验证模块进行验证(以节省成本)

我相信@rossberg-chromium 关注(或者至少我会关注)像嵌入式系统这样的设备,它们不希望增加一个完整的 ICU 库的成本。 他们要么被迫接受膨胀,不进行完整验证,要么不接受包含非 ascii 字符(他们可能无法控制)的 wasm 文件。

正如一再重申的那样,这是一个红鲱鱼。 不需要做任何远程ICU相关的事情; 网络绝对不会这样做。 请停止传播这种不正确的信息。

“完全验证”是一项极其简单的操作,作为符合 UTF-8 解码操作的一部分自动完成。

在与@tabatkins聊天时,我认为有一件事情很重要,需要明确:
要求符合 Unicode 解码器以允许修饰符未分配代码点等的任意组合。因此,Unicode 需要允许修饰符等的杂散混合,即使它不会呈现为合理的东西。 拒绝无意义组合的解码器将是不合规的。

因此,正确 UTF-8 解码的要求被明确界定为您可以在几行代码中完成的事情,是一个精确的操作,并且本质上等同于指定字节的 unicode + utf-8 解释。

是的。 解析 UTF-8 非常简单; 唯一的问题是一些不允许以 UTF-8 编码的代码点,兼容的解码器会将其解析为一个或多个 U+FFFD 字符。

但这是端点要做的操作。 Wasm 不必关心这些; 兼容的解码器可以处理您抛出的任何任意位模式。 (他们只会决定大部分垃圾位模式是 U+FFFD 字符。)一直以来,我一直在要求的是作者级别的一致性要求,即这些字符串用 UTF-8 编码。 如果您违反了这一点,您的工具链可以将其标记为错误,但 Wasm 本身无需执行任何操作。

这类似于,例如,CSS 定义了构成有效样式表的语法,但在技术上仍然接受任何任意的位模式。

此外,严格来说,此类设备通常包括具有非标准字符集的硬件,例如:

这种字符集的存在与 Wasm 无关,除非您希望人们在它们(的非 ASCII 范围)中编写 Wasm 标识符。

是的,所有“使用 UTF-8”的意思都是https://encoding.spec.whatwg.org/#utf -8-decoder。 ICU 甚至还没有达到要求。

二月2017年25 01:13,布拉德·尼尔森[email protected]写道:

在与@tabatkins https://github.com/tabatkins聊天时,有一件事
我认为在这里明确这一点至关重要:
需要符合标准的 Unicode 解码器以允许任意
修饰符未分配代码点等的组合。
修饰符等,即使它没有呈现为合理的东西,也是
需要被 Unicode 允许。 拒绝废话的解码器
组合将不合规。

因此,正确 UTF-8 解码的要求被明确界定为
你可以在几行代码中完成的事情是一个精确的操作,
并且本质上等同于指定一个 unicode + utf-8
字节的解释。

为了澄清我所说的。 我不否认完整的 ICU 可能不会
必要的(尽管例如按代码点排序名称听起来很糟糕
可用性)。

然而,只剩下微不足道的解码的说法是不正确的
或者,因为它不会停止验证。 非 Unicode 平台
将被迫执行转码以实际处理它们的字符串。
此外,他们将不得不处理字符的问题
无法映射(在任一方向),因此您仍然具有兼容性
一般的问题,只是踢了可以下路。

>

此外,严格来说,此类设备通常包括具有以下功能的硬件
非标准字符集,如:

这些字符集的存在与 Wasm 无关,除非您
期望人们在它们(的非 ASCII 范围)中编写 Wasm 标识符。

@rocallahan https://github.com/rocallahan ,他们仍然必须能够
接受任意 Unicode。 但他们会用它做什么? 如果一个 Wasm
在这种仅限于 ASCII 的平台上实现,那么它将是
违反了提议的规范。 (我也认为这意味着
某人的非 ASCII 字符是无关紧要的,可能是文化上的先验
可疑的。 这应该由他们来决定。)

此外,他们将不得不处理无法映射(在任一方向)的字符问题,因此通常您仍然会遇到兼容性问题,只是将罐子踢了下来。

这是一个理论上的问题吗?

如果这是一个合理的担忧,我们必须再次权衡处理它的(发生率 * 成本)与世界

非 Unicode 平台将被迫执行转码以实际处理其字符串。

但是,在什么情况下,Wasm 字符串需要与平台字符串互操作? 据我所知,我们只是在讨论 Wasm 元数据中的字符串编码,而不是由实际模块代码操作的字符串编码。 (如果那是错误的,我道歉......)然后我只能想到可能需要互操作/转码的几种可能情况:

  • Wasm 模块导入平台标识符
  • 平台导入一个 Wasm 标识符
  • 您可以提取 Wasm 名称并打印它们或使用平台字符串保存它们,例如转储堆栈跟踪。

对?

对于假设的非 Unicode 嵌入式系统,对于前两种情况,建议很简单:将跨平台边界导入的标识符限制为 ASCII,然后所需的转码是微不足道的。 Wasm 模块仍然可以在内部使用完整的 Unicode 名称并用于相互链接。

对于第三个问题——如果你有一个封闭的 Wasm 模块世界,你可以将它们的标识符限制为 ASCII。 如果没有,那么在实践中你会遇到 UTF8 标识符,你最好能够对它们进行转码,你会很高兴规范强制使用 UTF8!

暗示某人的非 ASCII 字符与先验无关

这是一个稻草人的论点。 这里的立场是“如果您想要非 ASCII 标识符,请使用 Unicode 或实现转码到/从 Unicode”,并且在其他规范中,AFAIK 并没有因为“文化上有问题”而受到批评。

>

如果这是一个合理的担忧,我们必须再次权衡(发生

  • 成本)与几乎所有其他成本的对比世界上的 Wasm 用户无法依赖编码,并且
    不得不处理 Web 平台必须经历的相同编码地狱,
    并最终尽可能地修复。

@tabatkins ,不,再次(不知何故,我觉得我已经重复了这 100
次):每个嵌入规范 _will_ 指定一个编码和
字符集。 在每个平台上,您都可以信赖这一点。 你只会跑
如果您尝试在两个不相关的之间进行互操作,则进入编码问题
生态系统 - 由于更深层次的原因,它已经不兼容
字符串。 这只会影响与其他平台的互操作
完全排除。 所以你_不会失去任何东西_而是赢得使用的能力
Wasm 在更多样化的平台上。

你们是软件工程师。 因此,我假设您理解并欣赏
模块化和分层的价值,分离关注点并最大化
重用。 这也适用于规范。

>

非 Unicode 平台将被迫执行转码到实际
处理他们的字符串。

在什么情况下,Wasm 字符串需要与平台字符串互操作,
尽管? 据我所知,我们只是在谈论
Wasm 元数据中的字符串,而不是由
实际模块代码。 (如果那是错的,我道歉......)然后我只能想
可能需要互操作/转码的几种可能情况:

  • Wasm 模块导入平台标识符
  • 平台导入一个 Wasm 标识符
  • 您可以提取 Wasm 名称并打印它们或使用平台保存它们
    字符串,例如转储堆栈跟踪。

对?

是的。 换句话说,每次你实际上需要_使用_一个字符串。

对于假设的非 Unicode 嵌入式系统,对于前两种情况,
建议很简单:限制跨平台导入的标识符
ASCII 的边界,那么所需的转码是微不足道的。 Wasm 模块
仍然可以在内部使用完整的 Unicode 名称并用于相互链接。

对于第三个问题 --- 如果你有一个封闭的 Wasm 模块世界,你
可以将它们的标识符限制为 ASCII。 如果没有,那么在实践中你会
遇到 UTF8 标识符,你最好能够对它们进行转码,并且
你会很高兴规范规定的 UTF8!

根据该提案,您不得将任何内容限制为 ASCII! 到
允许核心规范需要更多允许。 所以你正在做
我的观点。

每个嵌入规范 _will_ 指定一个编码和字符集。 在每个平台上,您都可以信赖这一点。 如果您尝试在两个不相关的生态系统之间进行互操作,您只会遇到编码问题——由于比字符串更深层次的原因,这已经不兼容了。

反汇编器等 Wasm 处理工具呢? 能够编写一个与任何 Wasm 模块一起工作的反汇编器,而不管“嵌入规范”变体如何,难道不是很有价值吗?

根据该提案,您不得将任何内容限制为 ASCII!

根据提案,Wasm 模块将不限于 ASCII,但如果实施者选择在 Wasm 模块之外定义所有标识符 ASCII(例如,几乎所有系统库实际上都是这样做的!),那将超出 Wasm 的范围规格

如果实现者选择在堆栈跟踪中仅打印 ASCII 字符并将所有非 ASCII Unicode 字符替换?或类似字符,则规范必须允许这样做,因为实际上总是存在您不知道的 Unicode 字符反正没有字体。

说了这么多,定义一个 Wasm 的子集,其中所有的 Wasm 名称都是 ASCII 将是相当无害的,因为这些 Wasm 模块会被将 Wasm 名称视为 UTF8 的工具正确处理。

你们是软件工程师。 因此,我假设您理解并欣赏模块化和分层的价值,以分离关注点并最大化重用。 这也适用于规范。

是的,我是一名软件工程师。 我也是一名规范工程师,所以我理解一致性和建立规范的价值,使生态系统更好地运作。 字符集和编码是允许模块化和选择的价值被一致性和可预测性的价值大大超过的主题之一。 我们有几十年的实际证据证明这一点。 这就是不断重复自己的原因——你无视历史和许多专家的建议,

在阅读整个(长)线程后,我认为解决此讨论的唯一方法是明确指定我们以二进制格式描述的名称部分并在https://github.com/WebAssembly/design/pull中增强UTF-8 编码,我建议我们将该部分简单地称为“utf8-names” 。 这使得编码变得明确,而且几乎可以肯定,当今所有想要在所有相关平台上操作 WASM 二进制文件的工具无论如何都希望使用 UTF-8。 他们只说 UTF-8 是可以原谅的。

我对@rossberg-chromium 对其他平台的担忧很敏感,在某种程度上,我同意。 然而,这很容易修复。 正如前面有人建议的那样,这些系统非常欢迎添加非标准的“ascii-names”部分或其生态系统使用的任何其他编码。 有了明确的名称,哪些工具与哪些部分一起工作就变得很明显了。 对于仅在 DOS 上工作的模块,这会因 DOS 特定部分的存在而变得明显。 IMO 将这些二进制文件的名称解释为具有不同的编码将是一场灾难。

(顺便说一句,这是从战争故事中得知的,该系统意外丢失了用户上传内容的字符串编码,并且永远无法恢复它们。该系统死于可怕的痉挛性死亡。从字面上看,损失了数百万美元.)

我们甚至可以对名称部分采用命名标准(呵呵),以便它们都是“\

@titzer是的,自定义部分是这里的解决方案,适用于与 UTF8 无关的异国或专业平台。 不过,我会犹豫是否在规范中规定:如果一个平台的操作模式如此具体,以至于它甚至懒得将 UTF-8 代码点映射到他们的本机偏好,他们可能想要这样做自定义部分不仅仅是提供其首选编码中的名称。

我建议在规范中更加强调使用自定义部分来处理特定于平台的细节,并让平台自己的规范定义这些细节。 常见的 WASM 工具链可以通过某种插件架构来支持它们。

@titzer切换到utf8-names听起来不错。 作为奖励,它可以平滑过渡,因为浏览器可以轻松支持“名称”(旧格式)和“utf8-名称”(#984 格式),然后再删除“名称”,然后再删除“名称”消除了部署它的很多紧迫性。

对不起,如果这已经在上面决定了,但是,要清楚:现在是否有任何建议对 BinaryEncoding.md 中的导入/导出名称进行更改?

utf8-names听起来不错。

@lukewagner关于导入/导出的问题相同。

@lukewagner @jfbastien好问题。 我没有看到上面的决定。 我认为最重要的是我们不想改变我们现在拥有的二进制格式。 所以这真的只是我们必须经历的任何心理扭曲才能说服自己我们所做的是理性的:-)

AFAICT 我们目前假设导入/导出中的字符串是未解释的字节序列。 没关系。 我认为认为用于导入/导出的字符串编码由嵌入器单独定义是合理的,而名称部分则不是; 例如 JS 总是使用 UTF-8。 名称部分在名称部分的名称中带有显式编码。

简短版本:导入/导出声明中的名称编码是嵌入环境的一个属性,名称部分中名称的编码由用于标识用户部分的字符串(例如“utf8-names”)显式。

WDYT?

这对我来说很好,并且与我们在 #984 合并之前的情况相匹配(模names => utf8-names )。

我认为名称部分不如导入/导出重要,这才是真正的兼容性问题发生的地方:

  • 加载一个 mojibaked names 部分,你会得到时髦的 Error.stack 和调试。
  • 加载 mojibaked 导入/导出,但没有任何效果。

我认为这并不是真正的二进制格式更改,因为我们都实现的嵌入已经假设了这一点。

在结束之前,我会依靠比我更了解这个主题的人的建议。

您需要决定如何解码 UTF-8。 你是用 U+FFFD 替换错误序列还是在第一个错误时停止? 也就是说,您要么想要https://encoding.spec.whatwg.org/#utf -8-decode-without-bom 要么想要https://encoding.spec.whatwg.org/#utf -8-decode-without- bom 或失败。 无论哪种方式加载都可能会失败,除非资源碰巧在其名称中使用了 U+FFFD。

根据当前描述的方式,如果导入/导出名称字节数组未能将 UTF-8 解码为 JS 字符串,我们将抛出异常。 之后,您有一个 JS 字符串,并且根据Get定义导入查找。

为了检查我的理解,如果我们做了https://encoding.spec.whatwg.org/#utf -8-decode-without-bom-or-fail,这是否意味着,在成功验证后,检查代码点序列的相等性将等同于检查字节序列的相等性?

是的。

经过上面的讨论,我支持在核心规范中验证 UTF-8 的导入/导出名称。

具体来说,这将是utf-8-decode-without-bom-or-fail和代码点序列相等(因此引擎可以执行字节序列相等),因此引擎将避免 Unicode 和国际化的可怕和昂贵的部分。 并且,这与 Web 嵌入一致。 我已经对此进行了试验,发现主要的开销可以忽略不计。

  • 回复:硬件 ISA 与编码无关:我们在这里讨论的硬件没有导入/导出,因此类比不直接适用。 我所知道的此类硬件使用任何类型的字节序列标识符的地方,x86 的 cpuid,确实指定了特定的字符编码:UTF-8。

  • 回复:分层:作为软件工程师,我们也知道分层和模块化是手段,而不是目的本身。 例如,我们可以从核心规范中干净地分解出 LEB128。 这将提供更大的分层和模块化。 LEB128 可以说偏向于 Web 用例。

  • 回复:“嵌入式系统”:给出的一个例子是 DOS,但是对于导入/导出名称的 UTF-8 要求需要 DOS 系统来做的事情,这将是昂贵的或不切实际的事情的一个例子是什么?

  • 回复:Islands:WebAssembly 还指定了特定的字节序,需要浮点支持、8 位地址单元,并做出其他选择,即使在实际设置中这些设置会带来不必要的负担。 当 WebAssembly 期望它们会加强许多人可以共享的公共平台时,就会做出类似的选择。

  • 回复:导入/导出名称中的任意数据结构:这在理论上很有用,但也可以通过将数据转换为字符串来完成。 Mangling 不太方便,但并不难。 所以这里有一个权衡,但不是一个大的权衡(并且可以说,如果普遍需要将元数据附加到导入/导出,那么拥有一个明确的机制会比附加标识符更好。)

  • 回复:二进制兼容性:我也同意 JF 的观点,即此更改仍然可行。 utf-8-decode-without-bom-or-fail 意味着没有沉默的行为改变,此时,所有已知的 wasm 生产者都保持他们的输出与 Web 嵌入兼容(即使他们也支持其他嵌入),所以他们已经在 UTF-8 范围内了。

为 UTF-8 名称提出具体建议的 PR 现在发布为https://github.com/WebAssembly/design/issues/1016。

使用 #1016,现在已修复。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

chicoxyzzy picture chicoxyzzy  ·  5评论

konsoletyper picture konsoletyper  ·  6评论

beriberikix picture beriberikix  ·  7评论

arunetm picture arunetm  ·  7评论

dpw picture dpw  ·  3评论