# 介绍

¥Introduction

AssemblyScript 使用 二进制 (opens new window)TypeScript (opens new window)(JavaScript 的类型化超集)的变体编译为 WebAssembly (opens new window),如下所示:

¥AssemblyScript compiles a variant of TypeScript (opens new window) (a typed superset of JavaScript) to WebAssembly (opens new window) using Binaryen (opens new window), looking like:

export function fib(n: i32): i32 {
  var a = 0, b = 1
  if (n > 0) {
    while (--n) {
      let t = a + b
      a = b
      b = t
    }
    return b
  }
  return a
}
asc fib.ts --outFile fib.wasm --optimize

它与 TypeScript 类似,但具有 WebAssembly 类型,由于提前编译严格类型化的代码而有一些限制,但也有一些源自 WebAssembly 功能集的添加。虽然并非所有 TypeScript 都能得到支持,但它与 JavaScript 的密切关系使其成为已经习惯为 Web 编写代码的开发者的熟悉选择,并且还具有与现有 Web 平台概念无缝集成的潜力,以产生精益和平均的结果 WebAssembly 模块。

¥It is similiar to TypeScript but with WebAssembly types, has some constraints due to compiling strictly typed code ahead of time, but also some additions originating in WebAssembly's feature set. While not all of TypeScript can be supported, its close relation to JavaScript makes it a familiar choice for developers who are already used to writing code for the Web, and also has the potential to integrate seamlessly with existing Web Platform concepts to produce lean and mean WebAssembly modules.

# 从 WebAssembly 的角度来看

¥From a WebAssembly perspective

AssemblyScript 提供 WebAssembly 和编译器基础作为 内置函数,使其适合作为原始 WebAssembly 之上的薄层。例如,可以使用直接编译为 WebAssembly 指令的内置函数来访问内存:

¥AssemblyScript provides WebAssembly and compiler foundations as built-in functions, making it suitable as a thin layer on top of raw WebAssembly. For example, memory can be accessed using built-in functions that compile to WebAssembly instructions directly:

store<i32>(ptr, load<i32>(ptr) + load<i32>(ptr, 4), 8)

为了进行比较,以下 C 代码大致等效:

¥For comparison, the following C code is roughly equivalent:

*(ptr + 2) = *ptr + *(ptr + 1)

大多数 WebAssembly 指令也可以直接用 AssemblyScript 代码编写,也可以使用通用变体:

¥Most WebAssembly instructions can also be written directly in AssemblyScript code, with generic variants available as well:

i32.ctz(...)             // ctz<i32>(...)
f64.reinterpret_i64(...) // reinterpret<f64>(...)
i64.load32_u(...)        // <i64>load<u32>(...)
...

# 从 JavaScript 的角度来看

¥From a JavaScript perspective

在其底层功能之上实现,AssemblyScript 提供了类似 JavaScript 的 标准库,其中包含 JavaScript 中的许多类和命名空间,包括 Math(还有用于单精度的 Mathf)、Array<T>StringMap<K,V>、类型化数组 等等。

¥Implemented on top of its low-level capabilities, AssemblyScript provides a JavaScript-like standard library with many of the classes and namespaces one is used to from JavaScript, including Math (also Mathf for single precision), Array<T>, String, Map<K,V>, the typed arrays and so on.

使用标准库时,上面的加载/存储示例可能如下所示:

¥The load/store example above could look like this when utilizing the standard library:

var view = new Int32Array(12)
...
view[2] = view[0] + view[1]

这两种观点都可以混合,具体取决于是否需要使用 WebAssembly 指令进行底层控制,或者使用托管标准库进行惯用概念来完成单个任务。

¥Both perspectives can be mixed depending on whether low-level control with WebAssembly instructions or idiomatic concepts with the managed standard library are desirable to accomplish an individual task.

# 常见问题

¥Frequently asked questions

AssemblyScript 是否涉及解释器或 "虚拟机中的虚拟机"?

不会,AssemblyScript 直接、静态、提前编译为 WebAssembly 字节码。

¥No, AssemblyScript compiles to WebAssembly bytecode directly, statically, ahead-of-time.

AssemblyScript 和 TypeScript 有什么区别?

TypeScript 转换为 JavaScript,一种动态的即时编译语言。另一方面,AssemblyScript 编译为静态 WebAssembly 二进制文件。他们的编译器实现有很大不同。然而,这两种语言表面上非常相似,以至于它们共享许多概念。例如,TypeScript 工具可用于编写和重构 AssemblyScript 代码,并且通过一些努力,可以使用 tsc 将相同的代码库转换为 JavaScript,并使用 asc 编译为 WebAssembly,或者共享代码。AssemblyScript 编译器本身是可移植的。

¥TypeScript transpiles down to JavaScript, a dynamic just-in-time compiled language. AssemblyScript, on the other hand, compiles to a static WebAssembly binary. Their compiler implementations are quite different. However, the two languages are so very similar on the surface that they share many concepts. For example, TypeScript tooling can be used to author and refactor AssemblyScript code and, with some effort, the same code base can be transpiled to JavaScript with tsc and compiled to WebAssembly with asc, or code shared. The AssemblyScript compiler itself is portable.

AssemblyScript 最终会支持所有 TypeScript 吗?

可能不会。虽然 TypeScript 为 JavaScript 添加了类型,但它毕竟是一个超集,可以描述 JavaScript 的许多动态特性,但并非所有这些特性都可以在提前编译中支持。然而,足够严格的 TypeScript 代码通常可以毫不费力地与 AssemblyScript 编译器兼容。

¥It likely won't. While TypeScript adds typings to JavaScript, it is a superset after all and can describe many of JavaScript's dynamic features, not all of which are feasible to support in ahead-of-time compilation. Yet, sufficiently strict TypeScript code can often be made compatible with the AssemblyScript compiler with little effort.

AssemblyScript 有哪些好的用例?

图片处理、热门游戏逻辑、专用算法、模拟器、编译器等计算密集型逻辑是 WebAssembly 的绝佳用例,对于 AssemblyScript 来说也是如此。在某些情况下,发送字节码而不是缩小的 JS 可能更好,或者仅仅利用类似 TypeScript 的语言的能力可能会带来新的机会,例如嵌入式脚本或插件。

¥Computation-heavy logic like image manipulation, hot game logic, specialized algorithms, emulators, compilers and the likes are great use cases for WebAssembly, and as such for AssemblyScript as well. In some situations it may also be preferable to ship bytecode instead of minified JS, or just the ability to utilize a TypeScript-like language may open up new opportunities, for example for embedded scripting or plugins.

AssemblyScript 是否可以以非标准方式(例如在浏览器之外)使用?

绝对地!AssemblyScript 模块是独立的,可以在支持 WebAssembly 的任何地方运行。事实上,可以支持任何任意主机接口。这是 使用 WASI 导入而不是 Web API 的示例 (opens new window)

¥Absolutely! AssemblyScript modules are self-contained and run anywhere where WebAssembly is supported. In fact, any arbitrary host interface can be supported. Here is an example of using WASI imports instead of Web APIs (opens new window).

为什么叫奇怪的名字?

AssemblyScript 之于 Assembly 就像 JavaScript 之于 Java。不完全的。

¥AssemblyScript is to Assembly as JavaScript is to Java. Not quite.

但现在,让我们 开始吧 吧!

¥But now, let's get started!