一、结构体系

1.编译

编译器的结构相对保守。

提供源文件,其文本被标记化并解析为抽象语法树。 这里执行语法级检查。

一旦解析了所有引用的源文件,就构造一个程序并从AST初始化。 在这里进行合理性检查。 然后,程序及其元素充当代码生成中的中间表示,包含解析类型,标识符,属性访问等所需的所有信息。

然后,执行将程序元素编译到Binaryen模块。 在此处执行对单个语句和表达式的最终检查。 默认情况下,编译从入口文件导出开始,然后遍历可访问的程序元素(也称为“树抖动”)。 在编译器级别上这样做可以提供显着的速度优势,因为根本不编译死代码,但也有缺陷,即没有完全检查死代码。 然而,指定 --noEmit --noTreeShaking 会检查所有内容而不生成代码。

然后可以验证、优化生成的模块,并以Binaryen的各种格式输出(textual .wat,binary .wasm,asm.js .js)。

2.API

编译器本身导出一个相对低级的类C语言API,它提供了在可互换的JS / WASM环境中执行编译所需的一切。

低级API由asc(节点的编译器前端)使用,它也以编程方式公开其CLI API。

3.标准库

虽然尚未完全理解,但标准库组件位于std文件夹中,有两种版本,用asc编译的针对WebAssembly的汇编标准库和tsc编译的针对JavaScript的可移植标准库。

可移植标准库基本上以与汇编脚本兼容的方式声明环境中已经存在的内容,而汇编标准库在AssemblyAs for WebAssembly中重新实现了相同的功能。

二、内置INS

为了提供对本机WebAssembly操作的直接(编译到操作码)访问,在全局范围中提供了以下函数以及一些类似TS / JS的常量:

1.上下文敏感的常量

  • NaN: f32 | f64 NaN (not a number) 作为32位或64位浮点数,具体取决于上下文。 编译为常量。
  • Infinity: f32 | f64 正无穷大为32位或64位浮点数,具体取决于上下文。 编译为常量。

2.编译时类型检查

  • isInteger<T>(value?: T): bool 测试指定的类型或表达式是否为整数类型而不是引用。 编译为常量。
  • isFloat<T>(value?: T): bool 测试指定的类型或表达式是否为float类型。 编译为常量。
  • isSigned < T>(value?:)Tbool 测试指定的类型或表达式是否可以表示负数。编译为常量。
  • isReference < T>(value?:)Tbool 测试指定的类型或表达式是否为引用类型。编译为常量。
  • isString < T>(value?:)Tbool 测试指定的类型或表达式是否可以用作字符串。编译为常量。
  • isArray < T>(value?:)Tbool 测试指定的类型或表达式是否可以用作数组。编译为常量。
  • isFunction < T>(value?:)Tbool 测试指定的类型或表达式是否为函数类型。编译为常量。
  • isNullable < T>(value?:)Tbool 测试指定的类型或表达式是否为可为空的引用类型。编译为常量。
  • isDefined(expression :)*bool 测试指定的表达式是否解析为已定义的元素。编译为常量。
  • isConstant(expression :)*bool 测试指定的表达式是否计算为常量值。编译为常量。
  • sizeof < T>():usize 确定指定核心或类类型的字节大小。编译为常量。
  • offsetof < T>(fieldName?:)stringusize 确定给定类类型中指定字段的偏移量。 如果省略了字段名,则返回类类型的结束偏移量。 编译为常量。
  • alignof < T>():usize 确定指定底层核心类型的对齐方式(log2)。编译为常量。

注意,constantOffset参数必须是编译时常量(const全局或本地)。 同样,fieldName参数必须是字符串。

注意,每当编译器发现常量条件时,它将自动删除未获取的分支,而不会尝试编译它们。例如,如果一个泛型函数要同时处理整数和字符串,并且只有几个不同的语句,那么可以使用if-then-else语句上带有常量条件的编译时类型检查,使其根据实际类型参数的不同部分表现不同:

 function doSomething<T>(a: T): T {
if (isString<T>()) {
... // eliminated if T is not a string
} else {
... // eliminated if T is a string
}
}

