# 实现情况

¥Implementation status

AssemblyScript 的目标是成为 WebAssembly 之上的一个薄而高效的层,以及一种为来自 TypeScript 的开发者提供熟悉语法的语言。这两个目标有时会发生冲突,因为目前并非所有功能都同样可以在 WebAssembly 的功能之上实现,分别适用于提前编译。因此,重点是首先实现可行的方案,并在可能的情况下推迟未来 WebAssembly 提案之一可以更好服务的功能,以避免重复工作。从某种意义上说,该方法类似于 WebAssembly 规范中使用的 MVP 模型。当然,某些功能对于让 AssemblyScript 现在正常工作至关重要,因此此规则有一些例外。

¥AssemblyScript both aims to be a thin and efficient layer on top of WebAssembly, as well as a language with familiar syntax for developers coming from TypeScript. These two goals are sometimes in conflict, since not all features are equally viable to implement on top of WebAssembly's capabilities right now, respectively applicable in general in ahead-of-time compilation. As such the focus is to implement what's feasible first, and where possible to delay features that are better served by one of the future WebAssembly proposals to avoid otherwise duplicate work. In a sense, the approach is similar to the MVP model used in WebAssembly specification. Some features are critical to make AssemblyScript work right now of course, so there are some exceptions to this rule.

# WebAssembly 功能

¥WebAssembly features

某些语言功能依赖于 未来的 WebAssembly 功能 (opens new window) 才能变得可行。下表旨在从 WebAssembly 的角度进行概述:

¥Some language features rely on future WebAssembly functionality (opens new window) to become viable. The following table aims to give an overview from a WebAssembly perspective:

WebAssembly 规范 引擎 AssemblyScript(标志) 看法
✔️ 提案完成
[可变全局变量的导入/导出] <否/> ⁞ ✔️ <good 互操作
[JS BigInt 集成]1 ✔️ <good 互操作
[符号扩展操作] <否/> ⁞ ✔️ good 效率
[非捕获浮点到整数的转换] <否/> ⁞ ✔️ good 效率
【大容量内存操作】 <否/> ⁞ ✔️ good 效率
[固定宽度 SIMD] <否/> ⁞ 🏁 simd good 特性
[参考类型] <否/> ⁞ 🔨 reference-types <good 互操作
[多值] <否/> ⁞ good 特性
🏁 标准化特性
[扩展常量表达式] 🔨 good 效率
[尾部调用] good 效率
🔨 实现阶段
[轻松的 SIMD] 🏁 relaxed-simd good 特性
[异常处理] 🔨 exception-handling good 特性
[类型化函数参考] 🔨 gc good 特性
[垃圾收集] 🔨 gc good 效率/互操作性
[多重回忆] 🔨 good 特性
【分支提示】 good 效率
[JS Promise 集成]
[话题] 🔨 threads
[记忆 64] 🔨
📖 可用规范文本
[ECMAScript 模块集成] <good 互操作
[仪器与追踪] good 调试
💡 功能提案
[引用类型字符串] 🔨 stringref <good 互操作
[扩展名称部分] 🔨 good 调试
【GC 的 JS 定制】 <good 互操作
[类型导入] <good 互操作
[灵活的载体] good 特性
[恒定时间] <good 安全
[堆栈切换]
[调用标签]
[内存控制]
[简介]
[组件模型]2
❔ 准提案
[WASI]2

网址: Chrome 火狐浏览器 苹果浏览器 Node.js ⁞ 非网络: Wasmer Wasmtime

¥Web:   Chrome Firefox Safari Node.js   ⁞   Non-Web:   Wasmer Wasmtime

1 非 Web 主机以其他方式支持。2 请参阅我们的详细 标准异议

¥1 Supported otherwise by Non-Web hosts.   2 See our detailed standards objections.

看法 描述
这个规范在概念上很好并且值得研究
AssemblyScript 对此规范不确定,并不急于实现它
AssemblyScript 认为该规范在当前状态下是有害的

# 语言特点

¥Language features

因此,某些高级语言功能仍然有其局限性或尚不可用。从语言角度来说:

¥As such, certain higher-level language features still have their limitations or are not yet available. From a language perspective:

特性 会发生什么?
🐤 功能性
引导程序 编译器可以将自身编译为 WebAssembly,并通过测试套件。请注意,从技术上讲,编译器在 WebAssembly 中还不是 "自托管",因为它当前使用 JavaScript 前端进行 I/O 并链接到 Binaryen(使用 Emscripten 编译的 C++),这又需要一定量的 JS 粘合代码。
面向对象编程 主要在线性存储器中实现。当前未强制执行 privateprotected 等访问修饰符。对接口有基本的支持。
标准库 主要在线性存储器中实现。由于静态类型或尚未提供的未来功能引入的差异,某些 API 的功能与 JavaScript 中的功能略有不同。有一个特定于标准库的 单独的状态文件 (opens new window)
泛型 泛型目前被编译为单态模板,并且可以专门用于 静态类型检查。约束 extends XY 条款尚未强制执行。
垃圾收集 暂时在线性内存中实现,独立于主机 GC。
主机集成 由生成的 主机绑定运行时接口 启用,以便集成到非 Web 环境中。
🐣 有限的
联盟类型 除可为 null 的类类型外,尚不支持联合类型。没有 any 型。一个可行的替代方案是使用专门针对 静态类型检查 的泛型来实现类似的效果。
符号 符号在标准库中实现,但尚未深度编译器集成。
对象字面量 对象字面量可以用在当前类型是裸类的地方,然后对应于该类的实例化。
JSON JSON 本质上不是严格类型的,因此我们尚未确定标准。社区开发的解决方案:assemblyscript-json (opens new window)
正则表达式 正则表达式需要相当多的支持代码,并且有很多怪癖,我们还没有决定实现。社区开发的解决方案:assemblyscript-regex (opens new window)
日期 初步支持 UTC 部分,但 WebAssembly 无法访问系统的时区数据。总的来说,临时提案可能更容易被采纳。社区开发的解决方案:assemblyscript-temporal (opens new window)
🥚 未实现
闭包 尚不支持捕获局部变量,最好在未来的 WebAssembly 功能之上实现,同时避免发明自定义 ABI。可以通过使用全局变量(不需要捕获)或传递具有相关值的参数来解决。
迭代器 尚不支持迭代器和 for..of 循环。原本会返回迭代器的 API 现在会返回一个键或值数组。
其余参数 尚不支持剩余参数。将受益于 WebAssembly 提案以避免自定义 ABI,但目前还没有。支持具有默认值的可选参数,并且通常可以用作替代参数。
例外情况 异常首先需要 WebAssembly 引擎的支持。当前抛出会中止程序。
Promise 由于缺乏事件循环,目前还没有 async/await 的概念。未来的 WebAssembly 提案可能有助于堆栈切换部分(暂停和恢复执行)。
大整型 AssemblyScript 选择使用 WebAssembly 的 64 位整数,而不是 BigInt。目前尚不清楚这两个概念如何混合。
🕳️ 不支持
动态性 AssemblyScript 在设计上避免了过度动态的 JavaScript 功能,并专注于静态编译。

# 关于关闭

¥On closures

尚不支持闭包(具有捕获环境的函数),我们正在等待函数引用🦄和垃圾收集🦄(捕获的环境经过 GC 处理)提案的落地。然而,由于这是一个重要的语言功能,我们最终可能会使用线性内存来实现填充。不过,目前尚不可用。

¥Closures (functions with a captured environment) are not yet supported and we are waiting for the Function References 🦄 and Garbage collection 🦄 (captured environments are GC'ed) proposals to land. However, since this is a crucial language feature, we may end up with a filler implementation using linear memory. Not available yet, though.

与此同时,我们建议重构代码,这样就不需要闭包,即不用编写

¥In the meantime we recommend to restructure code so closures are not necessary, i.e. instead of writing

function computeSum(arr: i32[]): i32 {
  var sum = 0
  arr.forEach(value => {
    sum += value // fails
  })
  return sum
}

重组为

¥restructure to

var sum: i32 // becomes a WebAssembly Global
function computeSum(arr: i32[]): i32 {
  sum = 0
  arr.forEach(value => {
    sum += value // works
  })
  return sum
}

或者

¥or to

function computeSum(arr: i32[]): i32 {
  var sum = 0
  for (let i = 0, k = arr.length; i < k; ++i) {
    sum += arr[i] // works
  }
  return sum
}

# 论动态性

¥On dynamicness

AssemblyScript 有意避免无法有效编译的非常动态的 JavaScript 功能,例如:

¥AssemblyScript intentionally avoids very dynamic JavaScript features that cannot be compiled efficiently, like for example:

  • 为任何变量分配任何值。

    ¥Assigning any value to any variable.

  • 比较不兼容类型的值。

    ¥Compare values of incompatible types.

  • 不使用 x.toString() 从非字符串隐式转换为字符串。

    ¥Implicitly convert from a non-string to a string without using x.toString().

  • 将尚未静态声明的新属性分配给类或对象。

    ¥Assign a new property, that has not been statically declared, to a class or object.

  • 将类分配给变量(例如 var clazz = MyClass),因为类是没有运行时表示的静态构造。

    ¥Assign a class to a variable (e.g. var clazz = MyClass) since classes are static constructs without a runtime representation.

  • 补丁类别 .prototype 因为没有。

    ¥Patch class .prototypes since there are none.

  • 访问 arguments 动态获取函数参数。

    ¥Access arguments to dynamically obtain function arguments.

  • 在运行时动态获取函数的名称或以其他方式使用反射。

    ¥Dynamically obtain the name of a function at runtime or otherwise use reflection.

其中一些限制(例如与字符串连接时隐式转换为字符串)可能会在将来取消,而其他限制(例如原型)可能永远无法在提前编译中实现。例如,某些功能可以在解释器中工作,并且通过 JIT 编译器可能会变得高效,但深入这个兔子洞与 WebAssembly's,根据定义 AssemblyScript' 的目标背道而驰。

¥Some of these restrictions, like implicit conversion to strings when concatenating with a string, may be lifted in the future, while others, like prototypes, may never be viable in ahead-of-time compilation. For instance, some features would work in an interpreter and may become efficient with a JIT compiler, yet going down that rabbit hole runs counter to WebAssembly's, and by definition AssemblyScript's, goals.

# 工具特性

¥Tooling features

特性 会发生什么?
🐤 功能性
调试 支持调试信息和源映射。也可以看看
测试 不发表任何简单的主张。社区开发的解决方案:as-pect (opens new window)
🐣 有限的
棉绒 AssemblyScript 在各处重新使用带有 // @ts-ignore 的 TypeScript 工具,但最终将受益于专用语言服务器。社区开发的解决方案:asls (opens new window)