一、结构体系

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. 作为一名Android APP开发者的自我总结

    每当接近年尾,最痛苦的工作无疑是写年终总结,写总结的同时不禁感叹这一年过得不容易阿.突然想起这一年也是自己开发Android APP的第一年,于是觉得应该给自己的APP来一个年终总结. 一.开发方面严 ...

  2. (cLion、RubyMine、PyCharm、WebStorm、PhpStorm、Appcode、Clion、Idea) 万能破解,获取自己的注冊码

    听说cLion的ide编写c/c++很的棒.今天下载了一个仅仅有30天的使用时间.作为程序猿破解它. 下载破解文件 | 点击下载 |password: 7biu 解压压缩包,然后打开命令行 cd 到解 ...

  3. XUtils3框架的基本用法(一)

    本文为作者原创,转载请指明出处: http://blog.csdn.net/a1002450926/article/details/50341173 今天给大家带来XUtils3的基本介绍.本文章的案 ...

  4. 【LeetCode】Longest Palindromic Substring 解题报告

    DP.KMP什么的都太高大上了.自己想了个朴素的遍历方法. [题目] Given a string S, find the longest palindromic substring in S. Yo ...

  5. 【Android进阶篇】Fragment的两种载入方式

    一.概述 Fragment(碎片,片段)是在Android 3.0后才引入的,基本的目的是为了实如今大屏幕设备上的更加动态更加灵活的UI设计. 这是由于平板电脑的屏幕比手机大得多,所以屏幕上能够放很多 ...

  6. Windows server 2008 布署FTP服务器实例(适用于阿里云)!

    Windows server 2008 布署FTP服务器实例(适用于阿里云). 1.打开管理.配置-用户-新建用户,如:ftp_user,并设置password.选择永只是期和password不能更改 ...

  7. python判断一个单词是否为有效的英文单词?——三种方法

    For (much) more power and flexibility, use a dedicated spellchecking library like PyEnchant. There's ...

  8. java9新特性-5-Java的REPL工具: jShell命令

    1.官方Feature 222: jshell: The Java Shell (Read-Eval-Print Loop) 2.产生背景 像Python 和 Scala 之类的语言早就有交互式编程环 ...

  9. if语句练习

    输入年月日,首先判断该年是平年闰年并且计算该天是该年的第几天: 判断男女体重是否标准: 体重判断里边出现一个问题:如果性别输入的不是男也不是女,那么会执行输出“请输入正确的性别”:然后底下会继续输出“ ...

  10. AngularJs轻松入门(八)Cookies读写

    虽然使用JavaScript创建和获取Cookie很简单,AngularJs还是把它作为一个单独的模块进行了封装,模块名为ngCookies,和前面的教程中做法一样,先引入angular-cookie ...