3.数学

  • isNaN<T = f32 | f64>(value: T): bool 测试32位或64位浮点数是否为NaN。
  • isFinite<T = f32 | f64>(value: T): bool 测试32位或64位浮点数是否有限,即不是NaN或+/-无穷大。
  • clz<T = i32 | i64>(value: T): T 执行符号无关的计数,在32位或64位整数上执行零位操作。 如果值为零,则认为所有零位都是前导的。
  • ctz<T = i32 | i64>(value: T): T 在32位或64位整数上执行符号无关的计数跟踪零位操作。 如果值为零,则将所有零位视为尾随。
  • popcnt<T = i32 | i64>(value: T): T 对32位或64位整数执行一位操作的符号不可知计数。
  • rotl<T = i32 | i64>(value: T, shift: T): T 对32位或64位整数执行符号无关的左旋转操作。
  • rotr<T = i32 | i64>(value: T, shift: T): T 对32位或64位整数执行符号无关的右旋操作。
  • abs<T = i32 | i64 | f32 | f64>(value: T): T 计算整数或浮点数的绝对值。
  • max<T = i32 | i64 | f32 | f64>(left: T, right: T): T 确定两个整数或浮点数的最大值。 如果任一操作数为NaN,则返回NaN。
  • min<T = i32 | i64 | f32 | f64>(left: T, right: T): T 确定两个整数或浮点数的最小值。 如果任一操作数为NaN,则返回NaN。
  • ceil<T = f32 | f64>(value: T): T 在32位或64位浮点上执行向上取整操作。
  • floor<T = f32 | f64>(value: T): T 在32位或64位浮点上执行向下取整操作。
  • copysign<T = f32 | f64>(x: T , y: T): T 根据x的大小和y的符号组成32位或64位浮点数。
  • nearest<T = f32 | f64>(value: T): T 对32位或64位浮点数四舍五入。
  • reinterpret<T = i32 | i64 | f32 | f64>(value: *): T 将指定值的位重新解释为类型T.有效的重新解释是 u32/i32 与 f32 和 u64/i64 与 f64。
  • sqrt<T = f32 | f64>(value: T): T 计算32位或64位浮点的平方根。
  • trunc<T = f32 | f64>(value: T): T 向32位或64位浮点数的最接近的整数舍入为零。

4.内存访问

  • load<T>(ptr: usize, constantOffset?: usize): T 从内存中加载指定类型的值。 相当于在其他语言中取消引用指针。
  • store<T>(ptr: usize, value: T, constantOffset?: usize): void 将指定类型的值存储到内存中。 相当于在分配值时取消引用其他语言中的指针。

5.控制流

  • select<T>(ifTrue: T, ifFalse: T, condition: bool): T 根据条件选择两个预先评估的值中的一个。
  • unreachable(): * 发出无法访问的操作,导致执行时出现运行时错误。 语句和任何类型的表达式。

6.主机操作

  • memory.size(): i32 以页为单位返回内存的当前大小。 一页是64kb。
  • memory.grow(value: i32): i32 通过给定的无符号页面增量生成线性内存。 一页是64kb。 以页为单位返回先前的内存大小,或者在失败时返回-1。 请注意,调用内存管理器所在的memory.grow可能会破坏它。

7.其他

  • parseInt(str: string, radix?: i32): i64 将字符串解析为64位整数。 与JS中的NaN不同,在无效输入上返回0。
  • parseFloat(str: string): f64 将字符串解析为64位浮点数。 在无效输入上返回NaN。
  • changetype<T>(value: *): T 将值的类型更改为另一个值。 用于将类实例转换为其指针值,反之亦然。
  • assert<T>(isTrueish: T, message?: string): T 如果断言的值不是true-ish,则捕捉,否则返回不可空值。
  • unchecked(expr: *): * 明确请求对提供的表达式不进行边界检查。 对数组访问很有用。
  • call_indirect<T>(target: u32, ...args: *[]): T 发出call_indirect指令,通过索引使用指定的参数调用函数表中的指定函数。 如果参数与被调用函数不匹配,则会导致运行时错误。
  • instantiate<T>(...args: *[]): T 使用指定的构造函数参数实例化T的新实例。

8.修饰符

以下特定于WebAssembly的运算符可用于注释非TS行为:

  • @global 将元素添加到全局范围。
  • @inline 强制函数内联。
  • @external([moduleName: string,] elementName: string) 更改声明的全局或函数的外部名称。
  • @operator(token: string) 注释二元运算符重载。
    • @operator.binary(token: string) 与@operator一样
    • @operator.prefix(token: string) 注释一元前缀运算符重载。
    • @operator.postfix(token: string) 注释一元后缀运算符重载。

参考文章:

https://github.com/AssemblyScript/assemblyscript/wiki

