WebAssembly学习(六):AssemblyScript - 限制与类型

一、限制

将无类型的JavaScript编译为WebAssembly没有意义,因为它最终会导致运行其中较慢的一个JavaScript。

相反,AssemblyScript专注于WebAssembly擅长的地方,并且不支持回退到无法提前有效编译的JavaScript的动态特性:

1.强制类型

  • 比 TypeScript 多了很多更细致的内置类型,以优化性能和内存占用,详情文档;
  • 没有联合类型,因为所有内容都必须按设计进行静态类型化;
  • 不能使用 any 和 undefined 类型,以及枚举类型;
  • 可空类型的变量必须是引用类型,例如 ClassType | null,而不能是基本数据类型如 string、number、boolean;
  • 函数中的可选参数必须提供默认值,函数必须有返回类型,无返回值的函数返回类型需要是 void;
    • 如果初始化是整数字面量,则假定i32适合32位,否则假设为i64。
    • 如果初始化是浮点数,则假定为f64。
    • 否则,将评估初始化程序以获取其类型。

总体来说 AssemblyScript 比 TypeScript 又多了很多限制,编写起来会觉得局限性很大; 用 AssemblyScript 来写 WebAssembly 经常会出现 tsc 编译通过但运行 WebAssembly 时出错的情况,这很可能就是你没有遵守以上限制导致的;但 AssemblyScript 通过修改 TypeScript 编译器默认配置能在编译阶段找出大多错误。

AssemblyScript 的实现原理其实也借助了 LLVM,它通过 TypeScript 编译器把 TS 源码解析成 AST,再把 AST 翻译成 IR,再通过 LLVM 编译成 WebAssembly 字节码实现; 上面提到的各种限制都是为了方便把 AST 转换成 LLVM IR。

2.详细说明

  • const和static readonly关键字当前与其他语言中的static const类似,需要编译时常量初始化程序,否则会回退到可变变量。
  • 在JavaScript中,类的静态字段在定义时始终进行求值,而在AssemblyScript中,内置树抖动时会在引用时懒惰地编译静态字段。

当调用一个从Js中导出的可变参数长度的WebAssembly函数时,例如:

1 export function add(a: i32 = 1, b: i32 = 2): i32 {
2   return a + b;
3 }

必须明确指定调用的实际参数数量,因为WebAssembly端没有与arguments.length等效的内容。 例如:

1 exports._setargc(0);
2 exports.sum(); // 3
3 
4 exports._setargc(1);
5 exports.sum(2); // 4
6 
7 exports._setargc(2);
8 exports.sum(2, 3); // 5

二、类型

与在JS中使用各种数值的数字类型不同,AssemblyScript将它们拆分为更精确的整数和浮点类型,这些类型直接映射到WebAssembly类型。

1.原生类型

  • i32/u32  一个32位有符号/无符号整数。
  • i64/u64  一个64位有符号/无符号整数。
  • f32  一个32为浮点数。
  • f64 一个64位浮点数。

2.模拟类型

  • i8/u8  一个8字节的有符号/无符号整数。
  • i16/u16  一个16字节的有符号/无符号整数。
  • bool  一个1字节无符号整数。

注意:模拟类型被隐式符号扩展,分别被屏蔽以处理溢出。 在进行大量数学运算时,建议在计算中使用原生类型,然后将值存储回模拟类型,上面的"位"即byte,字节。

3.针对特定类型

  • isize/usize  当目标是32位WebAssembly时,一个32位有符号/无符号整数;当目标是64位WebAssembly时,一个64位有符号/无符号整数。在其他语言中相当于void*, size_t等。

注意,使用目标特定类型可能需要也可能不需要显式强制类型,具体取决于目标。

注意,WASM64是未来的功能?,现在在任何地方都不受支持。

4.特殊类型

  • void  表示函数无返回值。

5.范围限制

为方便起见,以下范围限制作为全局常量出现:

ConstantValue
i8.MIN_VALUE: i8-128
i8.MAX_VALUE: i8127
i16.MIN_VALUE: i16-32768
i16.MAX_VALUE: i1632767
i32.MIN_VALUE: i32-2147483648
i32.MAX_VALUE: i322147483647
i64.MIN_VALUE: i64-9223372036854775808
i64.MAX_VALUE: i649223372036854775807
isize.MIN_VALUE: isizetarget specific: either i32.MIN_VALUE or i64.MIN_VALUE
isize.MAX_VALUE: isizetarget specific: either i32.MAX_VALUE or i64.MAX_VALUE
u8.MIN_VALUE: u80
u8.MAX_VALUE: u8255
u16.MIN_VALUE: u160
u16.MAX_VALUE: u1665535
u32.MIN_VALUE: u320
u32.MAX_VALUE: u324294967295
u64.MIN_VALUE: u640
u64.MAX_VALUE: u6418446744073709551615
usize.MIN_VALUE: usize0
usize.MAX_VALUE: usizetarget specific: either u32.MAX_VALUE or u64.MAX_VALUE
bool.MIN_VALUE: bool0
bool.MAX_VALUE: bool1
f32.MIN_VALUE: f32-3.40282347e+38
f32.MAX_VALUE: f323.40282347e+38
f32.MIN_SAFE_INTEGER: f32-16777215
f32.MAX_SAFE_INTEGER: f3216777215
f32.EPSILON: f321.19209290e-07
f64.MIN_VALUE: f64-1.7976931348623157e+308
f64.MAX_VALUE: f641.7976931348623157e+308
f64.MIN_SAFE_INTEGER: f64-9007199254740991
f64.MAX_SAFE_INTEGER: f649007199254740991
f64.EPSILON: f642.2204460492503131e-16

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 6.可转换性

 将一种类型的值分配给另一种类型的目标可以在没有显式强制转换的情况下执行,其中可以在目标类型中表示完整范围的可能值,而不管解释/签名:

booli8/u8i16/u16i32/u32i64/u64f32f64
bool
i8/u8 
i16/u16  
i32/u32    
i64/u64      
f32     
f64      

 

 

 

 

 

 

 

 

 

 

  

注意,如果目标是WASM32,则isize / usize的行为与i32 / u32相同,如果目标是WASM64,则分别为i64 / u64。

例如:

1 var i8val  : i8  = -128;  // 0x80
2 var u8val  : u8  = i8val; // becomes 128 (0x80)
3 var i16val : i16 = i8val; // becomes -128 through sign-extension (0xFF80)
4 var u16val : u16 = i8val; // becomes 65408 through masking (0xFF80)
5 var f32val : f32 = i8val; // becomes -128.0

7.可比性

可以在可分配性中概述的相同规则下执行比较不同类型的两个值而无需显式转换

1.如果比较是绝对的 (==!=)

2.如果比较是相对的  (><>=<=)  并且两种类型都具有相同的签名

因为WebAssembly对签名和未签名的比较具有不同的操作。 比较使用较大的类型并返回一个bool。

8.除法和余数

划分或取出除以不同类型的两个值的余数,可以在可转让性中概述的相同规则下进行显式转换。

  • 如果两种类型都具有相同的签名

因为WebAssembly对有符号和无符号除法和余数有不同的操作。 结果是更大的类型。

9.位运算

位运算(<<,>>)的结果是左类型,右类型隐式转换为左类型,如果左类型是有符号的,则执行算术移位;如果左类型是无符号,则执行逻辑移位。

无符号右移(>>>)的结果是左类型(保留了符号),右类型隐式转换为左类型,但始终执行逻辑移位。

如果左类型是浮点数,则会发出错误。

WebAssembly基本概念到此结束,虽然有很多不理解的东西,但还是先记录在此,慢慢学习。

参考原文:

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

WebAssembly 现状与实战

转载于:https://www.cnblogs.com/jixiaohua/p/10447701.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值