WebAssembly学习(四):AssemblyScript - 结构体系与内置函数的更多相关文章

  1. python学习笔记:第14天 内置函数补充和递归

    一.匿名函数 匿名函数主要是为了解决一些简单需求而设计的一种函数,匿名函数的语法为: lambda 形参: 返回值 先来看一个例子: # 计算n的n次方 In[2]: lst = lambda n: ...

  2. ruby -- 基础学习(七)时间的内置函数和格式说明

        Rails -- 时间的内置函数和格式说明 FROM:http://www.douban.com/note/99064603/ time = Time.now #获得当前时间 time.gmt ...

  3. 老男孩python学习自修第十一天【内置函数】

    1.基本内置函数 help() 帮助文档 dir() 列出当前文件的所有变量和方法 vars() 列出当前文件的所有变量及其值 type() 返回变量的类型 id() 返回变量的内存地址 len() ...

  4. sqlserver学习笔记(六)—— sqlserver内置函数(字符串、日期)

    sqlserver中有很多内置函数,这里总结了一些常用的 一.关于字符串的函数: 1.CHARINDEX 寻找一个指定字符串在另一个字符串中的起始位置 SELECT CHARINDEX('world‘ ...

  5. Python学习进程(15)常用内置函数

        本节介绍Python的一些常用的内置函数.     (1)cmp(x, y): cmp()函数比较 x 和 y 两个对象,并根据比较结果返回一个整数,如果 x<y,则返回-1:如果x&g ...

  6. 记录我的 python 学习历程-Day12 生成器/推导式/内置函数Ⅰ

    一.生成器 初识生成器 生成器的本质就是迭代器,在python社区中,大多数时候都把迭代器和生成器是做同一个概念. 唯一的不同就是: 迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来 ...

  7. python的学习笔记之——time模块常用内置函数

    1.Python time time()方法 Python time time() 返回当前时间的时间戳(1970纪元后经过的浮点秒数). time()方法语法: time.time() 举例: #! ...

  8. python学习笔记(十六)内置函数zip、map、filter的使用

    1.zip,就是把两个或者多个list,合并到一起,如果想同时循环2个list的时候,就使用zip.示例如下: l1 = ['a','b','c','e','f','g'] l2 = [,,] l3= ...

  9. python学习笔记:第13天 内置函数(一)

    详细文件查看点击这里:详细地址

随机推荐

  1. Spring MVC 的 研发之路 (二)

    二.web.xml的简单配置介绍1 1.启动Web项目时,容器回去读web.xml配置文件里的两个节点<context-param>和<listener> 2.接着容器会创建一 ...

  2. BZOJ1468: Tree & BZOJ3365: [Usaco2004 Feb]Distance Statistics 路程统计

    [传送门:BZOJ1468&BZOJ3365] 简要题意: 给出一棵n个点的树,和每条边的边权,求出有多少个点对的距离<=k 题解: 点分治模板题 点分治的主要步骤: 1.首先选取一个点 ...

  3. 31.ng-init 指令初始化 AngularJS 应用程序变量。

    转自:https://www.cnblogs.com/best/tag/Angular/ 1. <html> <head> <meta charset="utf ...

  4. BZOJ 1588 平衡树 模板题

    Treap: //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int si ...

  5. Java基础学习(六)-- 递归以及文件I/O流基础详解

    递归 1.递归的概念: 在函数自身内部,调用函数本身的方式,称为递归. 2.递归的注意事项:包括递进去,归出来两步.   即:首先依次执行[函数调自身语句]上半部分的代码,知道最里层.(递进去),然后 ...

  6. RecyclerView让列表嵌套如此简单

    平常开发时,相信像这样的页面,大家一定是遇到过的.这里比较坑爹的地方在于呢:列表嵌套.订单列表中的每一项,都包含一个商品列表.像这种需求,大家会如何实现呢? 这里呢,说一下我自己的思路,我没有使用列表 ...

  7. dedecms4张关键表解析之1

    虽然dedecms默认共有87张表,但是只有4张最核心,最最要的表. 1.第一张表:dede_arctype  栏目表 dede设计者认为不管存放什么样的数据(文章,商品,电影)都应该属于某个栏目(类 ...

  8. css hover图片hover效果兼容ie8

    例子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  9. iOS开发—— Couldn't add the Keychain Item

    报错:*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn ...

  10. 通过JMeter来测试Quick Easy FTP Server的上传与下载性能

    FTP性能测试 1.1背景说明 本测试选用的是一个小型的FTP服务器软件:Quick Easy FTP Server.Quick Easy FTP Server是一个全中文的FTP服务器软件,反应迅速 ...